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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

WaitForMultipleObject与MsgWaitForMultipleObjects用法

發布時間:2025/3/12 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 WaitForMultipleObject与MsgWaitForMultipleObjects用法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

用戶模式的線程同步機制效率高,如果需要考慮線程同步問題,應該首先考慮用戶模式的線程同步方法。但是,用戶模式的線程同步有限制,對于多個進程之間的線程同步,用戶模式的線程同步方法無能為力。這時,只能考慮使用內核模式。

用戶模式與內核模式線程同步機制比較:

?

用戶模式

內核模式

優點

線程同步機制速度快

?

支持多個進程之間的線程同步

防止死鎖

缺點

容易陷入死鎖狀態

多個進程之間的線程同步會出現問題。(比如競爭資源、死鎖

線程同步機制速度慢

線程必須從用戶模式轉為內核模式。這個轉換需要很大的代價:往返一次需要占用x 8 6平臺上的大約1 0 0 0個C P U周期

?

Windows提供了許多內核對象來實現線程的同步。對于線程同步而言,這些內核對象有兩個非常重要的狀態:“已通知”狀態,“未通知”狀態(也有翻譯為:受信狀態,未受信狀態)。Windows提供了幾種內核對象可以處于已通知狀態和未通知狀態:進程、線程、作業、文件、控制臺輸入/輸出/錯誤流、事件、等待定時器、信號量、互斥對象。

你可以通知一個內核對象,使之處于“已通知狀態”,然后讓其他等待在該內核對象上的線程繼續執行。你可以使用Windows提供的API函數,等待函數來等待某一個或某些內核對象變為已通知狀態。

?

一、WaitForSingleObjectWaitForMulitpleObjects

函數功能: 等待一個內核對象變為已通知狀態

可以使用WaitForSingleObject函數來等待一個內核對象變為已通知狀態:

DWORD WaitForSingleObject(

HANDLE hObject, //指明一個內核對象的句柄

DWORD dwMilliseconds); //等待時間

該函數需要傳遞一個內核對象句柄,該句柄標識一個內核對象,如果該內核對象處于未通知狀態,則該函數導致線程進入阻塞狀態;如果該內核對象處于已通知狀態,則該函數立即返回WAIT_OBJECT_0。第二個參數指明了需要等待的時間(毫秒),可以傳遞INFINITE指明要無限期等待下去,如果第二個參數為0,那么函數就測試同步對象的狀態并立即返回。如果等待超時,該函數返回WAIT_TIMEOUT。如果該函數失敗,返回WAIT_FAILED。可以通過下面的代碼來判斷:

?

DWORD dw = WaitForSingleObject(hProcess, 5000); //等待一個進程結束

switch (dw)

{

case WAIT_OBJECT_0:

// hProcess所代表的進程在5秒內結束

break;

?

case WAIT_TIMEOUT:

// 等待時間超過5

break;

?

case WAIT_FAILED:

// 函數調用失敗,比如傳遞了一個無效的句柄

break;

}

還可以使用WaitForMulitpleObjects函數來等待多個內核對象變為已通知狀態:

DWORD WaitForMultipleObjects(

DWORD dwCount, //等待的內核對象個數

CONST HANDLE* phObjects, //一個存放被等待的內核對象句柄的數組

BOOL bWaitAll, //是否等到所有內核對象為已通知狀態后才返回

DWORD dwMilliseconds); //等待時間

該函數的第一個參數指明等待的內核對象的個數,可以是0MAXIMUM_WAIT_OBJECTS64)中的一個值。phObjects參數是一個存放等待的內核對象句柄的數組。bWaitAll參數如果為TRUE,則只有當等待的所有內核對象為已通知狀態時函數才返回,如果為FALSE,則只要一個內核對象為已通知狀態,則該函數返回。第四個參數和WaitForSingleObject中的dwMilliseconds參數類似。

該函數失敗,返回WAIT_FAILED;如果超時,返回WAIT_TIMEOUT;如果bWaitAll參數為TRUE,函數成功則返回WAIT_OBJECT_0,如果bWaitAllFALSE,函數成功則返回值指明是哪個內核對象收到通知。

?

可以如下使用該函數:

HANDLE h[3]; //句柄數組

