事件——win32 API 例子
一、简单例子
HANDLE hEvent;
线程A: WaitForSingleObject(hEvent,INGINITE); //在事件上处于等待状态
线程B: SetEvent(hEvent); //用于触发一个事件
main: hEvent = CreateEvent(NULL,FALSE,FALSE,NULL);//自动事件,无信号
handle1 = CreateThread(NULL,0,线程A,NULL,0,&dw1);
handle2 = CreateThread(NULL,0,线程B,NULL,0,&dw2);
CloseHandle(handle1);
CloseHandle(handle2);
CloseHandle(hEvent);
程序的运行结果是:A一直处于等待状态,直到B把事件触发为有信号状态时,A才能进入并执行动作。
二、关于共享缓冲区的例子
HANDLE hWriteEvent;
HANDLE hReadEvent[2];
CRITICAL_SECTION section; //声明一个临界段,因为读事件的输出屏幕共享,所以要进行同步操作
BOOL run=TRUE;
写线程: hWriteEvent = CreateEvent(NULL,TRUE,FALSE,NULL);//手动事件;无信号
while(run)
{
if(WaitForMultipleObject(2,hReadEvent,TRUE,0)==WAIT_OBJECT_0)//等待两个读事件都有信号
{
写入缓冲区;
PulseEvent(hWriteEvent); //使所有等待该事件的线程运行,当所有线程收到触发信号后,
事件将自动复位为无信号状态,即不等待
}
}
读线程1: hReadEvent[0] = CreateEvent(NULL,FALSE,TRUE,NULL);//自动事件;有信号
while(run)
{
WaitForSingleObject(hWriteEvent,INFINITE); //等待写线程
EnterCriticalSection(§ion);//进入临界区
把缓冲区的内容读出;
LeaveCriticalSection(§ion);//离开临界区
SetEvent(hReadEvent[0]); //将事件置为有信号
}
读线程2: hReadEvent[1] = CreateEvent(NULL,FALSE,TRUE,NULL);//自动事件;有信号
while(run)
{
WaitForSingleObject(hWriteEvent,INFINITE); //等待写线程
EnterCriticalSection(§ion);//进入临界区
把缓冲区的内容读出;
LeaveCriticalSection(§ion);//离开临界区
SetEvent(hReadEvent[1]); //将事件置为有信号
}
控制线程: run=FALSE;//让运行停止
main: InitializeCriticalSection(§ion);
handle1=CreateThread(NULL,0,写线程,NULL,0,&dw1);
handle2=CreateThread(NULL,0,读线程1,NULL,0,&dw2);
handle3=CreateThread(NULL,0,读线程2,NULL,0,&dw3);
Sleep(1000);
handle4=CreateThread(NULL,0,控制线程,NULL,0,&dw4);//一秒钟后开启控制线程让进程停止
CloseHandle(handle1);
CloseHandle(handle2);
CloseHandle(handle3);
CloseHandle(handle4);
三、小结
1、以上都是对无名事件使用的举例,也就是在一个进程内的线程间。
2、事件在等待的时候,都是有信号的,在有信号的情况下,不断的试图得到事件的所有权
3、在 WaitForSingleObject 或 WaitForMultipleObject 得到执行之后,事件就变为无信号,即不在等待中。
4、要使用事件,必须先用等待函数去试图得到事件的所有权,得到事件所有权之后就可以进行操作;当操作完之后,要把事件置为有信号状态,把所有权交出。
5、从例2可以明显看出,事件可以同时为多个线程使用。