Windows内核模式的线程同步之事件(Event)

HANDLE hEvent = CreateEvent(PSECURITE_ATTRIBUTES psa, BOOL bManualReset, BOOL bInitialState, PCSTR pszName);

上面是创建一个事件对象,psa是该内核对象的安全属性, bManualReset是用来告诉系统创建一个手动重置事件(TRUE),还是创建一个自动重置事件(FALSE),bInitialState表示事件的初始化状态为触发状态(TRUE),还是未触发状态(FALSE), pszName表示对象的名字。


在使用事件同步的时候首先应该确定是使用手动重置还是自动重置事件,这两种方式的调用有很大的区别。

手动重置事件的方法:

DWORD WINAPI Thread1(PVOID pvParam)

{

WaitForSingleObject(hEvent, INFINITE);

//共享内存的访问

return 0;

}

DOWRD WINAPI Thread2(PVOID pvParam)

{

WaitForSingleObject(hEvent, INFINITE);

//共享内存的访问

return 0;

}

当hEvent处于未触发状态的时候两个线程都处于等待状态,应为WaitForSingleObject会将线程挂起。直到某个函数中调用SetEvent(hEvent)将hEvent设置为触发状态的,系统会使这个两个线程变为可调度状态,它们会得到cpu时间并会访问内存块。注意,所有的线程只能以读的方式访问共享内存,这是为什么三个线程能同时运行的原因。

自动重置事件的方法:

DOWRD WINAPI Thread1(PVOID pvParam)

{

WaitForSingleObject(hEvent, INFINITE);

//共享内存的访问

SetEvent(hEvent);

return 0;

}

DWORD WINAPI Thread2(PVOID pvParam)

{

WaitForSingleObejct(hEvent, INFINITE);

//共享内存的访问

SetEvent(hEevnt);

return 0;

}

与手动重置一样hEvent初始状态处于未触发状态的时候两个线程都处于挂起状态,当某个函数调用SetEvent(hEvent)将hEvent设置为触发状态的时候,系统只会把这个两个当中的一个线程变成可调度状态,而且我们不能设置也不会知道系统会将哪一个线程设置为可调度状态,所在在每个线程在内存访问完时要调用SetEvent。(其中涉及等待成功引起的副作用。)


这就是手动重置事件和自动重置事件的区别和用法。

你可能感兴趣的:(Windows核心编程之路)