//三個進程句柄

h[0] = hProcess1;

h[1] = hProcess2;

h[2] = hProcess3;

DWORD dw = WaitForMultipleObjects(3, h, FALSE, 5000); //等待3個進程結束

switch (dw)

{

case WAIT_FAILED:

// 函數呼叫失敗

break;

?

case WAIT_TIMEOUT:

// 超時

break;

?

case WAIT_OBJECT_0 + 0:

// h[0]hProcess1)所代表的進程結束

break;

?

case WAIT_OBJECT_0 + 1:

// h[1]hProcess2)所代表的進程結束

break;

?

case WAIT_OBJECT_0 + 2:

// h[2]hProcess3)所代表的進程結束

break;

}

?

你也可以同時通知一個內核對象,同時等待另一個內核對象,這兩個操作以原子的方式進行:

DWORD SignalObjectAndWait(

HANDLE hObjectToSignal, //通知的內核對象

HANDLE hObjectToWaitOn, //等待的內核對象

DWORD dwMilliseconds, //等待的時間

BOOL bAlertable); //IO完成端口有關的參數,暫不討論

該函數在內部使得hObjectToSignal參數所指明的內核對象變成已通知狀態,同時等待hObjectToWaitOn參數所代表的內核對象。dwMilliseconds參數的用法與WaitForSingleObject函數類似。

該函數返回如下:WAIT_OBJECT_0WAIT_TIMEOUTWAIT_FAILEDWAIT_IO_COMPLETION。

等你需要通知一個互斥內核對象并等待一個事件內核對象的時候,可以這么寫:

ReleaseMutex(hMutex);

WaitForSingleObject(hEvent, INFINITE);

可是,這樣的代碼不是以原子的方式來操縱這兩個內核對象。因此,可以更改如下:

SignalObjectAndWait(hMutex, hEvent, INFINITE, FALSE);

?

二、MsgWaitForMultipleObjects

函數功能:阻塞時仍可以響應消息

MsgWaitForMultipleObjects()函數類似WaitForMultipleObjects(),但它會在“對象被激發”或“消息到達隊列”時被喚醒而返回。MsgWaitForMultipleObjects()多接收一個參數,允許指定哪些消息是觀察對象。

?

DWORD MsgWaitForMultipleObjects(

? DWORD nCount,????????? // 表示pHandles所指的handles數組的元素個數,最大容量是MAXIMUM_WAIT_OBJECTS

?

? LPHANDLE pHandles,???? // 指向一個由對象handles組成的數組,這些handles的類型不需要相同

? BOOL fWaitAll,???????? // 是否等待所有的handles被激發才返回

? DWORD dwMilliseconds,? // 超時時間

? DWORD dwWakeMask?????? // 欲觀察的用戶輸入消息類型

);

?

參數

dwWakeMask

欲觀察的用戶輸入消息類型: Value Meaning

QS_ALLEVENTS An input, WM_TIMER, WM_PAINT, WM_HOTKEY, or posted message is in the queue.

QS_ALLINPUT Any message is in the queue.

QS_ALLPOSTMESSAGE A posted message (other than those listed here) is in the queue.?

QS_HOTKEY A WM_HOTKEY message is in the queue.

QS_INPUT An input message is in the queue.

QS_KEY A WM_KEYUP, WM_KEYDOWN, WM_SYSKEYUP, or WM_SYSKEYDOWN message is in the queue.

QS_MOUSE A WM_MOUSEMOVE message or mouse-button message (WM_LBUTTONUP, WM_RBUTTONDOWN, and so on).

QS_MOUSEBUTTON A mouse-button message (WM_LBUTTONUP, WM_RBUTTONDOWN, and so on).

QS_MOUSEMOVE A WM_MOUSEMOVE message is in the queue.

QS_PAINT A WM_PAINT message is in the queue.

QS_POSTMESSAGE A posted message (other than those just listed) is in the queue.

QS_SENDMESSAGE A message sent by another thread or application is in the queue.

QS_TIMER A WM_TIMER message is in the queue

?

返回值

WAIT_TIMEOUT :因時間終了而返回

WAIT_OBJECT_0 :當bWaitAllTRUE

