C 多執行緒程式設計(二)執行緒池與TPL

2022-07-04 17:18:11 字數 2173 閱讀 2078

每次都要建立thread物件,並向作業系統申請建立乙個執行緒,這是需要耗費cpu時間和記憶體資源的。

無法直接獲取執行緒函式返回值

無法直接捕捉執行緒函式內發生的異常

使用執行緒池可以解決第乙個問題

在這裡只簡單的介紹一下threadpool,由於tpl的存在,我工作中大部分使用的是tpl中的類,這是後面介紹的重點。

這個方法有三個過載

第乙個函式需要傳入乙個waitcallback 委託,該委託的定義如下

第二個函式多了乙個state引數,表示需要傳給委託的引數,若無需傳參呼叫第乙個函式即可。

第三個函式是乙個泛型版本,還多了乙個布林型別的引數preferlocal,這個引數表示傳入的委託將會在放入執行緒池工作執行緒的本地佇列還是執行緒池的全域性佇列。

執行緒池內部有本地佇列和全域性佇列的概念,執行緒池遵循生產者-消費者模式,執行緒池還可以為執行緒數量提供良好的伸縮性,有關.net執行緒池的詳細資訊,請參見

需要注意的是,執行緒池中的執行緒預設為後台執行緒,這意味著如下**一般不能按預期工作。

1

static

void main(string

args)2);

8 }

並且由於執行緒會被復用,所以不能作依賴於某個特定執行緒的操作。

需要乙個前台執行緒。

需要具有特定優先順序的執行緒。

擁有會導致執行緒長時間阻塞的任務。 執行緒池具有最大執行緒數,因此大量被阻塞的執行緒池執行緒可能會阻止任務啟動。

需將執行緒放入單執行緒單元。 所有 threadpool 執行緒均位於多執行緒單元中。

需具有與執行緒關聯的穩定標識,或需將乙個執行緒專用於一項任務。

執行緒池雖然解決了執行緒資源浪費的問題,但是以下兩點還未解決

無法直接獲取執行緒函式返回值

無法直接捕捉執行緒函式內發生的異常

1

static

void main(string

args)2"

);7});8

task.start();

9try

1013

catch

(exception e)

1417 }

輸出如下:

延續任務發生異常");

10},taskcreationoptions.attachedtoparent);

11task1.start();

12throw

new exception("

主任務發生異常");

13});

1415

task.start();

16try

1720

catch(aggregateexception ae)//

task內部包裝了異常,有異常發生wait()內部會丟擲乙個聚合異常

有返回值的就不演示了。可以看到,使用task解決了開始的三種問題,但事物總是具有兩面性,有優點也有缺點,task會帶來額外的記憶體分配,task抽象層次過高,深入理解並使用好並非易事,在與async/await關鍵字配合編寫非同步**時更加突出。

網上關於task的使用例子很多,微軟文件也很全,我在此這裡補充一下需要注意的地方。

Linux多執行緒程式設計(二) 執行緒屬性

pthread介面允許我們通過設定每個物件關聯的不同屬性來細調執行緒的行為。include int pthread attr init pthread attr t attr int pthread attr destroy pthread attr t attr 兩個函式的返回值 若成功,返回0 ...

c 多執行緒thread操作(二)執行緒管理

c 多執行緒thread操作 一 環境部署 c 多執行緒thread操作 二 執行緒管理 c 多執行緒thread操作 三 資料競爭互斥訪問 c 多執行緒thread操作 四 死鎖的問題和解決 c 多執行緒thread操作 五 unique lock加鎖 c 多執行緒thread操作 六 條件變數的...

c 執行緒池 多執行緒

1。設定引數類 using system using system.collections.generic using system.text public class stateinfo 執行緒開啟方法類 using system using system.collections.generic ...