win32 多線程 (五)Event


Event是內核對象,他可以分為自動和手動兩種模式。

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;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM