久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

線程中CreateEvent和SetEvent及WaitForSingleObject的用...

 swordinhand 2009-04-28

線程中CreateEvent和SetEvent及WaitForSingleObject的用法 2008-08-11 10:56

字號(hào):    

首先介紹CreateEvent是創(chuàng)建windows事件的意思,,作用主要用在判斷線程退出,,程鎖定方面.

CreateEvent

函功能描述:創(chuàng)建或打開一個(gè)命名的或無名的事件對象.
EVENT有兩種狀態(tài):發(fā)信號(hào),不發(fā)信號(hào),。
SetEvent/ResetEvent分別將EVENT置為這兩種狀態(tài)分別是發(fā)信號(hào)與不發(fā)信號(hào),。
WaitForSingleObject()等待,直到參數(shù)所指定的OBJECT成為發(fā)信號(hào)狀態(tài)時(shí)才返回,,OBJECT可以是EVENT,,也可以是其它內(nèi)核對象。

當(dāng)你創(chuàng)建一個(gè)線程時(shí),,其實(shí)那個(gè)線程是一個(gè)循環(huán),,不像上面那樣只運(yùn)行一次的。這樣就帶來了一個(gè)問題,,在那個(gè)死循環(huán)里要找到合適的條件退出那個(gè)死循環(huán),,那么是怎么樣實(shí)現(xiàn)它的呢?在Windows里往往是采用事件的方式,,當(dāng)然還可以采用其它的方式,。在這里先介紹采用事件的方式來通知從線程運(yùn)行函數(shù)退出來,它的實(shí)現(xiàn)原理是這樣,,在那個(gè)死循環(huán)里不斷地使用WaitForSingleObject函數(shù)來檢查事件是否滿足,,如果滿足就退出線程,不滿足就繼續(xù)運(yùn)行,。當(dāng)在線程里運(yùn)行阻塞的函數(shù)時(shí),,就需要在退出線程時(shí),先要把阻塞狀態(tài)變成非阻塞狀態(tài),比如使用一個(gè)線程去接收網(wǎng)絡(luò)數(shù)據(jù),,同時(shí)使用阻塞的SOCKET時(shí),,那么要先關(guān)閉SOCKET,再發(fā)送事件信號(hào),,才可以退出線程的,。

當(dāng)然我感覺重要應(yīng)用方面還是用來鎖定,實(shí)現(xiàn)所謂的pv功能,。

下面介紹函數(shù)功能,參數(shù)等

1.CreateEvent

 

函數(shù)功能描述:創(chuàng)建或打開一個(gè)命名的或無名的事件對象

函數(shù)原型:

HANDLE CreateEvent(

  LPSECURITY_ATTRIBUTES lpEventAttributes,   // 安全屬性

  BOOL bManualReset,   // 復(fù)位方式

  BOOL bInitialState,   // 初始狀態(tài)

  LPCTSTR lpName   // 對象名稱

);

參數(shù):

lpEventAttributes:

      [輸入]一個(gè)指向SECURITY_ATTRIBUTES結(jié)構(gòu)的指針,,確定返回的句柄是否可被子進(jìn)程繼承,。如果lpEventAttributes是NULL,此句柄不能被繼承,。

      Windows NT/2000:lpEventAttributes的結(jié)構(gòu)中的成員為新的事件指定了一個(gè)安全符,。如果lpEventAttributes是NULL,事件將獲得一個(gè)默認(rèn)的安全符,。

bManualReset:

      [輸入]指定將事件對象創(chuàng)建成手動(dòng)復(fù)原還是自動(dòng)復(fù)原,。如果是TRUE,那么必須用ResetEvent函數(shù)來手工將事件的狀態(tài)復(fù)原到無信號(hào)狀態(tài),。如果設(shè)置為FALSE,,當(dāng)事件被一個(gè)等待線程釋放以后,系統(tǒng)將會(huì)自動(dòng)將事件狀態(tài)復(fù)原為無信號(hào)狀態(tài),。

bInitialState:

      [輸入]指定事件對象的初始狀態(tài),。如果為TRUE,初始狀態(tài)為有信號(hào)狀態(tài),;否則為無信號(hào)狀態(tài),。

