zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    CentOS查看CPU信息、位数、多核信息
    Linux常用命令大全
    chmod命令详细用法
    tar命令的详细解释
    yum和rpm命令详解
    LeetCode 241. Different Ways to Add Parentheses
    LeetCode 139. Word Break
    LeetCode 201. Bitwise AND of Numbers Range
    LeetCode 486. Predict the Winner
    LeetCode 17. Letter Combinations of a Phone Number
  • 原文地址:https://www.cnblogs.com/zhidao-chen/p/3858755.html
Copyright © 2011-2022 走看看