日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

WaitForSingleObject和WaitForMultipleObjects用法

發(fā)布時(shí)間:2023/11/27 生活经验 54 豆豆
生活随笔 收集整理的這篇文章主要介紹了 WaitForSingleObject和WaitForMultipleObjects用法 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

轉(zhuǎn)自:http://www.360doc.com/content/10/0512/09/1072296_27178529.shtml

等待函數(shù)可使線程自愿進(jìn)入等待狀態(tài),直到一個(gè)特定的內(nèi)核對(duì)象變?yōu)橐淹ㄖ獱顟B(tài)為止。這些等待函數(shù)中最常用的是WaitForSingleObject:

? DWORD WaitForSingleObject(HANDLE hObject, DWORD dwMilliseconds);

當(dāng)線程調(diào)用該函數(shù)時(shí),第一個(gè)參數(shù)hObject標(biāo)識(shí)一個(gè)能夠支持被通知/未通知的內(nèi)核對(duì)象。第二個(gè)參數(shù)dwMilliseconds.允許該線程指明,為了等待該對(duì)象變?yōu)橐淹ㄖ獱顟B(tài),它將等待多長時(shí)間。調(diào)用下面這個(gè)函數(shù)將告訴系統(tǒng),調(diào)用函數(shù)準(zhǔn)備等待到hProcess句柄標(biāo)識(shí)的進(jìn)程終止運(yùn)行為止:

WaitForSingleObject(hProcess, INFINITE);

第二個(gè)參數(shù)告訴系統(tǒng),調(diào)用線程愿意永遠(yuǎn)等待下去(無限時(shí)間量),直到該進(jìn)程終止運(yùn)行。

通常情況下, INFINITE是作為第二個(gè)參數(shù)傳遞給WaitForSingleObject的,不過也可以傳遞任何一個(gè)值(以毫秒計(jì)算)。順便說一下, INFINITE已經(jīng)定義為0xFFFFFFFF(或-1)。當(dāng)然,傳遞INFINITE有些危險(xiǎn)。如果對(duì)象永遠(yuǎn)不變?yōu)橐淹ㄖ獱顟B(tài),那么調(diào)用線程永遠(yuǎn)不會(huì)被喚醒,它將永遠(yuǎn)處于死鎖狀態(tài),

不過,它不會(huì)浪費(fèi)寶貴的CPU時(shí)間。

下面是如何用一個(gè)超時(shí)值而不是INFINITE來調(diào)用WaitForSingleObject的例子:

DWORD dw = WaitForSingleObject(hProcess, 5000);

switch(dw)

{

?? case WAIT_OBJECT_0:

????? // The process terminated.

????? break;

?? case WAIT_TIMEOUT:

????? // The process did not terminate within 5000 milliseconds.

????? break;

?? case WAIT_FAILED:

????? // Bad call to function (invalid handle?)

????? break;

}

上面這個(gè)代碼告訴系統(tǒng),在特定的進(jìn)程終止運(yùn)行之前,或者在5 0 0 0 m s時(shí)間結(jié)束之前,調(diào)用線程不應(yīng)該變?yōu)榭烧{(diào)度狀態(tài)。因此,如果進(jìn)程終止運(yùn)行,那么這個(gè)

函數(shù)調(diào)用將在不到5000ms的時(shí)間內(nèi)返回,如果進(jìn)程尚未終止運(yùn)行,那么它在大約5000ms時(shí)間內(nèi)返回。注意,不能為dwMilliseconds傳遞0。如果傳遞了0,WaitForSingleObject函數(shù)將總是立即返回。WaitForSingleObject的返回值能夠指明調(diào)用線程為什么再次變?yōu)榭烧{(diào)度狀態(tài)。如果線程等待的對(duì)象變?yōu)橐淹ㄖ獱顟B(tài),那么返回值是WAIT_OBJECT_0。如果設(shè)置的超時(shí)已經(jīng)到期,則返回值是WAIT_TIMEOUT。如果將一個(gè)錯(cuò)誤的值(如一個(gè)無效句柄)傳遞給WaitForSingleObject,那么返回值將是WAIT_FAILED(若要了解詳細(xì)信息,可調(diào)用GetLastError)。

下面這個(gè)函數(shù)WaitForMultipleObjects與WaitForSingleObject函數(shù)很相似,區(qū)別在于它允許調(diào)用線程同時(shí)查看若干個(gè)內(nèi)核對(duì)象的已通知狀態(tài):