WAIT_OBJECT_0 to (WAIT_OBJECT_0 + nCount 1) bWaitAllFALSE,將返回值減去WAIT_OBJECT_0,就表示數組中哪一個handle被激發了

WAIT_ABANDONED_0 to (WAIT_ABANDONED_0 + nCount 1) :等待的對象中有任何mutexes

WAIT_FAILED :函數失敗時返回該值,可以使用GetLastError()找出失敗的原因

WAIT_OBJECT_0 + nCount :消息到達隊列

?

MsgWaitForMultipleObjects()的正確使用方式是改寫主消息循環,使得激發狀態的handles得以像消息一樣被對待。通常程序中只會有一個地方調用MsgWaitForMultipleObjects(),而這個調用存在于消息循環中。

注意:

1. 在收到WM_QUIT之后,Windows仍然會傳送消息給你,如果要在收到WM_QUIT之后等待所有線程結束,必須繼續處理你的消息,否則窗口會變得反應遲鈍,而且沒有重繪能力。

2.MsgWaitForMultipleObjects()不允許handles數組中有縫隙產生。所以當某個handle被激發了時,應該在下一次調用MsgWaitForMultipleObjects之前先把handles數組做個整理、緊壓,不要只是把數組中的handle設為NULL

3.如果有另一個線程改變了對象數組,而那是你正在等待的,那么需要一種方法,可以強迫MsgWaitForMultipleObjects返回,并重新開始,以包含新的handle

?

三、MsgWaitForMultipleObjectsEx

函數功能:阻塞時仍可以響應消息

函數原型

DWORD MsgWaitForMultipleObjectsEx(

DWORD nCount, // 句柄數組中句柄數目

LPHANDLE pHandles, // 指向句柄數組的指針

DWORD dwMilliseconds, // 以毫秒計的超時值

DWORD dwWakeMask, // 要等待的輸入事件類型

DWORD dwFlags // 等待標志

);

?

參數

nCount,指定pHandles指向的數組中的對象句柄數目。最大對象數目是MAXIMUM_WAIT_OBJECTS-1

pHandles ,指向一個對象句柄數組。要得到可以使用的對象句柄類型清單,請查看備注部分。數組中可以包含多種對象類型。 Windows NT: 數組中句柄必須擁有SYNCHRONIZE訪問權。要得到更多相關信息,請查閱MSDNStandard Access Rights。

dwMilliseconds ,指定以毫秒計的超時值。即使參數dwWakeMaskdwFlags中指定的條件未滿足,超時后函數仍然返回。如果dwMilliseconds值為0,函數測試指定的對象狀態并立即返回。如果dwMilliseconds值為INFINITE,函數超時周期為無窮大。

dwWakeMask ,指定被加到對象句柄數組中的輸入事件對象句柄的對象類型。這個參數可以是下面列出值的任意組合:

值含義

QS_ALLEVENTS

?WM_TIMER, WM_PAINT, WM_HOTKEY輸入消息或登記消息(posted message)在消息隊列中

QS_ALLINPUT

?任何消息在消息隊列中

QS_ALLPOSTMESSAGE

?登記消息(在此處列出的除外)在消息隊列中

QS_HOTKEY

?WM_HOTKEY消息在消息隊列中

QS_INPUT

?輸入消息在消息隊列中

?

QS_KEY

?WM_KEYUP,WM_KEYDOWN,WM_SYSKEYUPWM_SYSKEYDOWN消息在消息隊列中

QS_MOUSE

?WM_MOUSEMOVE消息或鼠標點擊消息(WM_LBUTTONUP,WM_RBUTTONDOWN)在消息隊列中

QS_MOUSEBUTTON

?鼠標點擊消息(WM_LBUTTONUP,WM_RBUTTONDOWN)在消息隊列中

QS_MOUSEMOVE

?WM_MOUSEMOVE消息在消息隊列中

QS_PAINT

?WM_PAINT消息在消息隊列中

QS_POSTMESSAGE

?登記消息(在此處列出的除外)在消息隊列中

QS_SENDMESSAGE

?由另一個線程或應用發送的消息在消息隊列中?

QS_TIMER

?WM_TIMER消息在消息隊列中

?

dwFlags ,指定等待類型。這個參數可以是下面列出值的任意組合:

值含義

0

