使用者模式的執行緒同步機制效率高,如果需要考慮執行緒同步問題,應該首先考慮使用者模式的執行緒同步方法。
但是,使用者模式的執行緒同步有限制,對於多個程序之間的執行緒同步,使用者模式的執行緒同步方法無能為力。這時,只能考慮使用核心模式。
windows提供了許多核心物件來實現執行緒的同步。對於執行緒同步而言,這些核心物件有兩個非常重要的狀態:「已通知」狀態,「未通知」狀態(也有翻譯為:受信狀態,未受信狀態)。windows提供了幾種核心物件可以處於已通知狀態和未通知狀態:程序、執行緒、作業、檔案、控制台輸入/輸出/錯誤流、事件、等待定時器、訊號量、互斥物件。
你可以通知乙個核心物件,使之處於「已通知狀態」,然後讓其他等待在該核心物件上的執行緒繼續執行。你可以使用windows提供的api函式,等待函式來等待某乙個或某些核心物件變為已通知狀態。
你可以使用waitforsingleobject函式來等待乙個核心物件變為已通知狀態:
dword waitforsingleobject(
handle hobject, //指明乙個核心物件的控制代碼
dword dwmilliseconds); //等待時間
該函式需要傳遞乙個核心物件控制代碼,該控制代碼標識乙個核心物件,如果該核心物件處於未通知狀態,則該函式導致執行緒進入阻塞狀態;如果該核心物件處於已通知狀態,則該函式立即返回wait_object_0。第二個引數指明了需要等待的時間(毫秒),可以傳遞infinite指明要無限期等待下去,如果第二個引數為0,那麼函式就測試同步物件的狀態並立即返回。如果等待超時,該函式返回wait_timeout。如果該函式失敗,返回wait_failed。可以通過下面的**來判斷:
dword dw = waitforsingleobject(hprocess, 5000); //等待乙個程序結束
switch (dw)
還可以使用waitformulitpleobjects函式來等待多個核心物件變為已通知狀態:
dword waitformultipleobjects(
dword dwcount, //等待的核心物件個數
const handle* phobjects, //乙個存放被等待的核心物件控制代碼的陣列
bool bwaitall, //是否等到所有核心物件為已通知狀態後才返回
dword dwmilliseconds); //等待時間
該函式的第乙個引數指明等待的核心物件的個數,可以是0到maximum_wait_objects(64)中的乙個值。phobjects引數是乙個存放等待的核心物件控制代碼的陣列。bwaitall引數如果為true,則只有當等待的所有核心物件為已通知狀態時函式才返回,如果為false,則只要乙個核心物件為已通知狀態,則該函式返回。第四個引數和waitforsingleobject中的dwmilliseconds引數類似。
該函式失敗,返回wait_failed;如果超時,返回wait_timeout;如果bwaitall引數為true,函式成功則返回wait_object_0,如果bwaitall為false,函式成功則返回值指明是哪個核心物件收到通知。
可以如下使用該函式:
handle h[3]; //控制代碼陣列
//三個程序控制代碼
h[0] = hprocess1;
h[1] = hprocess2;
h[2] = hprocess3;
dword dw = waitformultipleobjects(3, h, false, 5000); //等待3個程序結束
switch (dw)
你也可以同時通知乙個核心物件,同時等待另乙個核心物件,這兩個操作以原子的方式進行:
dword signalobjectandwait(
handle hobjecttosignal, //通知的核心物件
handle hobjecttowaiton, //等待的核心物件
dword dwmilliseconds, //等待的時間
bool balertable); //與io完成埠有關的引數,暫不討論
該函式在內部使得hobjecttosignal引數所指明的核心物件變成已通知狀態,同時等待hobjecttowaiton引數所代表的核心物件。dwmilliseconds引數的用法與waitforsingleobject函式類似。
該函式返回如下:wait_object_0,wait_timeout,wait_failed,wait_io_completion。
等你需要通知乙個互斥核心物件並等待乙個事件核心物件的時候,可以這麼寫:
releasemutex(hmutex);
waitforsingleobject(hevent, infinite);
可是,這樣的**不是以原子的方式來操縱這兩個核心物件。因此,可以更改如下:
signalobjectandwait(hmutex, hevent, infinite, false);
**
WaitForSingleObject的通俗講解!
用最簡單的語言說就是這個物件有兩個狀態比如我們稱0和1,稱什麼一點也不重要,有訊號和無訊號就是相對的兩個狀態,沒什麼意義,你就認為乙個狀態是0另乙個狀態是1。在程式裡如果加了waitforsingleobject,那麼程式到這裡就去檢測你給他的那個控制代碼的狀態,如果是0程式就停在這裡了,如果是1,...
WaitForSingleObject的詳細用法
在多執行緒的情況下,有時候我們會希望等待某一線程完成了再繼續做其他事情,要實現這個目的,可以使用windows api函式waitforsingleobject,或者waitformultipleobjects。這兩個函式都會等待object被標為有訊號 signaled 時才返回的。那麼,訊號是什...
WaitForSingleObject的詳細用法
在多執行緒的情況下,有時候我們會希望等待某一線程完成了再繼續做其他事情,要實現這個目的,可以使用windows api函式waitforsingleobject,或者waitformultipleobjects。這兩個函式都會等待object被標為有訊號 signaled 時才返回的。那麼,訊號是什...