DWORD WaitForMultipleObjects(DWORD dwCount,

?? CONST HANDLE* phObjects,

?? BOOL fWaitAll,

?? DWORD dwMilliseconds);

dwCount參數(shù)用于指明想要讓函數(shù)查看的內(nèi)核對(duì)象的數(shù)量。這個(gè)值必須在1與MAXIMUM_WAIT_OBJECTS(在Windows頭文件中定義為64)之間。phObjects參數(shù)是指向內(nèi)核對(duì)象句柄的數(shù)組的指針。

可以以兩種不同的方式來使用WaitForMultipleObjects函數(shù)。

一種方式是讓線程進(jìn)入等待狀態(tài),直到指定內(nèi)核對(duì)象中的任何一個(gè)變?yōu)橐淹ㄖ獱顟B(tài)。

另一種方式是讓線程進(jìn)入等待狀態(tài),直到所有指定的內(nèi)核對(duì)象都變?yōu)橐淹ㄖ獱顟B(tài)。fWaitAll參數(shù)告訴該函數(shù),你想要讓它使用何種方式。如果為該參數(shù)傳遞TRUE,那么在所有對(duì)象變?yōu)橐淹ㄖ獱顟B(tài)之前,該函數(shù)將不允許調(diào)用線程運(yùn)行。

dwMilliseconds參數(shù)的作用與它在WaitForSingleObject中的作用完全相同。如果在等待的時(shí)候規(guī)定的時(shí)間到了,那么該函數(shù)無論如何都會(huì)返回。同樣,通常為該參數(shù)傳遞INFINITE,但是在編寫代碼時(shí)應(yīng)該小心,以避免出現(xiàn)死鎖情況。

WaitForMultipleObjects函數(shù)的返回值告訴調(diào)用線程,為什么它會(huì)被重新調(diào)度。可能的返回值是WAIT_FAILED和WAIT_TIMEOUT,這兩個(gè)值的作用是很清楚的。如果fWaitAll參數(shù)傳遞TRUE,同時(shí)所有對(duì)象均變?yōu)橐淹ㄖ獱顟B(tài),那么返回值是WAIT_OBJECT_0。如果為fWaitAll傳遞FALSE,那么一旦任何一個(gè)對(duì)象變?yōu)橐淹ㄖ獱顟B(tài),該函數(shù)便返回。在這種情況下,你可能想要知道哪個(gè)對(duì)象變?yōu)橐淹ㄖ獱顟B(tài)。返回值是WAIT_OBJECT_0 與(WAIT_OBJECT_0 +?dwCount-1)之間的一個(gè)值。換句話說,如果返回值不是WAIT_TIMEOUT,也不是WAIT_FAILED,那么應(yīng)該從返回值中減去WAIT_OBJECT_0。產(chǎn)生的數(shù)字是作為第二個(gè)參數(shù)傳遞給WaitForMultipleObjects的句柄數(shù)組中的索引。該索引說明哪個(gè)對(duì)象變?yōu)橐淹ㄖ獱顟B(tài)。

下面是說明這一情況的一些示例代碼:

HANDLE h[3];

h[0] = hProcess1;

h[1] = hProcess2;

h[2] = hProcess3;

DWORD dw = WaitForMultipleObjects(3, h, FALSE, 5000);

switch(dw)

{

?? case WAIT_FAILED:

????? // Bad call to function (invalid handle?)

????? break;

?? case WAIT_TIMEOUT:

????? // None of the objects became signaled within 5000 milliseconds.

????? break;

?? case WAIT_OBJECT_0 + 0:

????? // The process identified by h[0] (hProcess1) terminated.

????? break;

?? case WAIT_OBJECT_0 + 1:

????? // The process identified by h[1] (hProcess2) terminated.

????? break;

?? case WAIT_OBJECT_0 + 2:

????? // The process identified by h[2] (hProcess3) terminated.

????? break;

}

如果為fWaitAll參數(shù)傳遞FALSE,WaitForMultipleObjects就從索引0開始向上對(duì)句柄數(shù)組進(jìn)行掃描,同時(shí)已通知的第一個(gè)對(duì)象終止等待狀態(tài)。這可能產(chǎn)生一些你不希望有的結(jié)果。例如,通過將3個(gè)進(jìn)程句柄傳遞給該函數(shù),你的線程就會(huì)等待3個(gè)子進(jìn)程終止運(yùn)行。如果數(shù)組中索引為0的進(jìn)程終止運(yùn)行,WaitForMultipleObjects就會(huì)返回。這時(shí)該線程就可以做它需要的任何事情,然后循環(huán)反復(fù),等待另一個(gè)進(jìn)程終止運(yùn)行。如果該線程傳遞相同的3個(gè)句柄,該函數(shù)立即再次返回WAIT_OBJECT_0。除非刪除已經(jīng)收到通知的句柄,否則代碼就無法正確地運(yùn)行。

