19-线程同步:事件对象

线程同步:事件对象

事件

事件对象也属于内核对象,它包含以下三个成员:

● 使用计数;

● 用于指明该事件是一个自动重置的事件还是一个人工重置的事件的布尔值;

● 用于指明该事件处于已通知状态还是未通知状态的布尔值。

1.创建事件CreateEvent函数

将一个句柄变为一个事件的标志,设置该事件的初始信号。

参数:

HANDLE CreateEvent(
LPSECURITY_ATTRIBUTES lpEventAttributes, // 安全属性
BOOL bManualReset, // 复位方式 TRUE 必须用 ResetEvent 手动复原 FALSE自动还原为无信号状态
BOOL bInitialState, // 初始状态 TRUE 初始状态为有信号状态 FALSE无信号状态
LPCTSTR lpName //对象名称 NULL 无名的事件对象
);

使用:

hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
//NUll 默认的安全符 手动 FALSE 初始状态为无信号状态

2.设置事件信号为有信号SetEvent函数

传入一个事件句柄,将该事件设置为有信号(可用)。

参数:事件句柄

3.设置事件信号为无信号ResetEvent函数

传入一个事件句柄,将该事件设置为无信号(不可用)。

参数:事件句柄

4.请求事件对象函数WaitForSingleObject

线程通过调用 WaitForSingleObject 函数请求事件对象,阻塞等待事件,直到有信号。

案例

#include<stdio.h>
#include<Windows.h>
#include<process.h>

char str[100];
HANDLE hEvent;

unsigned WINAPI NumberOfAs(void* arg)
{
int i, cnt = 0;
WaitForSingleObject(hEvent, INFINITE);
for (int i = 0; str[i] != 0; i++)
{
if (str[i] == 'A')
{
cnt++;
}
}
printf("NumberOfAs %d", cnt);
return 0;

}

unsigned WINAPI NumberOfOthers(void* arg)
{
int i, cnt = 0;
for (int i = 0; str[i] != 0; i++)
{
if (str[i] != 'A')
{
cnt++;
}
}
printf("NumberOfOthers %d", cnt);
SetEvent(hEvent);
return 0;
}

int main()
{
HANDLE hThread1, hThread2;
fputs("Input string:\n",stdout);
fgets(str, 100, stdin);
hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

hThread1 = (HANDLE)_beginthreadex(NULL, 0, NumberOfAs, NULL, 0, NULL);
hThread2 = (HANDLE)_beginthreadex(NULL, 0, NumberOfOthers, NULL, 0, NULL);

WaitForSingleObject(hThread1, INFINITE);
WaitForSingleObject(hThread2, INFINITE);

CloseHandle(hEvent);
system("pause");

return 0;
}