进程、线程同步互斥学习 —— 事件

来源:互联网 发布:mac打开mpp 编辑:程序博客网 时间:2024/06/05 20:45

关于事件,先看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 orCreateEventEx 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 theOpenEventfunction.

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;}


0 0
原创粉丝点击