• 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;
    }
  • 相关阅读:
    windbg常用命令
    Windbg双机调试环境配置(Windows7/Windows XP+VirtualBox/VMware+WDK7600)
    SVN使用说明文档
    JavaScript-浏览器兼容之客户端检测
    JavaScript-执行环境
    JavaScript-函数
    JavaScript-静态私有变量
    JavaScript-构造函数模式
    JavaScript 自执行函数剖析
    easyui如何在datagrid 每行增加超链接
  • 原文地址:https://www.cnblogs.com/zhidao-chen/p/3858755.html
Copyright © 2020-2023  润新知