當對象中任意一個變為有信號狀態則函數返回。返回值指出是哪個對象狀態的改變導致函數返回。

MWMO_WAITALL

只有當pHandles數組中所有對象有信號時函數返回

MWMO_ALERTABLE

調用QueueUserAPC加入一個APC將導致函數返回

MWMO_INPUTAVAILABLE

只適用于Windows 98, Windows NT 5.0及其以后版本: 消息隊列中存在輸入函數將返回,甚至于輸入已經被另一個函數檢測過了,如PeekMessage函數

?

返回值

假如函數成功,返回值表明引起函數返回的事件。成功的函數值是下面中的一個:

值含義

WAIT_OBJECT_0 (WAIT_OBJECT_0 + nCount - 1)

假如MWMO_WAITALL標志置位,返回值指明所有指定的對象處于有信號狀態。返回值減去WAIT_OBJECT_0就是pHandles數組中引起函數返回的對象的索引

WAIT_OBJECT_0 + nCount

有新的在dwWakeMask參數中指定的輸入類型存在于輸入隊列中。函數如:PeekMessage,GetMessage,GetQueueStatusWaitMessage將隊列中的消息標記為舊的。因此,當你在這些函數之后調用MsgWaitForMultipleObjectsEx,函數將不會返回,除非有新的被指定的輸入到達。當一個需要該線程活動的系統事件發生時也將返回該值,例如前臺活動。因此即使沒有相應的輸入發生或dwWaitMask0MsgWaitForMultipleObjectsEx也可以返回。如果發生這種情況,那么在再次調用MsgWaitForMultipleObjectsEx之前要調用PeekMessageGetMessage處理系統事件。

?

WAIT_ABANDONED_0 (WAIT_ABANDONED_0 + nCount - 1)

假如MWMO_WAITALL標志置位,返回值指明所有指定的對象處于有信號狀態并且至少其中的一個是一個被舍棄的(abandoned)互斥對象。另外,返回值減去WAIT_ABANDONED_0即是pHandles數組中引起函數返回的被舍棄的互斥對象的索引

?

WAIT_IO_COMPLETION

等待被一加入隊列中的用戶模式異步過程調用(user-mode asynchronous procedure call (APC))所終止

?

WAIT_TIMEOUT

超時,但dwFlagsdwWakeMask參數中條件未滿足

?

假如函數調用失敗,返回值是0xFFFFFFFF。若想獲得更多的錯誤信息,請調用GetLastError函數。

?

備注

MsgWaitForMultipleObjectsEx函數檢測是否dwWakeMaskdwFlags參數中指定的條件滿足。假如條件未滿足,調用線程進入高效的等待狀態。線程在等待條件之一滿足或超時時只用很少的處理器時間。

返回前,等待函數會修改某些異步對象的狀態。修改只會針對那些置信號狀態后會導致函數返回的對象,例如系統將信號對象(semaphore)的引用計數減一。當dwFlags為零并且多個對象處于信號狀態時,函數選擇對象中的一個來確保等待;未被選中的對象的狀態不受影響。

?

MsgWaitForMultipleObjectsEx函數可以在pHandles數組中指定下列的對象類型:

改變通知(Change notification)

控制臺輸入

事件

作業(job)

互斥

進程

信號

線程

等待計時器

要獲取更多信息,請參閱Synchronization Objects

?

QS_ALLPOSTMESSAGEQS_POSTMESSAGE標志被消除時是有區別的。QS_POSTMESSAGE在你調用GetMessagePeekMessage時被消除,而不管你是否正在過濾消息。QS_ALLPOSTMESSAGE在你調用不過濾消息(wMsgFilterMinwMsgFilterMax皆為零)GetMessagePeekMessage時被消除。這在你調用PeekMessage多次以獲得不同區域的消息時會很有用。

?

Windows CE:Windows CE不支持QS_HOTKEY賦予dwWakeMask參數,也不支持MWMO_WAITALLMWMO_ALERTABLE標志賦予dwFlags參數。

?

MsgWaitForMultipleObjectsEx復制句柄表,將消息隊列事件加入其中,然后調用WaitForMultipleObjects

?

示例代碼段

?

//一段代碼,等待線程與事件對象及消息,超時值為2000毫秒

?