http://www.cnblogs.com/EmbeddedBoy/archive/2010/03/09/1681095.html

WaitForSingleObject?? 當(dāng)指定的對(duì)象的狀態(tài)被標(biāo)記或者指定的時(shí)間間隔過完時(shí),此函數(shù)返回DWORD類型參數(shù)。

?

  格式:

    DWORD WaitForSingleObject(HANDLE hHandle,DWORD dwMilliseconds);

  參數(shù):

    hHandle表示對(duì)象的句柄

    dwMilliseconds指出了時(shí)間間隔;過了指定的時(shí)間,即使對(duì)象狀態(tài)沒發(fā)生改變,函數(shù)也會(huì)返回;如果此參數(shù)設(shè)為0,函數(shù)測(cè)試對(duì)象的狀態(tài)并且立即返回;如果此參數(shù)設(shè)為INFINITE,則表示此函數(shù)的時(shí)間間隔永遠(yuǎn)不會(huì)流逝完——只有等待對(duì)象狀態(tài)被標(biāo)識(shí)時(shí)返回。

  返回值:

    成功:WAIT_OBJECT_0:表示對(duì)象的狀態(tài)被標(biāo)識(shí)

      ?? WAIT_TIMEOUT:表示指定時(shí)間已到而對(duì)象狀態(tài)沒有被標(biāo)識(shí)

    失敗:WAIT_FAILED:表明失敗

?

  WaitForSingleObject 函數(shù)檢查指定對(duì)象當(dāng)前狀態(tài),如果對(duì)象的狀態(tài)沒有被標(biāo)識(shí),則調(diào)用的線程進(jìn)入有效的等待狀態(tài)。在等待對(duì)象狀態(tài)被標(biāo)識(shí)或者指定的時(shí)間間隔到期,線程只會(huì)占據(jù)(consume)處理器一小段時(shí)間。時(shí)間間隔需要被指定在0到0x7FFFFFFF之間的正數(shù),最大的時(shí)間間隔值不等于無窮大而是0x7FFFFFFF,無窮大的時(shí)間間隔值是0xFFFFFFFF。任何在0x7FFFFFFF和0xFFFFFFFE之間的值都等同于0x7FFFFFFF;如果你需要一個(gè)時(shí)間間隔比0x7FFFFFFF還要大的話,使用表示不窮的值0xFFFFFFFF。

?

  返回之前,等待函數(shù)修改了某些類型的同步對(duì)象的狀態(tài),只有當(dāng)對(duì)象的信號(hào)狀態(tài)引起了函數(shù)的返回時(shí)這種修改才發(fā)生。例如,一個(gè)信號(hào)量對(duì)象計(jì)數(shù)減少1。

  WaitForSingleObject 函數(shù)能等待如下的各種對(duì)象:事件(Event)、線程(Thread)、進(jìn)程(Process)、互斥量(Mutex)、信號(hào)量(Semaphore)。

  使用時(shí)要小心調(diào)用等待函數(shù)和直接或間接產(chǎn)生窗口的代碼。如果一個(gè)線程創(chuàng)建了窗口,那么它必須處理消息。廣播消息發(fā)送到系統(tǒng)中的所有窗口。使用一個(gè)沒有時(shí)間間隔的等待函數(shù)的線程可能導(dǎo)致系統(tǒng)死鎖。例如,動(dòng)態(tài)數(shù)據(jù)交換(DDE)協(xié)議和COM函數(shù)CoInitialize兩個(gè)都間接地創(chuàng)建了可能導(dǎo)致死鎖的窗口。因此,如果您有一個(gè)線程創(chuàng)建的窗口,使用MsgWaitForMultipleObjects 或者 MsgWaitForMultipleObjectsEx 而不是使用WaitForSingleObject。

/

http://blog.csdn.net/lyd_253261362/archive/2009/08/15/4450202.aspx

