使用Windows API函数CreateEvent()来创建一个事件对象。事件对象是一种同步原语,用于线程间的通信,允许一个线程通知另一个线程某个特定条件已经满足或特定事件已经发生。
函数原型:
Cpp
HANDLE CreateEvent(
LPSECURITY_ATTRIBUTES lpEventAttributes,
BOOL bManualReset,
BOOL bInitialState,
LPCTSTR lpName
);
说明:
lpEventAttributes: 指向SECURITY_ATTRIBUTES结构的指针,用于指定事件对象的安全属性,如是否允许子进程继承此事件句柄。如果不需要这些特性,通常设置为NULL。
bManualReset: 布尔值,指示事件是否为手动重置类型。如果为TRUE,当事件被触发后,即使有多个等待线程被唤醒,事件状态将保持“有信号”状态,直到显式调用ResetEvent()函数将其重置为“无信号”。如果为FALSE,事件为自动重置类型,一旦有一个等待线程被唤醒,事件会自动变为“无信号”,其他等待线程将继续阻塞。
bInitialState: 布尔值,指定事件的初始状态。如果为TRUE,事件创建后即处于“有信号”状态;若为FALSE,则初始为“无信号”状态。
lpName: 事件对象的名称(以空结束的字符串)。如果为非NULL,则创建一个命名事件,可以在同一台计算机上的不同进程中共享。如果为NULL,创建的是一个本地事件,只能在同一进程中访问。
示例:
Cpp
#include <windows.h>
int main()
{
// 创建一个手动重置、初始状态为有信号的本地事件,不使用命名且不指定安全属性
HANDLE hEvent = CreateEvent(nullptr, TRUE, TRUE, nullptr);
if (hEvent == NULL)
{
// 处理错误:CreateEvent失败
DWORD error = GetLastError();
printf("CreateEvent failed with error code %lu\n", error);
return -1;
}
// 在这里,你可以使用hEvent作为同步机制的一部分,
// 例如在一个线程中触发事件(SetEvent(hEvent)),在另一个线程中等待事件(WaitForSingleObject(hEvent, INFINITE))
// 使用完毕后,记得关闭事件句柄
CloseHandle(hEvent);
return 0;
}
创建了一个手动重置事件,一旦它被触发,所有等待的线程都会被唤醒,并且事件状态保持为“有信号”,直到程序明确调用ResetEvent(hEvent)来将其重置为“无信号”。事件初始状态被设置为“有信号”,创建后即可立即被等待的线程感知到。
实际使用时,需要根据具体需求调整bManualReset和bInitialState的值,并确保在不再需要事件对象时正确关闭其句柄,以避免资源泄漏。在多线程环境中,事件通常与WaitForSingleObject()、WaitForMultipleObjects()等函数结合使用,以实现线程间的同步与通信。