事件内核对象是在线程同步时比较常用的内核对象。
一个事件内核对象的触发表示一个操作已经完成。有两种类型的事件内核对象:手动重置事件和自动重置事件。
当一个手动重置对象被触发的时候,正在等待该事件的所有线程都将变成可调度状态。而当一个自动重置事件被触发时,只有一个正在等待该事件的线程会变成可调度状态。
事件内核对象最通常的用途是:让一个线程执行初始化工作,然后触发另一个线程,让他执行剩余的工作,一开始的时候我们将时间初始化为未触发状态,然后当线程完成初始化工作的时候触发事件。此时,另一个线程一直在等待该事件,它发现事件被触发,于是变成可调度状态,第二个线程知道第一个线程已经完成了他的工作。
HANDLE CreateEvent(
LPSECURITY_ATTRIBUTES lpEventAttributes,// 安全属性
BOOLb ManualReset,// 复位方式
BOOLb InitialState,// 初始状态
LPCTSTR lpName // 对象名称
);
参数bManualReset是一个布尔值,用来告诉系统应该创建一个手动重置时间(TRUE)还是一个自动重置时间(FALSE)。
参数bInitialState表示应该事件初始化为触发状态(TRUE)还是未触发状态(FALSE)。
当系统插件事件对象之后,返回一个事件内核对象。
还有一个是CreateEvent的增强版CreateEventEx。
其他进程中的线程可以通过多种方式来访问该事件对象,这包括调用CreateEvent并在pszName参数中传入相同的值,使用继承,使用DuplicateHandle函数或者调用OpenEvent并在pszName参数指定与CreateEvent中相同的名字:
HANDLE OpenEvent(
DWORD dwDesiredAccess,
BOOL bInherit,
PCTSTR pszName
);
一旦我们不需要事件内核对象的时候调用closehandlel来关闭。通过调用SetEvent可以直接控制它的状态,变成触发状态,使用ResetEvent使得事件变成未触发状态。
BOOL SetEvent(HANDLE hEvent);
BOOL ResetEvent(HANDLE hEvent);
简单的例子
HANDLE g_hEvent;
int main()
{
g_hEvent=CreateEvent(NULL,true,false,NULL);
HANDLE hThread=CreateThread
NULL,0,Thread1,NULL,0,NULL);
//打开文件并读取内存。
SetEvent(g_hEvent);//通知Thread1开始运行。
//其他操纵。
}
DWORD WINAPI Thread1(PVOID param)
{
WatiForSingleObject(g_hEvent,INFINITE);
//访问内存。
ResetEvent(g_hEvent);
}