DWORD WaitForMultipleObjects(
? DWORD nCount,???????????? // number of handles in the handle array
? CONST HANDLE *lpHandles,? // pointer to the object-handle array
? BOOL fWaitAll,??????????? // wait flag
? DWORD dwMilliseconds????? // time-out interval in milliseconds
);

其中參數(shù)

nCount 句柄的數(shù)量 最大值為MAXIMUM_WAIT_OBJECTS(64)

HANDLE 句柄數(shù)組的指針。

HANDLE 類型可以為(Event,Mutex,Process,Thread,Semaphore )數(shù)組

BOOL bWaitAll 等待的類型,如果為TRUE 則等待所有信號(hào)量有效在往下執(zhí)行,FALSE 當(dāng)有其中一個(gè)信號(hào)量有效時(shí)就向下執(zhí)行

DWORD dwMilliseconds 超時(shí)時(shí)間 超時(shí)后向執(zhí)行。 如果為WSA_INFINITE 永不超時(shí)。如果沒有信號(hào)量就會(huì)在這死等。

舉個(gè)例子:當(dāng) bWaitAll參數(shù)為FALSE 可以等待其中之一的事件

HANDLE m_hEvent[2];?

//兩事件

m_hEvent[0]=::CreateEvent(NULL, FALSE, FALSE, NULL);

m_hEvent[1]=::CreateEvent(NULL, FALSE, FALSE, NULL);

::CreateThread(NULL, 0, MyThreadProc, this, 0, NULL);

DWORD WINAPI MyThreadProc(LPVOID lpParam)

{

while(TRUE)

?{? //每次等500毫秒

?int nIndex = ::WaitForMultipleObjects(2, pThis->m_hEvent, FALSE,500);??

?if (nIndex == WAIT_OBJECT_0 + 1)

?{

?//第二個(gè)事件發(fā)生?? //ExitThread(0);?? //break;?

}

?else if (nIndex == WAIT_OBJECT_0) //第一個(gè)事件發(fā)生?

{

? //第一個(gè)事件

?? }?

else if (nIndex == WAIT_TIMEOUT) //超時(shí)500毫秒?

{?? //超時(shí)可作定時(shí)用?

}

}

?::OutputDebugString("線程結(jié)束. /n");

?return 0L;}

當(dāng)要處理第一個(gè)事件時(shí),你只需執(zhí)行SetEvent(m_hEvent[0]);

即可進(jìn)入第一個(gè)事件的位置

當(dāng)要執(zhí)行第二個(gè)事件時(shí)執(zhí)行SetEvent(m_hEvent[1]);?

?當(dāng) bWaitAll參數(shù)為TRUE 等待所有的事件

?DWORD WINAPI MyThreadProc(LPVOID lpParam)

{ while(TRUE)

?{? //每次等500毫秒?

int nIndex = ::WaitForMultipleObjects(2, pThis->m_hEvent, TRUE,500);??

? if (WAIT_OBJECT_0 + 1<= nIndex <= WAIT_OBJECT_0) //所有事件發(fā)生

?{

? //所有的信號(hào)量都有效時(shí)(事件都發(fā)生)其中之一無效。

?}

當(dāng)WaitForMultipleObjects()等到多個(gè)內(nèi)核對(duì)象的時(shí)候,

如果它的bWaitAll 參數(shù)設(shè)置為false。其返回值減去WAIT_OBJECT_0 就是參數(shù)lpHandles數(shù)組的序號(hào)。

如果同時(shí)有多個(gè)內(nèi)核對(duì)象被出發(fā),這個(gè)函數(shù)返回的只是其中序號(hào)最小的那個(gè)。


問題就在這里,我們?nèi)绾慰梢垣@取所有被同時(shí)觸發(fā)的內(nèi)核對(duì)象。

舉個(gè)例子:我們需要在一個(gè)線程中處理從完成端口、數(shù)據(jù)庫、和可等待定時(shí)器來的數(shù)據(jù)。

一個(gè)典型的實(shí)現(xiàn)方法就是:用WaitForMultipleObjects等待所有的這些事件。

如果完成端口,數(shù)據(jù)庫發(fā)過來的數(shù)據(jù)量非常大,可等待定時(shí)器時(shí)間也只有幾十毫秒。

那么這些事件同時(shí)觸發(fā)的幾率可以說非常大,我們不希望丟棄任何一個(gè)被觸發(fā)的事件。那么如何能高效地實(shí)現(xiàn)這一處理呢?

多個(gè)內(nèi)核對(duì)象被觸發(fā)時(shí),WaitForMultipleObjects選擇其中序號(hào)最小的返回。而WaitForMultipleObjects它只會(huì)改變使它返回的那個(gè)內(nèi)核對(duì)象的狀態(tài)。
這兒又會(huì)產(chǎn)生一個(gè)問題,如果序號(hào)最小的那個(gè)對(duì)象頻繁被觸發(fā),那么序號(hào)比它大的內(nèi)核對(duì)象將的不到被出理的機(jī)會(huì)。
?為了解決這一問題,可以采用雙WaitForMultipleObjects檢測(cè)機(jī)制來實(shí)現(xiàn)。見下面的例子:

DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
DWORD dwRet = 0;
int nIndex = 0;
while(1)
{dwRet = WaitForMultipleObjects(nCount,pHandles,false,INFINITE);
switch(dwRet)
{
case WAIT_TIMEOUT:
break;
case WAIT_FAILED:
return 1;
default:
{
nIndex = dwRet - WAIT_OBJECT_0;
ProcessHanlde(nIndex++); //同時(shí)檢測(cè)其他的事件 while(nIndex < nCount)
{
dwRet = WaitForMultipleObjects(nCount - nIndex,&pHandles[nIndex],false,0);
switch(dwRet)
case WAIT_TIMEOUT:
nIndex = nCount; //退出檢測(cè),因?yàn)闆]有被觸發(fā)的對(duì)象了.
break;
case WAIT_FAILED:
return 1;
default:
{ nIndex = dwRet - WAIT_OBJECT_0;
ProcessHanlde(nIndex++);
}
break;
}
}
}
break;
}
}
return 0;
}

