转:Win32 C++事件对象,线程同步

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 "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 : 定义控制台应用程序的入口点。
//
 
#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分别结束自己。
栏地址:https://blog.youkuaiyun.com/chexlong/article/details/7078521

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值