win32 多線程 (五)Event

Event是內核對象,他能夠分爲自動和手動兩種模式。ios

HANDLE CreateEvent( 
LPSECURITY_ATTRIBUTES lpEventAttributes,
BOOL bManualReset,
BOOL bInitialState,
LPCTSTR lpName
); 
參數
lpEventAttributes  安全屬性。NULL 表示使用默認屬性。該屬性在
Windows 95中會被忽略。
bManualReset  如爲FALSE,表示這個event  將在變成激發狀態
(於是喚醒一個線程)以後,自動重置(reset)爲
非激發狀態。若是是TRUE,表示不會自動重置,
必須靠程序操做(調用ResetEvent())才能將激發
狀態的event  重置爲非激發狀態。
bInitialState  如爲TRUE,表示這個event  一開始處於激發狀
態。如爲FALSE,則表示這個event  一開始處於
非激發狀態。
lpNameEvent  對象的名稱。任何線程或進程均可以根據這
個文字名稱,使用這一event  對象。
SetEvent()  把event  對象設爲激發狀態
ResetEvent()  把event  對象設爲非激發狀態(譯註:在此我要提醒讀者,
"Reset" 的意思是「設定爲非激發狀態」,而非「從新設定爲
激發狀態」。)
PulseEvent()  若是是一個 Manual Reset Event :把event  對象設爲激發狀
態,喚醒「全部」等待中的線程,而後event  恢復爲非激發
狀態。若是是一個Auto  Reset  Event:把event  對象設爲激
髮狀態,喚醒「一個」等待中的線程,而後event  恢復爲非
激發狀態

下面作一個模擬實驗,用兩個線程輪流輸出10次,固然哪一個先開始也是能夠控制的。安全

#pragma once
#include <Windows.h>
#include <iostream>

using namespace std;

class EventOption
{
public:
    EventOption(void);
    ~EventOption(void);
    void StartRnner();
    void ReleaseOption();
private:
    static DWORD WINAPI ThreadFunctionA(LPVOID param);
    static DWORD WINAPI ThreadFunctionB(LPVOID param);
    void FunctionA();
    void FunctionB();
private:
    HANDLE m_hThreadA;
    HANDLE m_hThreadB;
    HANDLE m_hEventA;
    HANDLE m_hEventB;
};


 
#include "EventOption.h"

EventOption::EventOption(void)
{
}

EventOption::~EventOption(void)
{
}
// interface
void EventOption::StartRnner()
{
    m_hEventA = CreateEvent(NULL, TRUE, FALSE, NULL);
    m_hEventB = CreateEvent(NULL, TRUE, FALSE, NULL);
    SetEvent(m_hEventA);
    m_hThreadA = CreateThread(NULL, 0, ThreadFunctionA, this, 0, NULL);
    m_hThreadB = CreateThread(NULL, 0, ThreadFunctionB, this, 0, NULL);
}

void EventOption::ReleaseOption()
{
    WaitForSingleObject(m_hThreadA, INFINITE);
    WaitForSingleObject(m_hThreadB, INFINITE);
    CloseHandle(m_hEventA);
    CloseHandle(m_hEventB);
    CloseHandle(m_hThreadA);
    CloseHandle(m_hThreadB);
}
//private
DWORD EventOption::ThreadFunctionA(LPVOID param)
{
    EventOption *pThis = (EventOption*)param;
    pThis->FunctionA();
    return 0;
}
DWORD EventOption::ThreadFunctionB(LPVOID param)
{
    EventOption *pThis = (EventOption*)param;
    pThis->FunctionB();
    return 0;
}

void EventOption::FunctionA()
{
    int iCount = 10;
    while(iCount--)
    {
        WaitForSingleObject(m_hEventA, INFINITE);
        cout<<"FunctionA: "<<iCount<<endl;
        ResetEvent(m_hEventA);
        SetEvent(m_hEventB);
    }
}

void EventOption::FunctionB()
{
    int iCount = 10;
    while(iCount--)
    {
        WaitForSingleObject(m_hEventB, INFINITE);
        cout<<"FunctionB: "<<iCount<<endl;
        ResetEvent(m_hEventB);
        SetEvent(m_hEventA);
    }
}


#include "EventOption.h"
int _tmain(int argc, _TCHAR* argv[])
{
    EventOption test;
    test.StartRnner();
    test.ReleaseOption();
    ::getchar();
    return 0;
}
相關文章
相關標籤/搜索