CreateEvent、SetEvent、ResetEvent和WaitForSingleObject

事件对象就像一个开关:它只有两种状态---开和关。当一个事件处于”开”状态,我们称其为”有信号”,否则称为”无信号”。可以在一个线程的执行函数中创建一个事件对象,然后观察它的状态,如果是”无信号”就让该线程睡眠,这样该线程占用的CPU时间就比较少。

产生事件对象的函数如下:

(1)CreateEvent

函数原型:

HANDLE CreateEvent(   

LPSECURITY_ATTRIBUTES lpEventAttributes, // 安全属性   

BOOL bManualReset, // 复位方式   

BOOL bInitialState, // 初始状态   

LPCTSTR lpName // 对象名称   

);

      该函数创建一个Event同步对象,如果CreateEvent调用成功的话,会返回新生成的对象的句柄,否则返回NULL。

lpEventAttributes:一般为NULL

bManualReset:指定将事件对象创建成手动复原还是自动复原。如果是TRUE(手动),那么就算等待线程处理了,必须用ResetEvent函数来手工才能将事件的状态复原到无信号状态。如果设置为FALSE(自动),当事件被一个等待线程处理并释放以后,系统会自动将事件状态复原为无信号状态。所以两者可用于不同的场合,自动复位的需要每次的事件信号才会执行,而手动复位的则可以一直运行。

bInitialState:指定事件对象的初始状态。如果为TRUE,初始状态为有信号状态;否则为无信号状态。

lpName:指定事件的对象的名称,在OpenEvent函数中可能使用。

示例代码:// 创建一个有名的,不能被继承的,手动复原,初始状态是无信号状态的事件对象:

Handle h = CreateEvent(NULL,TRUE,FALSE,“MyEvent”);

一个Event被创建以后,可以用OpenEvent()API来获得它的Handle,用CloseHandle()来关闭它,用SetEvent()或PulseEvent()来设置它使其有信号,用ResetEvent()来使其无信号,用WaitForSingleObject()或WaitForMultipleObjects()来等待其变为有信号.。

(2)SetEvent

函数原型:

BOOL WINAPI SetEvent(

__in  HANDLE hEvent

);

设置事件的状态为有标记。如果事件创建时是手工的,此事件将保持有标记直到调用ResetEvent。如果事件是自动的,此事件将保持有标记,直到一个线程被释放,系统将设置事件的状态为无标记。

(3)ResetEvent

函数原型:

BOOL ResetEvent(   

HANDLE hEvent   

);

hEvent 指向事件对象的句柄,由 CreateEvent or OpenEvent 函数返回。这个句柄需要拥有EVENT_MODIFY_STATE 访问权限。函数成功,返回非0值,否则返回0值,可以调用GetLastError得到错误的详细信息。

这个函数用于手动重置事件对象。手动重置的对象在线程释放后必须手动置为无信号状态。自动重置的事件对象在一个等待它成功的线程释放后会自动变为无信号状态。 重置一个无信号的事件对象没有任何效果。

(4)WaitForSingleObject

函数原型:

DWORD WaitForSingleObject(

HANDLE hHandle,

DWORD dwMilliseconds

);

参数hHandle是一个事件的句柄,第二个参数dwMilliseconds是时间间隔。如果事件是有信号状态返回WAIT_OBJECT_0,如果事件超过dwMilliseconds值但事件还是无信号状态,则返回WAIT_TIMEOUT。之前线程会一直阻塞程序在该语句处。

举例:

#include <windows.h>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

//通过事件得知另一个线程的内部状态
//例:线程内部有三种状态:起床 吃饭 上班
HANDLE getupHandle;
HANDLE breakfastHandle;
HANDLE workHandle;

vector<string> stateTexts;
DWORD WINAPI Worker(LPVOID n);

int main()
{
	stateTexts.reserve(3);//容器预留空间
	getupHandle = CreateEvent(NULL, TRUE, FALSE, NULL);//手动,无信号
	breakfastHandle = CreateEvent(NULL, TRUE, FALSE, NULL);
	workHandle = CreateEvent(NULL, TRUE, FALSE, NULL);

	DWORD threadId;
	HANDLE threadHandle = CreateThread(NULL,
		0,
		Worker,//线程入口函数
		0,
		0,
		&threadId);

	WaitForSingleObject(getupHandle, INFINITE);
	cout << stateTexts[0] << endl;
	WaitForSingleObject(breakfastHandle, 3000);
	cout << stateTexts[1] << endl;
	WaitForSingleObject(workHandle, INFINITE);
	cout << stateTexts[2] << endl;

	CloseHandle(threadHandle);
	CloseHandle(getupHandle);
	CloseHandle(breakfastHandle);
	CloseHandle(workHandle);

	system("pause");
}

DWORD WINAPI Worker(LPVOID n)
{
	stateTexts.push_back("GetUp");
	SetEvent(getupHandle);
	stateTexts.push_back("Breakfast");
	ResetEvent(breakfastHandle);
	stateTexts.push_back("Work");
	SetEvent(workHandle);
	return 0;
}

运行结果:

