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

关于事件,先看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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值