lpName:

      [輸入]指定事件的對象的名稱,是一個(gè)以0結(jié)束的字符串指針,。名稱的字符格式限定在MAX_PATH之內(nèi),。名字是對大小寫敏感的。

      如果lpName指定的名字,,與一個(gè)存在的命名的事件對象的名稱相同,,函數(shù)將請求EVENT_ALL_ACCESS來訪問存在的對象。這時(shí)候,,由于bManualReset和bInitialState參數(shù)已經(jīng)在創(chuàng)建事件的進(jìn)程中設(shè)置,,這兩個(gè)參數(shù)將被忽略。如果lpEventAttributes是參數(shù)不是NULL,,它將確定此句柄是否可以被繼承,,但是其安全描述符成員將被忽略。

      如果lpName為NULL,將創(chuàng)建一個(gè)無名的事件對象,。

      如果lpName的和一個(gè)存在的信號(hào),、互斥、等待計(jì)時(shí)器,、作業(yè)或者是文件映射對象名稱相同,,函數(shù)將會(huì)失敗,在GetLastError函數(shù)中將返回ERROR_INVALID_HANDLE,。造成這種現(xiàn)象的原因是這些對象共享同一個(gè)命名空間,。

      終端服務(wù)(Terminal Services):名稱中可以加入"Global\"或是"Local\"的前綴,這樣可以明確的將對象創(chuàng)建在全局的或事務(wù)的命名空間,。名稱的其它部分除了反斜杠(\),,可以使用任意字符。詳細(xì)內(nèi)容可參考Kernel Object Name Spaces,。

      Windows 2000:在Windows 2000系統(tǒng)中,,沒有終端服務(wù)運(yùn)行,"Global\"和"Local\"前綴將被忽略,。名稱的其它部分除了反斜杠(\),,可以使用任意字符。

      Windows NT 4.0以及早期版本, Windows 95/98:名稱中除了反斜杠(\),,可以使用任意字符。

返回值:

       如果函數(shù)調(diào)用成功,,函數(shù)返回事件對象的句柄,。如果對于命名的對象,在函數(shù)調(diào)用前已經(jīng)被創(chuàng)建,,函數(shù)將返回存在的事件對象的句柄,,而且在GetLastError函數(shù)中返回ERROR_ALREADY_EXISTS。

      如果函數(shù)失敗,,函數(shù)返回值為NULL,,如果需要獲得詳細(xì)的錯(cuò)誤信息,需要調(diào)用GetLastError,。

備注:

      調(diào)用CreateEvent函數(shù)返回的句柄,,該句柄具有EVENT_ALL_ACCESS權(quán)限去訪問新的事件對象,同時(shí)它可以在任何有此事件對象句柄的函數(shù)中使用,。

      在調(diào)用的過程中,,所有線程都可以在一個(gè)等待函數(shù)中指定事件對象句柄。當(dāng)指定的對象的狀態(tài)被置為有信號(hào)狀態(tài)時(shí),,單對象等待函數(shù)將返回,。

      對于多對象等待函數(shù),,可以指定為任意或所有指定的對象被置為有信號(hào)狀態(tài)。當(dāng)?shù)却瘮?shù)返回時(shí),,等待線程將被釋放去繼續(xù)運(yùn)行,。

      初始狀態(tài)在bInitialState參數(shù)中進(jìn)行設(shè)置,。使用SetEvent函數(shù)將事件對象的狀態(tài)置為有信號(hào)狀態(tài),。使用ResetEvent函數(shù)將事件對象的狀態(tài)置為無信號(hào)狀態(tài)。

      當(dāng)一個(gè)手動(dòng)復(fù)原的事件對象的狀態(tài)被置為有信號(hào)狀態(tài)時(shí),,該對象狀態(tài)將一直保持有信號(hào)狀態(tài),直至明確調(diào)用ResetEvent函數(shù)將其置為無符號(hào)狀態(tài),。

      當(dāng)事件的對象被置為有信號(hào)狀態(tài)時(shí),,任意數(shù)量的等待中線程,以及隨后開始等待的線程均會(huì)被釋放,。

      當(dāng)一個(gè)自動(dòng)復(fù)原的事件對象的狀態(tài)被置為有信號(hào)狀態(tài)時(shí),該對象狀態(tài)將一直保持有信號(hào)狀態(tài),,直至一個(gè)等待線程被釋放;系統(tǒng)將自動(dòng)將此函數(shù)置為無符號(hào)狀態(tài),。如果沒有等待線程正在等待,事件對象的狀態(tài)將保持有信號(hào)狀態(tài),。

      多個(gè)進(jìn)程可持有同一個(gè)事件對象的多個(gè)句柄,,可以通過使用此對象來實(shí)現(xiàn)進(jìn)程間的同步。下面的對象共享機(jī)制是可行的:

      ·在CreateEvent函數(shù)中,,lpEventAttributes參數(shù)指定句柄可被繼承時(shí),,通過CreateProcess函數(shù)創(chuàng)建的子進(jìn)程繼承的事件對象句柄。

      ·一個(gè)進(jìn)程可以在DuplicateHandle函數(shù)中指定事件對象句柄,,從而獲得一個(gè)復(fù)制的句柄,此句柄可以被其它進(jìn)程使用,。

      ·一個(gè)進(jìn)程可以在OpenEvent或CreateEvent函數(shù)中指定一個(gè)名字,,從而獲得一個(gè)有名的事件對象句柄。

      使用CloseHandle函數(shù)關(guān)閉句柄,。當(dāng)進(jìn)程停止時(shí),,系統(tǒng)將自動(dòng)關(guān)閉句柄。當(dāng)最后一個(gè)句柄被關(guān)閉后,,事件對象將被銷毀,。