CWinThread* pThread = AfxBeginThread((AFX_THREADPROC)YourThreadFun, NULL);

?

HANDLE hThreadAndEvent[ 2 ];

?

hThreadAndEvent[ 0 ] = pThread->m_hThread;

?

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

?

DWORD dwReturn = ::MsgWaitForMultipleObjectsEx(2,

hThreadAndEvent,

2000,//2秒醒來一次

QS_ALLEVENTS,

MWMO_INPUTAVAILABLE

);

?

if ( dwReturn==WAIT_OBJECT_0 )

{

?

//線程對象通知

?

}

if ( dwReturn==WAIT_OBJECT_0+1 )

{

?

//事件對象通知

?

}

if ( dwReturn == WAIT_OBJECT_0+2 )

{

?

//消息

?

}

if ( dwReturn == WAIT_TIMEOUT )

?

{

?

//超時

?

}

總結

以上是生活随笔為你收集整理的WaitForMultipleObject与MsgWaitForMultipleObjects用法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 成人短视频在线观看 | 香蕉视频一区二区三区 | 日本一本久草 | 97人妻天天摸天天爽天天 | 国产福利免费观看 | 免费的性爱视频 | 亚洲精品av中文字幕在线在线 | 国产情侣久久久久aⅴ免费 caoporn成人 | 欧美黄色图片 | 日韩av三级在线观看 | 国产精品白嫩白嫩大学美女 | 日本伦理中文字幕 | 女同hd系列中文字幕 | 国产精品免费一区二区区 | 精品欧美乱码久久久久久 | 国产精品久久久久久久久免费桃花 | 亚洲最大成人在线视频 | aa黄色片| 爱的天堂 | 午夜性生活视频 | 欧美成人一区二免费视频软件 | 青草青在线 | 成人羞羞国产免费 | 国产精品国语自产拍在线观看 | 日本我不卡 | 欧美人妖老妇 | 青青青视频在线播放 | 欧美黑人又粗又大高潮喷水 | 精品免费国产一区二区三区四区 | 日韩一区二区在线免费观看 | 日韩乱码在线 | 波多野结衣调教 | 日本亚洲精品 | 人妻妺妺窝人体色www聚色窝 | 国产精品成人无码专区 | 久久精品99北条麻妃 | 麻豆视频在线看 | 丰满人妻一区二区三区免费 | 欧美三级自拍 | 成人av在线看 | 男男做爰猛烈啪啪高 | 毛片视频网址 | 久久性生活 | 国产日视频| 亚洲av无码一区二区三区在线播放 | 日韩在线视频在线观看 | 国产a精品 | 两口子交换真实刺激高潮 | 健身教练巨大粗爽gay视频 | 白峰美羽在线播放 | 大肉大捧一进一出好爽动态图 | 国产对白videos麻豆高潮 | 天天操天天舔天天干 | 一区在线免费 | 老熟妻内射精品一区 | 99re国产精品 | 国产欧美精品在线观看 | 在线观看一区视频 | 国产欧美一区二 | 老司机精品在线 | 影音先锋波多野结衣 | 超碰免费91 | 亚洲国产成人精品久久 | 午夜香蕉网| 国产熟女一区二区 | 操操网| 久草资源网 | 看av网址| 毛片无码一区二区三区a片视频 | 99超碰在线观看 | 69网址| 国产对白羞辱绿帽vk | 男人天堂2019 | 久久艳片www.17c.com | 爱情岛亚洲品质自拍极速福利网站 | 一级欧美一级日韩片 | 少妇按摩一区二区三区 | 欧美日韩精品区别 | 99er精品视频| 日本久久精品视频 | 欧美大片免费高清观看 | 日批视频免费在线观看 | 成人综合色站 | 男生舔女生的屁股 | 亚洲视频精品 | 成人三级电影网站 | 中文天堂在线播放 | 在线免费观看av的网站 | 久久久国产片 | 成人免费看片98 | 五月婷婷丁香综合 | 不卡中文字幕 | 欧美性大战久久久 | 欧美日韩午夜 | 黄色毛毛片 | 精品少妇人妻av免费久久久 | 高清成人免费视频 | 肥熟女一区二区三肥熟女 | 亚洲色图综合网 |