?

http://www.51testing.com/?uid-68149-action-viewspace-itemid-73321

如果需要在一個(gè)線程中等待多個(gè)事件,則用WaitForMultipleObjects()來等待。WaitForMultipleObjects()與WaitForSingleObject()類似,
同時(shí)監(jiān)視位于句柄數(shù)組中的所有句柄。這些被監(jiān)視對(duì)象的句柄享有平等的優(yōu)先權(quán),任何一個(gè)句柄都不可能比其他句柄具有更高的優(yōu)先權(quán)。
WaitForMultipleObjects()的函數(shù)原型為:

DWORD WaitForMultipleObjects(
 DWORD nCount, // 等待句柄數(shù)
 CONST HANDLE *lpHandles, // 句柄數(shù)組首地址
 BOOL fWaitAll, // 等待標(biāo)志
 DWORD dwMilliseconds // 等待時(shí)間間隔
);

  參數(shù)nCount指定了要等待的內(nèi)核對(duì)象的數(shù)目,存放這些內(nèi)核對(duì)象的數(shù)組由lpHandles來指向。fWaitAll對(duì)指定的這nCount個(gè)內(nèi)核對(duì)象的兩種等待方式
進(jìn)行了指定,為TRUE時(shí)當(dāng)所有對(duì)象都被通知時(shí)函數(shù)才會(huì)返回,為FALSE則只要其中任何一個(gè)得到通知就可以返回。dwMilliseconds在這里的作用與
在WaitForSingleObject()中的作用是完全一致的。如果等待超時(shí),函數(shù)將返回WAIT_TIMEOUT。如果返回WAIT_OBJECT_0到WAIT_OBJECT_0+nCount-1中的某個(gè)
值,則說明所有指定對(duì)象的狀態(tài)均為已通知狀態(tài)(當(dāng)fWaitAll為TRUE時(shí))或是用以減去WAIT_OBJECT_0而得到發(fā)生通知的對(duì)象的索引(當(dāng)fWaitAll為FALSE時(shí))。
如果返回值在WAIT_ABANDONED_0與WAIT_ABANDONED_0+nCount-1之間,則表示所有指定對(duì)象的狀態(tài)均為已通知,且其中至少有一個(gè)對(duì)象是被丟棄的互斥對(duì)象
(當(dāng)fWaitAll為TRUE時(shí)),或是用以減去WAIT_OBJECT_0表示一個(gè)等待正常結(jié)束的互斥對(duì)象的索引(當(dāng)fWaitAll為FALSE時(shí))。

總結(jié)

以上是生活随笔為你收集整理的WaitForSingleObject和WaitForMultipleObjects用法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

歡迎分享!

轉(zhuǎn)載請(qǐng)說明來源于"生活随笔",并保留原作者的名字。

本文地址:WaitForSingleObject和WaitForMul