有两种事件内核对象:自动事件和手动事件。当手动事件被触发时,所以该事件的等待线程都编程可调度状态;而自动事件被触发时,只有个一个等待该事件线程变成可调度状态。
下面再逐个讲解Event的相关函数:
a)创建事件函数——CreateEvent函数:
HANDLE CreateEvent(
PSECURITY_ATTRIBUTESpsa,
BOOLbManualReset,
BOOLbInitialState,
PCTSTRpszName);
具体的函数参数及用法,请查看上面的超链接。
b)第二创建事件的函数——CreateEventEx函数:
HANDLE CreateEventEx(
PSECURITY_ATTRIBUTESpsa,
PCTSTRpszName,
DWORDdwFlags,
DWORDdwDesiredAccess);
c)访问某个打开的事件(Event)——OpenEvent函数:
HANDLE OpenEvent(
DWORDdwDesiredAccess,
BOOLbInherit,
PCTSTRpszName)
在pszName传递创建事件时函数的pszName参数值。
d)使得某个事件处于触发状态——SetEvent函数:
BOOL SetEvent(HANDLE hEvent);
e)将某个事件设置为非触发状态——ResetEvent函数:
BOOL ResetEvent(HANDLE hEvent);
f)特别的函数——PluseEvent函数:
BOOL PulseEvent(HANDLE hEvent);
其作用相当于在调用SetEvent函数后立即调用ResetEvent函数,功能就是一次启用一个线程。因为手动方式的事件时,当事件触发时,所有的该事件阻塞的线程都会转为可调度状态。如果你调用PluseEvent函数后,在系统调用某一个线程后,由于立马将事件设置为非触发状态,这是其他线程也就再次被阻塞了。解释起来好像比较麻烦,不过该函数在实际使用过程中也少有用到。
看一个创建事件时设置手动方式的事件(manual-reset events)示例:
// Create a global handle to a manual-reset, nonsignaled event.
HANDLE g_hEvent;
int WINAPI _tWinMain(...) {
// Create the manual-reset, nonsignaled event.
g_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
// Spawn 3 new threads.
HANDLE hThread[3];
DWORD dwThreadID;
hThread[0] = _beginthreadex(NULL, 0, WordCount, NULL, 0, &dwThreadID);
hThread[1] = _beginthreadex(NULL, 0, SpellCheck, NULL, 0, &dwThreadID);
hThread[2] = _beginthreadex(NULL, 0, GrammarCheck, NULL, 0, &dwThreadID);
OpenFileAndReadContentsIntoMemory(...);
// Allow all 3 threads to access the memory.
SetEvent(g_hEvent);
...
}
DWORD WINAPI WordCount(PVOID pvParam) {
// Wait until the file's data is in memory.
WaitForSingleObject(g_hEvent, INFINITE);
// Access the memory block.
...
return(0);
}
DWORD WINAPI SpellCheck (PVOID pvParam) {
// Wait until the file's data is in memory.
WaitForSingleObject(g_hEvent, INFINITE);
// Access the memory block.
...
return(0);
}
DWORD WINAPI GrammarCheck (PVOID pvParam) {
// Wait until the file's data is in memory.
WaitForSingleObject(g_hEvent, INFINITE);
// Access the memory block.
...
return(0);
}
创建事件时设置为自动方式时的事件(auto-reset event)示例:
// Create a global handle to a auto-reset, nonsignaled event.
HANDLE g_hEvent;
int WINAPI _tWinMain(...) {
// Create the auto-reset, nonsignaled event.
g_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
// Spawn 3 new threads.
HANDLE hThread[3];
DWORD dwThreadID;
hThread[0] = _beginthreadex(NULL, 0, WordCount, NULL, 0, &dwThreadID);
hThread[1] = _beginthreadex(NULL, 0, SpellCheck, NULL, 0, &dwThreadID);
hThread[2] = _beginthreadex(NULL, 0, GrammarCheck, NULL, 0, &dwThreadID);
OpenFileAndReadContentsIntoMemory(...);
// Allow all 3 threads to access the memory.
SetEvent(g_hEvent);
...
}
DWORD WINAPI WordCount(PVOID pvParam) {
// Wait until the file's data is in memory.
WaitForSingleObject(g_hEvent, INFINITE);
// Access the memory block.
...
SetEvent(g_hEvent);
return(0);
}
DWORD WINAPI SpellCheck (PVOID pvParam) {
// Wait until the file's data is in memory.
WaitForSingleObject(g_hEvent, INFINITE);
// Access the memory block.
...
SetEvent(g_hEvent);
return(0);
}
DWORD WINAPI GrammarCheck (PVOID pvParam) {
// Wait until the file's data is in memory.
WaitForSingleObject(g_hEvent, INFINITE);
// Access the memory block.
...
SetEvent(g_hEvent);
return(0);
}
分析:
对比上面的代码示例,细心的话你会发现:在自动方式下的代码中,每个线程在返回前都会调用SetEvent函数将事件设置为触发状态;而手动方式事件对应的函数中没有调用这个函数。
这是因为在自动方式下,事件每次转化为触发状态时只能使一个线程变成可调度状态,为了让其他线程也能被执行,所以在每个线程返回前再次将事件设置为触发状态,使得其他等待该事件的线程转为可调度状态从而被执行。
而手动方式下,则不同,当手动方式事件被SetEvent函数触发一次,它就一直保持触发态,直到再次调用ReSetEvent函数将它设为非触发态。
分享到:
相关推荐
Chapter3-《Ext JS高级程序设计》源代码.rar Chapter4-《Ext JS高级程序设计》源代码.rar Chapter5《Ext JS高级程序设计》源代码.rar Chapter6-《Ext JS高级程序设计》源代码.rar Chapter7-《Ext JS高级程序设计》源...
操作系统概念英文课件:Chapter 09-virtual memory.pptx
Chapter3-《Ext JS高级程序设计》源代码.rar Chapter4-《Ext JS高级程序设计》源代码.rar Chapter5《Ext JS高级程序设计》源代码.rar Chapter6-《Ext JS高级程序设计》源代码.rar Chapter7-《Ext JS高级程序设计》源...
Chapter3-《Ext JS高级程序设计》源代码.rar Chapter4-《Ext JS高级程序设计》源代码.rar Chapter5《Ext JS高级程序设计》源代码.rar Chapter6-《Ext JS高级程序设计》源代码.rar Chapter7-《Ext JS高级程序设计》源...
Chapter3-《Ext JS高级程序设计》源代码.rar Chapter4-《Ext JS高级程序设计》源代码.rar Chapter5《Ext JS高级程序设计》源代码.rar Chapter6-《Ext JS高级程序设计》源代码.rar Chapter7-《Ext JS高级程序设计》源...
Chapter3-《Ext JS高级程序设计》源代码.rar Chapter4-《Ext JS高级程序设计》源代码.rar Chapter5《Ext JS高级程序设计》源代码.rar Chapter6-《Ext JS高级程序设计》源代码.rar Chapter7-《Ext JS高级程序设计》源...
Chapter3-《Ext JS高级程序设计》源代码.rar Chapter4-《Ext JS高级程序设计》源代码.rar Chapter5《Ext JS高级程序设计》源代码.rar Chapter6-《Ext JS高级程序设计》源代码.rar Chapter7-《Ext JS高级程序设计》源...
Chapter3-《Ext JS高级程序设计》源代码.rar Chapter4-《Ext JS高级程序设计》源代码.rar Chapter5《Ext JS高级程序设计》源代码.rar Chapter6-《Ext JS高级程序设计》源代码.rar Chapter7-《Ext JS高级程序设计》源...
Chapter3-《Ext JS高级程序设计》源代码.rar Chapter4-《Ext JS高级程序设计》源代码.rar Chapter5《Ext JS高级程序设计》源代码.rar Chapter6-《Ext JS高级程序设计》源代码.rar Chapter7-《Ext JS高级程序设计》源...
CISSP ALL IN ONE 5TH EDITON - Part 3/3 ( Chapter09 - 12)
ProWPFinVB-src-Chapter02-15 ProWPFinVB-src-Chapter02-15 ProWPFinVB-src-Chapter02-15
ProWPFinVB-src-Chapter15-28ProWPFinVB-src-Chapter15-28ProWPFinVB-src-Chapter15-28
电力系统自动化chapter2-2同步发电机励磁系统.pptx
chapter14-cross coupling-bc [兼容模式].pdf
嵌入式系统软件基础描述及各类嵌入式软件分析方法。嵌入式系统及应用-Chapter3-嵌入式软件系统基础
chapter9--network--server.ipynb
计算机网络第6版课件:Chapter 4-4 routing and IP routing.ppt
c讲稿Chapter2-类和对象.pptx
NULL 博文链接:https://hnzhoujunmei.iteye.com/blog/759473
《Android开发案例驱动教程》全面介绍了在开源的手机平台Android操作系统下的应用程序开发技术,包括UI、多线程、数据存储、多媒体、云端应用以及通信应用等方面。 《Android开发案例驱动教程》采用案例驱动模式展开...