关于事件,先看MSDN介绍:
Event Objects
Anevent object is a synchronization object whose state can be explicitly set to signaled by use of theSetEvent function.
即:Event与其他线程同步不同,Event可以通过函数来设置有无信号量。
初始化
A thread uses theCreateEvent or CreateEventEx function to create an event object. The creating thread specifies the initial state of the object and whether it is a manual-reset or auto-reset event object. The creating thread can also specify a name for the event object. Threads in other processes can open a handle to an existing event object by specifying its name in a call to theOpenEvent function.
HANDLE WINAPI CreateEvent(
__in_opt LPSECURITY_ATTRIBUTES lpEventAttributes,
__in BOOL bManualReset,
__in BOOL bInitialState,
__in_opt LPCTSTR lpName
);
HANDLE WINAPI CreateEventEx(
__in_opt LPSECURITY_ATTRIBUTES lpEventAttributes,
__in_opt LPCTSTR lpName,
__in DWORD dwFlags,
__in DWORD dwDesiredAccess
);
bManualReset :指定将事件对象创建成手动复原还是自动复原。如果是TRUE(wait functions恢复到无信号状态),那么必须用ResetEvent函数来手工将事件的状态复原到无信号状态。如果设置为FALSE,当一个等待线程被释放以后,系统将会自动将事件状态复原为无信号状态。
bInitialState :指定初始化时是否为有信号状态,TRUE则有,FALSE则无。
The event object is useful in sending a signal to a thread indicating that a particular event has occurred.
事件对象是有用的在一个线程发送信号来表明一个特定的事件发生。
设置事件
Sets the specified event object to the signaled state.
BOOL WINAPI SetEvent(
__in HANDLE hEvent
);
即:让事件变为有信号状态。
复位事件
Sets the specified event object to the nonsignaled state.
BOOL WINAPI ResetEvent(
__in HANDLE hEvent
);
即:让事件变为无信号状态。
通过对事件对象进行操作,我们可以判断一个特定事件是否发生,进行同步操作等。
测试代码:
Event.h
#pragma once
#include <windows.h>
class ILock
{
public:
virtual void lock() = 0;
virtual void unlock() = 0;
};
class _CEvent : public ILock
{
public:
_CEvent();
~_CEvent();
virtual void lock();
virtual void unlock();
private:
HANDLE m_hEvent;
};
class CLock
{
public:
CLock(ILock&);
~CLock();
private:
ILock& m_lock;
};
Event.cpp
#include "stdafx.h"
#include "Event.h"
#include <assert.h>
_CEvent::_CEvent()
{
m_hEvent = ::CreateEvent(NULL, FALSE, TRUE, NULL);
assert(m_hEvent);
}
_CEvent::~_CEvent()
{
::CloseHandle(m_hEvent);
}
void _CEvent::lock()
{
WaitForSingleObject(m_hEvent, INFINITE);
}
void _CEvent::unlock()
{
SetEvent(m_hEvent);
}
CLock::CLock(ILock& locker) : m_lock(locker)
{
m_lock.lock();
}
CLock::~CLock()
{
m_lock.unlock();
}
test.cpp
// Event_test.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <process.h>
#include "Event.h"
#define THREADCOUNT 10
_CEvent g_event;
int nFood = 0;
unsigned int WINAPI EatThread(void *pParam)
{
int i = (int)pParam;
int nHasEaten = 0;
while (true)
{
CLock lock(g_event);
if (nFood > 0)
{
Sleep(100);
std::cout << "消费者" << i << "进行消费,已经吃掉(" << ++nHasEaten << "),当前剩余食物" << --nFood << std::endl;
}
else
{
break;
}
}
return 0;
}
unsigned int WINAPI ProductThread(void *pParam)
{
int i = 0;
while (i < 52)
{
std::cout << "生产者进行生产,当前剩余食物" << ++nFood << std::endl;
i++;
}
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hProductThread;
HANDLE hEatThread[THREADCOUNT];
hProductThread = (HANDLE)_beginthreadex(NULL, 0, &ProductThread, (void *)0, 0, 0);
WaitForSingleObject(hProductThread, INFINITE);
for (int i = 0; i < THREADCOUNT; i++)
{
hEatThread[i] = (HANDLE)_beginthreadex(NULL, 0, &EatThread, (void *)i, 0, 0);
}
WaitForMultipleObjects(THREADCOUNT, hEatThread, TRUE, INFINITE);
::CloseHandle(hProductThread);
for (int i = 0; i < THREADCOUNT; i++)
{
::CloseHandle(hEatThread[i]);
}
system("pause");
return 0;
}