使用環(huán)境:

      Windows NT/2000:需要3.1或更高版本

      Windows 95/98:需要Windows 95或更高版本

      頭文件:定義在Winbase.h;需要包含 Windows.h。

      導(dǎo)入庫:user32.lib

      Unicode:在Windows NT/2000中,,以 Unicode 和 ANSI 執(zhí)行

    一個(gè)Event被創(chuàng)建以后,可以用OpenEvent()API來獲得它的Handle,用CloseHandle()   

    來關(guān)閉它,用SetEvent()或PulseEvent()來設(shè)置它使其有信號(hào),用ResetEvent()   

    來使其無信號(hào),用WaitForSingleObject()或WaitForMultipleObjects()來等待   

    其變?yōu)橛行盘?hào).   

   

    PulseEvent()是一個(gè)比較有意思的使用方法,正如這個(gè)API的名字,它使一個(gè)Event   

    對象的狀態(tài)發(fā)生一次脈沖變化,從無信號(hào)變成有信號(hào)再變成無信號(hào),而整個(gè)操作是原子的.   

    對自動(dòng)復(fù)位的Event對象,它僅釋放第一個(gè)等到該事件的thread(如果有),而對于   

    人工復(fù)位的Event對象,它釋放所有等待的thread.  


2.    WaitForSingleObject的用法                                       

WaitForSingleObject的用法

DWORD WaitForSingleObject(

  HANDLE hHandle,

  DWORD dwMilliseconds

);

參數(shù)hHandle是一個(gè)事件的句柄,,第二個(gè)參數(shù)dwMilliseconds是時(shí)間間隔。如果時(shí)間是有信號(hào)狀態(tài)返回WAIT_OBJECT_0,,如果時(shí)間超過dwMilliseconds值但時(shí)間事件還是無信號(hào)狀態(tài)則返回WAIT_TIMEOUT,。

hHandle可以是下列對象的句柄:

    Change notification

Console input

Event

Job

Memory resource notification

Mutex

Process

Semaphore

Thread

Waitable timer

WaitForSingleObject函數(shù)用來檢測hHandle事件的信號(hào)狀態(tài),當(dāng)函數(shù)的執(zhí)行時(shí)間超過dwMilliseconds就返回,,但如果參數(shù)dwMilliseconds為INFINITE時(shí)函數(shù)將直到相應(yīng)時(shí)間事件變成有信號(hào)狀態(tài)才返回,,否則就一直等待下去,直到WaitForSingleObject有返回直才執(zhí)行后面的代碼,。在這里舉個(gè)例子:

先創(chuàng)建一個(gè)全局Event對象g_event:

    CEvent g_event;

在程序中可以通過調(diào)用CEvent::SetEvent設(shè)置事件為有信號(hào)狀態(tài),。

下面是一個(gè)線程函數(shù)MyThreadPro()

UINT CFlushDlg::MyThreadProc( LPVOID pParam )

{

     WaitForSingleObject(g_event,INFINITE);

     For(;;)

        {

         ………….

        }

     return 0;

}

在這個(gè)線程函數(shù)中只有設(shè)置g_event為有信號(hào)狀態(tài)時(shí)才執(zhí)行下面的for循環(huán),因?yàn)間_event是全局變量,,所以我們可以在別的線程中通過g_event. SetEvent控制這個(gè)線程,。

還有一種用法就是我們可以通過WaitForSingleObject函數(shù)來間隔的執(zhí)行一個(gè)線程函數(shù)的函數(shù)體

     UINT CFlushDlg::MyThreadProc( LPVOID pParam )

{

     while(WaitForSingleObject(g_event,MT_INTERVAL)!=WAIT_OBJECT_0)

     {

         ………………

     }

     return 0;

}

在這個(gè)線程函數(shù)中可以可以通過設(shè)置MT_INTERVAL來控制這個(gè)線程的函數(shù)體多久執(zhí)行一次,當(dāng)事件為無信號(hào)狀態(tài)時(shí)函數(shù)體隔MT_INTERVAL執(zhí)行一次,,當(dāng)設(shè)置事件為有信號(hào)狀態(tài)時(shí),,線程就執(zhí)行完畢了(return 0)。

 

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請遵守用戶 評(píng)論公約

    類似文章 更多