C 多執行緒學習 四 多執行緒的自動管理 執行緒池

2021-05-26 12:03:47 字數 4457 閱讀 8077

在多執行緒的程式中,經常會出現兩種情況:

一種情況: 應用程式中,執行緒把大部分的時間花費在等待狀態,等待某個事件發生,然後才能給予響應

這一般使用threadpool(執行緒池)來解決;

另一種情況:執行緒平時都處於休眠狀態,只是周期性地被喚醒

這一般使用timer(定時器)來解決;

threadpool類提供乙個由系統維護的執行緒池(可以看作乙個執行緒的容器),該容器需要 windows 2000 以上系統支援,因為其中某些方法呼叫了只有高版本的windows才有的api函式。

//將乙個執行緒放進執行緒池,該執行緒的start()方法將呼叫waitcallback**物件代表的函式

public static bool queueuserworkitem(waitcallback);

//過載的方法如下,引數object將傳遞給waitcallback所代表的方法

public static bool queueuserworkitem(waitcallback, object);

在這裡你無需自己建立執行緒,只需把你要做的工作寫成函式,然後作為引數傳遞給threadpool.queueuserworkitem()方法就行了,傳遞的方法就是依靠waitcallback**物件,而執行緒的建立、管理、執行等工作都是由系統自動完成的,你無須考慮那些複雜的細節問題。

threadpool 的用法:

首先程式建立了乙個manualresetevent物件,該物件就像乙個訊號燈,可以利用它的訊號來通知其它執行緒。

本例中,當執行緒池中所有執行緒工作都完成以後,manualresetevent物件將被設定為有訊號,從而通知主線程繼續執行。

manualresetevent物件有幾個重要的方法:

初始化該物件時,使用者可以指定其預設的狀態(有訊號/無訊號);

在初始化以後,該物件將保持原來的狀態不變,直到它的reset()或者set()方法被呼叫:

reset()方法:將其設定為無訊號狀態;

set()方法:將其設定為有訊號狀態。

waitone() 方法:使當前執行緒掛起,直到manualresetevent物件處於有訊號狀態,此時該執行緒將被啟用。然後,程式將向執行緒池中新增工作項,這些以函式形式提供的工作項被系統用來初始化自動建立的執行緒。當所有的執行緒都執行完了以後,manualresetevent.set()方法被呼叫,因為呼叫了 manualresetevent.waitone()方法而處在等待狀態的主線程將接收到這個訊號,於是它接著往下執行,完成後邊的工作。

threadpool 的用法示例:

code

using system;

using system.collections;

using system.threading;

namespace threadexample

}public class alpha

//執行緒池裡的執行緒將呼叫beta()方法

public void beta(object state)

:", thread.currentthread.gethashcode(),((somestate)state).cookie);

console.writeline("hashcount.count==, thread.currentthread.gethashcode()==", hashcount.count, thread.currentthread.gethashcode());

lock (hashcount)

int ix = 2000;

thread.sleep(ix);

操作是乙個原子操作,具體請看下面說明

interlocked.increment(ref icount);

if (icount == imaxcount)}}

public class ******pool

items to thread pool", maxcount);

alpha oalpha = new alpha(maxcount);

//建立工作項

//注意初始化oalpha物件的eventx屬性

oalpha.eventx = eventx;

console.writeline("queue to thread pool 0");

trycatch (notsupportedexception)

if (w2k)//如果當前系統支援threadpool的方法.

", iitem);

threadpool.queueuserworkitem(new waitcallback(oalpha.beta), new somestate(iitem));

}console.writeline("waiting for thread pool to drain");

//等待事件的完成,即執行緒呼叫manualresetevent.set()方法

eventx.waitone(timeout.infinite,true);

//waitone()方法使呼叫它的執行緒等待直到eventx.set()方法被呼叫

console.writeline("thread pool has been drained (event fired)");

console.writeline();

console.writeline("load across threads");

foreach(object o in oalpha.hashcount.keys)

console.writeline(" ", o, oalpha.hashcount[o]);

}console.readline();

return 0;}}

}}程式中應該引起注意的地方:

somestate類是乙個儲存資訊的資料結構,它在程式中作為引數被傳遞給每乙個執行緒,因為你需要把一些有用的資訊封裝起來提供給執行緒,而這種方式是非常有效的。

程式出現的interlocked類也是專為多執行緒程式而存在的,它提供了一些有用的原子操作。

原子操作:就是在多執行緒程式中,如果這個執行緒呼叫這個操作修改乙個變數,那麼其他執行緒就不能修改這個變數了,這跟lock關鍵字在本質上是一樣的。

輸出的結果

thread pool sample:

queuing 10 items to thread pool

queue to thread pool 0

queue to thread pool 1

queue to thread pool 2

queue to thread pool 3

queue to thread pool 4

queue to thread pool 5

2 0 :

hashcount.count==0, thread.currentthread.gethashcode()==2

queue to thread pool 6

queue to thread pool 7

queue to thread pool 8

queue to thread pool 9

waiting for thread pool to drain

4 1 :

hashcount.count==1, thread.currentthread.gethashcode()==4

6 2 :

hashcount.count==1, thread.currentthread.gethashcode()==6

7 3 :

hashcount.count==1, thread.currentthread.gethashcode()==7

2 4 :

hashcount.count==1, thread.currentthread.gethashcode()==2

8 5 :

hashcount.count==2, thread.currentthread.gethashcode()==8

9 6 :

hashcount.count==2, thread.currentthread.gethashcode()==9

10 7 :

hashcount.count==2, thread.currentthread.gethashcode()==10

11 8 :

hashcount.count==2, thread.currentthread.gethashcode()==11

4 9 :

hashcount.count==2, thread.currentthread.gethashcode()==4

setting eventx

thread pool has been drained (event fired)

load across threads

11 1

10 1

9 18 1

7 16 1

4 22 2

我們應該徹底地分析上面的程式,把握住執行緒池的本質,理解它存在的意義是什麼,這樣才能得心應手地使用它。

C 多執行緒學習 四 多執行緒的自動管理 執行緒池

在多執行緒的程式中,經常會出現兩種情況 一種情況 應用程式中,執行緒把大部分的時間花費在等待狀態,等待某個事件發生,然後才能給予響應 這一般使用threadpool 執行緒池 來解決 另一種情況 執行緒平時都處於休眠狀態,只是周期性地被喚醒 這一般使用timer 定時器 來解決 threadpool...

C 多執行緒學習 四 多執行緒的自動管理 執行緒池

在多執行緒的程式中,經常會出現兩種情況 一種情況 應用程式中,執行緒把大部分的時間花費在等待狀態,等待某個事件發生,然後才能給予響應 這一般使用threadpool 執行緒池 來解決 另一種情況 執行緒平時都處於休眠狀態,只是周期性地被喚醒 這一般使用timer 定時器 來解決 threadpool...

C 多執行緒學習 四 多執行緒的自動管理 執行緒池

在多執行緒的程式中,經常會出現兩種情況 一種情況 應用程式中,執行緒把大部分的時間花費在等待狀態,等待某個事件發生,然後才能給予響應 這一般使用threadpool 執行緒池 來解決 另一種情況 執行緒平時都處於休眠狀態,只是周期性地被喚醒 這一般使用timer 定時器 來解決 threadpool...