Windows下線程中CreateEvent和SetEvent及WaitForSingleObject的用法總結

Windows下的事件編程,應包含頭文件
#include <windows.h>          // for HANDLE

     當你創建一個線程時,其實那個線程是一個循環,不像上面 那樣只運行一次的。這樣就帶來了一個問題,在那個死循環裏要找到合適的條件退出那個死循環,那麼是怎麼樣實現它的呢?

    在Windows裏往往是採用事件的 方式,它的實現原理如下:在那個死循環裏不斷地使用 WaitForSingleObject函數來檢查事件是否滿足,如果滿足就退出線程,不滿足就繼續運行。

    對函數進行解釋。

  • CreateEvent是創建windows事件的意思,作用主要用在判斷線程退出,線程鎖定方面.

          返回值:如果函數調用成功,函數返回事件對象的句柄,如果函數調用失敗,函數返回值爲NULL

           EVENT有兩種狀態:發信號,不發信號。

  • SetEvent:將EVENT置爲發信號。
  • ResetEvent:將EVENT置爲不發信號。
  • WaitForSingleObject():等待,直到參數所指定的OBJECT成爲發信號狀態時才返回,OBJECT可以是EVENT,也可以是其它內核對象。
  •  WaitForSingleObject用法:

(1)函數功能描述:用來檢測hHandle事件的信號狀態,在某一線程中調用該函數時,線程暫時掛起,如果在掛起的dwMilliseconds毫秒內,線程所等待的對象變爲有信號狀態,則該函數立即返回;如果超時時間已經到達dwMilliseconds毫秒,但hHandle所指向的對象還沒有變成有信號狀態,函數照樣返回。參數dwMilliseconds有兩個具有特殊意義的值:0和INFINITE。若爲0,則該函數立即返回;若爲INFINITE,則線程一直被掛起,直到hHandle所指向的對象變爲有信號狀態時爲止。

(2)函數原型:

DWORD WINAPI WaitForSingleObject(
__in HANDLE hHandle,      // 句柄
__in DWORD dwMilliseconds   // 時間間隔
);
(3)參數:
hHandle:對象句柄。可以指定一系列的對象,如Event、Job、Memory resource notification、Mutex、Process、Semaphore、Thread、Waitable timer等。
 
dwMilliseconds:定時時間間隔,單位爲milliseconds(毫秒).
(1)如果指定一個非零值,函數處於等待狀態直到hHandle標記的對象被觸發,或者時間到了。
(2)如果dwMilliseconds爲0,對象沒有被觸發信號,函數不會進入一個等待狀態,它總是立即返回。
(3)如果dwMilliseconds爲INFINITE,對象被觸發信號後,函數纔會返回。
(4)返回值:執行成功,返回值指示出引發函數返回的事件。可能的返回值:
WAIT_ABANDONED 0x00000080:當hHandle爲mutex時,如果擁有mutex的線程在結束時沒有釋放核心對象會引發此返回值。

WAIT_OBJECT_0 0x00000000 :指定的對象出有信號狀態。

WAIT_TIMEOUT 0x00000102:等待超時。

WAIT_FAILED 0xFFFFFFFF :出現錯誤,可通過GetLastError得到錯誤代碼。
  •  具體實例
//test.h

#include <windows.h>          // for HANDLE
HANDLE m_HandleWaitForTest;

m_HandleWaitForTest= CreateEvent(NULL,FALSE,FALSE,NULL);

// test.cpp
void fun()
{
    ......//其他操作

    ResetEvent(m_HandleWaitForTest);//程序剛開始事件清零,設爲無信號狀態

    ......//其他操作

    QtConcurrent::run(this, &MotionTest::TestEvent);//開啓一個線程

    ......//其他操作

    if (!(WaitForSingleObject(m_HandleWaitForTest, 5000) == WAIT_OBJECT_0))
    {
        return;
    }
}


void MotionTest::TestEvent()
{
    if(Test())
    {
        SetEvent(m_HandleWaitForTest);//設置爲有信號,爲後續判斷該線程是否執行完做準備
    }
    else
    {
        MessageInformation(tr("test failed"), false);
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章