用c++实现win32事件对象,同步线程

在Win32环境下编写多线程应用程序,经常要用到事件对象Event,来进行线程同步。与其相关的一组API包括:CreateEvent,SetEvent,ResetEvent,WaitForSingleObject,和CloseHandle。关于这些API的功能以及参数意义等这里就不多说了。下边,我封装了一个事件对象类,以及测试代码:

stdafx.h

 #pragma once
 #include "targetver.h"
 #include <stdio.h>
 #include <tchar.h>


MyEvent.h

    #ifndef My_Event_Header  
    #define My_Event_Header  
      
    #include <iostream>  
      
    #ifdef WIN32  
    #include <Windows.h>  
    #endif  
      
    using namespace std;  
      
    //---------------------------------------------------------------  
      
    class CEventImpl  
    {  
    protected:  
          
        /* 
         创建一个匿名事件对象 
        `bAutoReset  true   人工重置 
                     false  自动重置 
        */  
        CEventImpl(bool bManualReset);        
          
        /* 
         销毁一个事件对象 
        */  
        ~CEventImpl();  
      
        /* 
         将当前事件对象设置为有信号状态 
         若自动重置,则等待该事件对象的所有线程只有一个可被调度 
         若人工重置,则等待该事件对象的所有线程变为可被调度 
        */  
        void SetImpl();  
      
        /* 
         以当前事件对象,阻塞线程,将其永远挂起 
         直到事件对象被设置为有信号状态 
        */  
        bool WaitImpl();  
      
        /* 
         以当前事件对象,阻塞线程,将其挂起指定时间间隔 
         之后线程自动恢复可调度 
        */  
        bool WaitImpl(long lMilliseconds);  
      
        /* 
         将当前事件对象设置为无信号状态 
        */  
        void ResetImpl();  
      
    private:  
        HANDLE h_Event;  
    };  
      
    inline void CEventImpl::SetImpl()  
    {  
        if (!SetEvent(h_Event))  
        {  
            cout<<"cannot signal event"<<endl;  
        }  
    }  
      
    inline void CEventImpl::ResetImpl()  
    {  
        if (!ResetEvent(h_Event))  
        {  
            cout<<"cannot reset event"<<endl;  
        }  
    }  
      
    //---------------------------------------------------------------  
      
    class CMyEvent: private CEventImpl  
    {  
    public:  
        CMyEvent(bool bManualReset = true);  
        ~CMyEvent();  
      
        void Set();  
        bool Wait();  
        bool Wait(long milliseconds);  
        bool TryWait(long milliseconds);  
        void Reset();  
      
    private:  
        CMyEvent(const CMyEvent&);  
        CMyEvent& operator = (const CMyEvent&);  
    };  
      
      
    inline void CMyEvent::Set()  
    {  
        SetImpl();  
    }  
      
    inline bool CMyEvent::Wait()  
    {  
        return WaitImpl();  
    }  
      
    inline bool CMyEvent::Wait(long milliseconds)  
    {  
        if (!WaitImpl(milliseconds))  
        {  
            cout<<"time out"<<endl;  
            return false;  
        }  
        else  
        {  
            return true;  
        }  
    }  
      
    inline bool CMyEvent::TryWait(long milliseconds)  
    {  
        return WaitImpl(milliseconds);  
    }  
      
    inline void CMyEvent::Reset()  
    {  
        ResetImpl();  
    } 
	#endif  
      

MyEvent.cpp

#include "stdafx.h"
#include "MyEvent.h"   
CEventImpl::CEventImpl(bool bManualReset)  
    {  
        h_Event = CreateEvent(NULL, bManualReset, FALSE, NULL);  
        if (!h_Event)  
            cout<<"cannot create event"<<endl;  
    }  
      
      
    CEventImpl::~CEventImpl()  
    {  
        CloseHandle(h_Event);  
    }  
      
    bool CEventImpl::WaitImpl()  
    {  
        switch (WaitForSingleObject(h_Event, INFINITE))  
        {  
        case WAIT_OBJECT_0:  
            return true;  
        default:  
            cout<<"wait for event failed"<<endl;  
        }  
        return false;  
    }  
      
    bool CEventImpl::WaitImpl(long lMilliseconds)  
    {  
        switch (WaitForSingleObject(h_Event, lMilliseconds + 1))  
        {  
        case WAIT_TIMEOUT:  
            return false;  
        case WAIT_OBJECT_0:  
            return true;  
        default:  
            cout<<"wait for event failed"<<endl;  
            return false;  
        }  
    }  
      
    CMyEvent::CMyEvent(bool bManualReset): CEventImpl(bManualReset)  
    {  
    }  
      
    CMyEvent::~CMyEvent()  
    {  
    }  

CEvent.cpp


// test.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"


#include "MyEvent.h"  
#include <process.h>  
  
#define PRINT_TIMES 10  
  
//创建一个人工自动重置事件对象  
CMyEvent g_myEvent(true);  
int g_iNum = 0;  
  
//线程函数1  
unsigned int __stdcall ThreadProc1(void *pParam)  
{  
    for (int i = 0; i < PRINT_TIMES; i++)  
    {  
        g_iNum++;  
        cout<<"ThreadProc1 do print, Num = "<<g_iNum<<endl;  
  
        //设置事件为有信号状态  
        g_myEvent.Set();  
  
        Sleep(1000);  
    }  
  
    return (unsigned int)0;  
}  
  
//线程函数2  
unsigned int __stdcall ThreadProc2(void *pParam)  
{  
    bool bRet = false;  
    while ( 1 )  
    {  
        if ( g_iNum >= PRINT_TIMES )  
        {  
            break;  
        }  
  
        //以当前事件对象阻塞本线程,将其挂起  
        bRet = g_myEvent.Wait();  
        if ( bRet )  
        {  
            cout<<"ThreadProc2 do print, Num = "<<g_iNum<<endl;  
  
            //设置事件为无信号状态  
            g_myEvent.Reset();  
        }  
        else  
        {  
            cout<<"ThreadProc2 system exception"<<endl;  
        }  
    }  
  
    return (unsigned int)0;  
}  
  
  
int main(int argc, char* argv[])  
{  
    HANDLE hThread1, hThread2;  
    unsigned int uiThreadId1, uiThreadId2;  
  
  
    //创建两个工作线程  
    hThread1 = (HANDLE)_beginthreadex(NULL, 0, &ThreadProc1, NULL, 0, &uiThreadId1);  
    hThread2 = (HANDLE)_beginthreadex(NULL, 0, &ThreadProc2, NULL, 0, &uiThreadId2);  
  
    //等待线程结束  
    DWORD dwRet = WaitForSingleObject(hThread1,INFINITE);  
    if ( dwRet == WAIT_TIMEOUT )  
    {  
        TerminateThread(hThread1,0);  
    }  
    dwRet = WaitForSingleObject(hThread2,INFINITE);  
    if ( dwRet == WAIT_TIMEOUT )  
    {  
        TerminateThread(hThread2,0);  
    }  
  
    //关闭线程句柄,释放资源  
    CloseHandle(hThread1);  
    CloseHandle(hThread2);  
  
    system("pause");  
    return 0;  
}  


测试代码中使用全局事件对象g_myEvent,对线程1和2进行同步,每当线程1函数对全局变量g_iNum做加1之后,通知线程2,立即将该变量值打印出来。如此循环10,线程1和2分别结束自己。

    编译,运行

  


    转载来自于:   http://blog.csdn.net/chexlong



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值