先显示 GetUp,等待3000ms后显示Breakfast,接着马上显示Work

由于getupHandle和workHandle是设置为有信号的,它们的WaitForSingleObject直接有返回值

breakfastHandle设置为无信号的,它的WaitForSingleObject要等待定时完成才有返回值

CreateEvent、SetEvent、ResetEvent和WaitForSingleObject,布布扣,bubuko.com

时间: 2024-10-05 17:56:48

CreateEvent、SetEvent、ResetEvent和WaitForSingleObject的相关文章

delphi.thread.同步

注意:此文只是讲线程间的同步,其它同步不涉及. 线程同步是个好话题,因为写线程经常会遇到,所以就写写自己知道的东西. D里面,同步(特指线程同步)从线程的角度来分,有几种情况: 1:主线程与工作线程的同步 2:工作线程与主线程的同步 3:工作线程之间的同步. 同步,嗯,直白点讲,或可以说成是:A线程怎么通知B线程去做某某事,或者说某事需要:如何控制某一时间段内,A能做,B不能做(互斥). 所以,手段很重要,也就有了API,也就有了方法: 1:lock(CriticalSection) 2:Eve

CreateEvent和SetEvent及WaitForSingleObject的使用方法

CreateEvent: 1.函数功能: 创建一个命名或匿名的事件对象 2.函数原型: HANDLE CreateEvent( LPSECURITY_ATTRIBUTES lpEventAttributes,  // pointer to security attributes   BOOL bManualReset,    // flag for manual-reset event   BOOL bInitialState,   // flag for initial state   LPC

CreateEvent和SetEvent及WaitForSingleObject的用法

CreateEvent: 1.函数功能: 创建一个命名或匿名的事件对象 2.函数原型: HANDLE CreateEvent( LPSECURITY_ATTRIBUTES lpEventAttributes,  // pointer to security attributes   BOOL bManualReset,    // flag for manual-reset event   BOOL bInitialState,   // flag for initial state   LPC

线程中CreateEvent和SetEvent及WaitForSingleObject的用法

线程中CreateEvent和SetEvent及WaitForSingleObject的用法 首先介绍CreateEvent是创建windows事件的意思,作用主要用在判断线程退出,程锁定方面. CreateEvent 函功能描述:创建或打开一个命名的或无名的事件对象. EVENT有两种状态:发信号,不发信号. SetEvent/ResetEvent分别将EVENT置为这两种状态分别是发信号与不发信号. WaitForSingleObject()等待,直到参数所指定的OBJECT成为发信号状态时

setevent/waitforsingleobject

线程中CreateEvent和SetEvent及WaitForSingleObject的用法          博客分类: delphi 多线程WindowsSocket网络应用thread 首先介绍CreateEvent是创建windows事件的意思,作用主要用在判断线程退出,程锁定方面. CreateEvent 函功能描述:创建或打开一个命名的或无名的事件对象.EVENT有两种状态:发信号,不发信号. SetEvent/ResetEvent分别将EVENT置为这两种状态分别是发信号与不发信号

线程中的WaitForSingleObject和Event的用法

http://chinaxyw.iteye.com/blog/548622 首先介绍CreateEvent是创建windows事件的意思,作用主要用在判断线程退出,程锁定方面. CreateEvent 函功能描述:创建或打开一个命名的或无名的事件对象. EVENT有两种状态:发信号,不发信号. SetEvent/ResetEvent分别将EVENT置为这两种状态分别是发信号与不发信号. WaitForSingleObject()等待,直到参数所指定的OBJECT成为发信号状态时才返回,OBJEC

WaitForSingleObject()

可以让调用该函数的线程做无限的等待,直到参数所指定的OBJECT成为发信号状态时才返回,OBJECT可以是EVENT,也可以是其它内核对象. SetEvent/ResetEvent 分别将EVENT置为这两种状态分别是发信号与不发信号.

[转]同步对象Event的用法

同步对象Event的用法  首先介绍CreateEvent是创建windows事件的意思,作用主要用在判断线程退出,线程锁定方面.  CreateEvent函数功能描述:创建或打开一个命名的或无名的事件对象.  EVENT有两种状态:发信号,不发信号.   SetEvent/ResetEvent分别将EVENT置为这两种状态分别是发信号与不发信号.   WaitForSingleObject()等待(阻塞),直到参数所指定的OBJECT成为发信号状态时才返回,OBJECT可以是EVENT,也可以

秒杀多线程第九篇 经典线程同步总结 关键段 事件 互斥量 信号量

版权声明:本文为博主原创文章,未经博主允许不得转载. 前面<秒杀多线程第四篇一个经典的多线程同步问题>提出了一个经典的多线程同步互斥问题,这个问题包括了主线程与子线程的同步,子线程间的互斥,是一道非常经典的多线程同步互斥问题范例,后面分别用了四篇 <秒杀多线程第五篇经典线程同步关键段CS> <秒杀多线程第六篇经典线程同步事件Event> <秒杀多线程第七篇经典线程同步互斥量Mutex> <秒杀多线程第八篇经典线程同步信号量Semaphore> 来