1、简介
HANDLECreateEvent(
LPSECURITY_ATTRIBUTESlpEventAttributes,// 安全属性
BOOLbManualReset,// 复位方式
BOOLbInitialState,// 初始状态
LPCTSTRlpName // 对象名称
);
我们常用比较关心的其实是第2、3个参数,另外两个直接设置为NULL即可,下面分别主要介绍第2、3个参数:
1、bManualReset:TRUE,使用ResetEvent()手动重置为无信号状态;FALSE,当一个等待线程被释放时,自动重置状态为无信号状态。
2、bInitialState:指定事件对象的初始状态,当TRUE,初始状态为有信号状态;当FALSE,初始状态为无信号状态。
2、代码实例进行讲解
2.1 第一种情况
//使用手动重置为无信号状态,初始化时有信号状态
g_hEvent = CreateEvent(NULL, TRUE, TRUE, NULL);
源代码:
#include <process.h>
#include <Windows.h>
#include <iostream>
HANDLE g_hEvent = NULL;
HANDLE g_hThread1 = NULL;
HANDLE g_hThread2 = NULL;
unsigned _stdcall ThreadProc1(void* lpParam)
{
std::cout << "ThreadProc1 come in!" << std::endl;
DWORD rel = WaitForSingleObject(g_hEvent, INFINITE);
if (WAIT_OBJECT_0 == rel)
{
std::cout << "ThreadProc1 get event signal!" << std::endl;
}
std::cout << "ThreadProc1 will out!" << std::endl;
return 0;
}
unsigned _stdcall ThreadProc2(void* lpParam)
{
std::cout << "ThreadProc2 come in!" << std::endl;
DWORD rel = WaitForSingleObject(g_hEvent, INFINITE);
if (WAIT_OBJECT_0 == rel)
{
std::cout << "ThreadProc2 get event signal!" << std::endl;
}
std::cout << "ThreadProc2 will out!" << std::endl;
return 0;
}
int main(int argc, char* argv[])
{
//使用手动重置为无信号状态,初始化时有信号状态
g_hEvent = CreateEvent(NULL, TRUE, TRUE, NULL);
g_hThread1 = (HANDLE)_beginthreadex(NULL, 0, ThreadProc1, NULL, 0, NULL);
Sleep(100);
g_hThread2 = (HANDLE)_beginthreadex(NULL, 0, ThreadProc2, NULL, 0, NULL);
if (!g_hThread1 || !g_hThread2)
{
std::cout << "Create Thread Failed!" << std::endl;
}
Sleep(5000); //保证上面两个线程都执行完毕。
return 0;
}
执行结果:
从结果中可以看出,执行完线程1又执行了线程2:
由于g_hEvent = CreateEvent(NULL, TRUE, TRUE, NULL);//使用手动重置为无信号状态,初始化时有信号状态,
所以g_hEvent一直是处于有信号的状态,即线程1释放以后,g_hEvent还是处于有信号状态,所以线程2正常执
行了。要想使g_hEvent没有信号,我们必须手动使用代码ResetEvent(g_hEvent)才可以将其设置为无信号。
2.2 第二种情况
//<span class="comment" style="margin: 0px; padding: 0px; border: none; color: rgb(0, 130, 0); font-family: Consolas, 'Courier New', Courier, mono, serif; line-height: 18px;">当一个等待线程被释放时,自动重置为无信号状态,初始是有信号状态</span><span style="margin: 0px; padding: 0px; border: none; font-family: Consolas, 'Courier New', Courier, mono, serif; line-height: 18px;"> </span>
g_hEvent = CreateEvent(NULL, FALE, TRUE, NULL);
源代码:
#include <process.h>
#include <Windows.h>
#include <iostream>
HANDLE g_hEvent = NULL;
HANDLE g_hThread1 = NULL;
HANDLE g_hThread2 = NULL;
unsigned _stdcall ThreadProc1(void* lpParam)
{
std::cout << "ThreadProc1 come in!" << std::endl;
DWORD rel = WaitForSingleObject(g_hEvent, INFINITE);
if (WAIT_OBJECT_0 == rel)
{
std::cout << "ThreadProc1 get event signal!" << std::endl;
}
std::cout << "ThreadProc1 will out!" << std::endl;
return 0;
}
unsigned _stdcall ThreadProc2(void* lpParam)
{
std::cout << "ThreadProc2 come in!" << std::endl;
DWORD rel = WaitForSingleObject(g_hEvent, INFINITE);
if (WAIT_OBJECT_0 == rel)
{
std::cout << "ThreadProc2 get event signal!" << std::endl;
}
std::cout << "ThreadProc2 will out!" << std::endl;
return 0;
}
int main(int argc, char* argv[])
{
//当一个等待线程被释放时,自动重置为无信号状态,初始是有信号状态
g_hEvent = CreateEvent(NULL, FALSE, TRUE, NULL);
g_hThread1 = (HANDLE)_beginthreadex(NULL, 0, ThreadProc1, NULL, 0, NULL);
Sleep(100);
g_hThread2 = (HANDLE)_beginthreadex(NULL, 0, ThreadProc2, NULL, 0, NULL);
if (!g_hThread1 || !g_hThread2)
{
std::cout << "Create Thread Failed!" << std::endl;
}
Sleep(5000); //保证上面两个线程都执行完毕。
return 0;
}
从结果中可以看出,执行完线程1又执行了线程2,线程2没有获得信号执行完:
由于g_hEvent = CreateEvent(NULL, FALE, TRUE, NULL);//当一个等待线程被释放时,自动重置为无信号状态,
初始是有信号状态 ,所以执行线程1的时候g_hEvent是有信号的,当线程1获取信号,线程释放以后,会制动将
g_hEvent设置为无信号状态,所以线程2一直在WaitForSingleObject(hEvent,INFINITE);处无法获取信号,
阻塞不能正常执行完。
2.3 第三种情况
//使用手动重置为无信号状态,初始化时为无信号状态
g_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
源代码:
#include <process.h>
#include <Windows.h>
#include <iostream>
HANDLE g_hEvent = NULL;
HANDLE g_hThread1 = NULL;
HANDLE g_hThread2 = NULL;
unsigned _stdcall ThreadProc1(void* lpParam)
{
std::cout << "ThreadProc1 come in!" << std::endl;
DWORD rel = WaitForSingleObject(g_hEvent, INFINITE);
if (WAIT_OBJECT_0 == rel)
{
std::cout << "ThreadProc1 get event signal!" << std::endl;
}
std::cout << "ThreadProc1 will out!" << std::endl;
return 0;
}
unsigned _stdcall ThreadProc2(void* lpParam)
{
std::cout << "ThreadProc2 come in!" << std::endl;
DWORD rel = WaitForSingleObject(g_hEvent, INFINITE);
if (WAIT_OBJECT_0 == rel)
{
std::cout << "ThreadProc2 get event signal!" << std::endl;
}
std::cout << "ThreadProc2 will out!" << std::endl;
return 0;
}
int main(int argc, char* argv[])
{
//使用手动重置为无信号状态,初始化时为无信号状态
g_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
g_hThread1 = (HANDLE)_beginthreadex(NULL, 0, ThreadProc1, NULL, 0, NULL);
Sleep(100);
g_hThread2 = (HANDLE)_beginthreadex(NULL, 0, ThreadProc2, NULL, 0, NULL);
if (!g_hThread1 || !g_hThread2)
{
std::cout << "Create Thread Failed!" << std::endl;
}
Sleep(10000); //保证上面两个线程都执行完毕。
return 0;
}
执行结果可想而知,两个线程都处于等待状态,如下:
因为初始为无信号状态,所以hEvent一直处于无信号状态,因此这两个线程一直在等待,直到主线程结束。
这种情况使用我们可以使用SetEvent(g_hEvnet)将其设置为有信号的状态,线程就可以正常执行了。
2.4 第四种情况
//线程释放后自动重置为无信号状态,初始化时为无信号状态
g_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
源代码:
#include <process.h>
#include <Windows.h>
#include <iostream>
HANDLE g_hEvent = NULL;
HANDLE g_hThread1 = NULL;
HANDLE g_hThread2 = NULL;
unsigned _stdcall ThreadProc1(void* lpParam)
{
std::cout << "ThreadProc1 come in!" << std::endl;
DWORD rel = WaitForSingleObject(g_hEvent, INFINITE);
if (WAIT_OBJECT_0 == rel)
{
std::cout << "ThreadProc1 get event signal!" << std::endl;
}
std::cout << "ThreadProc1 will out!" << std::endl;
return 0;
}
unsigned _stdcall ThreadProc2(void* lpParam)
{
std::cout << "ThreadProc2 come in!" << std::endl;
DWORD rel = WaitForSingleObject(g_hEvent, INFINITE);
if (WAIT_OBJECT_0 == rel)
{
std::cout << "ThreadProc2 get event signal!" << std::endl;
}
std::cout << "ThreadProc2 will out!" << std::endl;
return 0;
}
int main(int argc, char* argv[])
{
//线程释放后自动重置为无信号状态,初始化时为无信号状态
g_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (SetEvent(g_hEvent))
{
std::cout << "SetEvent Success!" << std::endl;
}
g_hThread1 = (HANDLE)_beginthreadex(NULL, 0, ThreadProc1, NULL, 0, NULL);
Sleep(100);
g_hThread2 = (HANDLE)_beginthreadex(NULL, 0, ThreadProc2, NULL, 0, NULL);
if (!g_hThread1 || !g_hThread2)
{
std::cout << "Create Thread Failed!" << std::endl;
}
Sleep(10000); //保证上面两个线程都执行完毕。
return 0;
}
执行结果,如下:
由于调用SetEvent将g_hEvent置为有信号状态,线程1正常执行,又由于调用完线程1后,g_hEvent自动重置
为无信号状态,所以线程2只能处于等待,直到主线程退出。
修改:
线程1中的SetEvent(hEvent);的注释去掉,再运行,则线程1和线程2 都不会执行,以为初始为无信号状态。