程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++ 經典線程同步 事件Event(八)

C++ 經典線程同步 事件Event(八)

編輯:C++入門知識

上一篇中使用關鍵段來解決經典的多線程同步互斥問題,由於“線程所有權”特性所以關鍵段只能用於線程的互斥而不能用於同步。本篇介紹用事件Event來嘗試解決這個線程同步問題。

Event原理解析

多線程同步Event,主要用於線程間的等待通知。

內核對象中,事件內核對象是個最基本的對象。它們包含一個使用計數(與所有內核對象一樣),一個用於指明該事件是個自動重置的事件還是一個人工重置的事件的布爾值,另一個用於指明該事件處於已通知狀態還是未通知狀態的布爾值。

事件能夠通知一個操作已經完成。有兩種不同類型的事件對象。一種是人工重置的事件,另一種是自動重置的事件。當人工重置的事件得到通知時,等待該事件的所有線程均變為可調度線程。當一個自動重置的事件得到通知時,等待該事件的線程中只有一個線程變為可調度線程。

當一個線程執行初始化操作,然後通知另一個線程執行剩余的操作時,事件使用得最多。事件初始化為未通知狀態,然後,當該線程完成它的初始化操作後,它就將事件設置為已通知狀態。這時,一直在等待該事件的另一個線程發現該事件已經得到通知,因此它就變成可調度線程。


Event API

Event function Description CreateEvent Creates or opens a named or unnamed event object. CreateEventEx Creates or opens a named or unnamed event object and returns a handle to the object. OpenEvent Opens an existing named event object. PulseEvent Sets the specified event object to the signaled state and then resets it to the nonsignaled state after releasing the appropriate number of waiting threads. ResetEvent Sets the specified event object to the nonsignaled state. SetEvent Sets the specified event object to the signaled state.

OK上面是Event的基本函數(也可以直接點擊進去CSDN看參數什麼的下面是我的部分翻譯),那麼下面我面就來細細的接觸接觸吧。

Event函數解析

HANDLECreateEvent(

LPSECURITY_ATTRIBUTESlpEventAttributes,// 安全屬性

BOOLbManualReset,// 復位方式

BOOLbInitialState,// 初始狀態

LPCTSTRlpName // 對象名稱

);

參數

lpEventAttributes[輸入] 一個指向SECURITY_ATTRIBUTES結構的指針,確定返回的句柄是否可被子進程繼承。如果lpEventAttributes是NULL,此句柄不能被繼承。 Windows NT/2000:lpEventAttributes的結構中的成員為新的事件指定了一個安全符。如果lpEventAttributes是NULL,事件將獲得一個默認的安全符。 bManualReset[輸入] 指定將事件對象創建成手動復原還是自動復原。如果是TRUE,那麼必須用ResetEvent函數來手工將事件的狀態復原到無信號狀態。如果設置為FALSE,當事件被一個等待線程釋放以後,系統將會自動將事件狀態復原為無信號狀態。 bInitialState[輸入] 指定事件對象的初始狀態。如果為TRUE,初始狀態為有信號狀態;否則為無信號狀態。 lpName[輸入] 指定事件的對象的名稱,是一個以0結束的字符串指針。名稱的字符格式限定在MAX_PATH之內。名字是對大小寫敏感的。 如果lpName指定的名字,與一個存在的命名的事件對象的名稱相同,函數將請求EVENT_ALL_ACCESS來訪問存在的對象。這時候,由於bManualReset和bInitialState參數已經在創建事件的進程中設置,這兩個參數將被忽略。如果lpEventAttributes是參數不是NULL,它將確定此句柄是否可以被繼承,但是其安全描述符成員將被忽略。 如果lpName為NULL,將創建一個無名的事件對象。 如果lpName的和一個存在的信號、互斥、等待計時器、作業或者是文件映射對象名稱相同,函數將會失敗,在GetLastError函數中將返回ERROR_INVALID_HANDLE。造成這種現象的原因是這些對象共享同一個命名空間。

一個Event被創建以後,可以用OpenEvent()API來獲得它的Handle,用CloseHandle() 來關閉它,用SetEvent()或PulseEvent()來設置它使其有信號,用ResetEvent() 來使其無信號,用WaitForSingleObject()或WaitForMultipleObjects()來等待 其變為有信號.

PulseEvent()是一個比較有意思的使用方法,正如這個API的名字,它使一個Event 對象的狀態發生一次脈沖變化,從無信號變成有信號再變成無信號,而整個操作是原子的. 對自動復位的Event對象,它僅釋放第一個等到該事件的thread(如果有),而對於 人工復位的Event對象,它釋放所有等待的thread.

OpenEvent

HANDLEOpenEvent( DWORD dwDesiredAccess, BOOL bInheritHandle, LPCTSTR lpName ); 參數說明 dwDesiredAccess 【in】指定對事件對象的請求訪問權限,如果安全描述符指定的對象不允許要求通過對調用該函數的過程,函數將返回失敗。 該參數必須設置為以下值: EVENT_ALL_ACCESS 指定事件對象所有可能的權限 bInheritHandle 【in】指定是否返回的句柄是否繼承 。該參數必須設置為false lpName 【in】指向一個以null結束的字符串,即將要打開的事件對象的名字。名稱是區分大小寫的。

Event 原理就先說那麼多吧,上面沒有提及的函數,在我前面的文章都有詳細的說明和解析!

也可參照秒殺多線程第六篇 經典線程同步 事件Event。
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved