Using Event Objects
来源:互联网 发布:木婉清代餐粉骗局知乎 编辑:程序博客网 时间:2024/05/03 14:10
Applications use event objects in a number of situations to notify a waiting thread of the occurrence of an event. For example, overlapped I/O operations on files, named pipes, and communications devices use an event object to signal their completion. For more information about the use of event objects in overlapped I/O operations, see Synchronization and Overlapped Input and Output.
In the following example, an application uses event objects to prevent several threads from reading from a shared memory buffer while a master thread is writing to that buffer. First, the master thread uses the CreateEvent function to create a manual-reset event object. The master thread sets the event object to nonsignaled when it is writing to the buffer and then resets the object to signaled when it has finished writing. Then it creates several reader threads and an auto-reset event object for each thread. Each reader thread sets its event object to signaled when it is not reading from the buffer.
#define NUMTHREADS 4 HANDLE hGlobalWriteEvent; void CreateEventsAndThreads(void) { HANDLE hReadEvents[NUMTHREADS], hThread; DWORD i, IDThread; // Create a manual-reset event object. The master thread sets // this to nonsignaled when it writes to the shared buffer. hGlobalWriteEvent = CreateEvent( NULL, // no security attributes TRUE, // manual-reset event TRUE, // initial state is signaled "WriteEvent" // object name ); if (hGlobalWriteEvent == NULL) { // error exit } // Create multiple threads and an auto-reset event object // for each thread. Each thread sets its event object to // signaled when it is not reading from the shared buffer. for(i = 1; i <= NUMTHREADS; i++) { // Create the auto-reset event. hReadEvents[i] = CreateEvent( NULL, // no security attributes FALSE, // auto-reset event TRUE, // initial state is signaled NULL); // object not named if (hReadEvents[i] == NULL) { // Error exit. } hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) ThreadFunction, &hReadEvents[i], // pass event handle 0, &IDThread); if (hThread == NULL) { // Error exit. } }}
Before the master thread writes to the shared buffer, it uses the ResetEvent function to set the state of hGlobalWriteEvent
(an application-defined global variable) to nonsignaled. This blocks the reader threads from starting a read operation. The master then uses the WaitForMultipleObjects function to wait for all reader threads to finish any current read operations. When WaitForMultipleObjects returns, the master thread can safely write to the buffer. After it has finished, it sets hGlobalWriteEvent
and all the reader-thread events to signaled, enabling the reader threads to resume their read operations.
VOID WriteToBuffer(VOID) { DWORD dwWaitResult, i; // Reset hGlobalWriteEvent to nonsignaled, to block readers. if (! ResetEvent(hGlobalWriteEvent) ) { // Error exit. } // Wait for all reading threads to finish reading. dwWaitResult = WaitForMultipleObjects( NUMTHREADS, // number of handles in array hReadEvents, // array of read-event handles TRUE, // wait until all are signaled INFINITE); // indefinite wait switch (dwWaitResult) { // All read-event objects were signaled. case WAIT_OBJECT_0: // Write to the shared buffer. break; // An error occurred. default: printf("Wait error: %d/n", GetLastError()); ExitProcess(0); } // Set hGlobalWriteEvent to signaled. if (! SetEvent(hGlobalWriteEvent) ) { // Error exit. } // Set all read events to signaled. for(i = 1; i <= NUMTHREADS; i++) if (! SetEvent(hReadEvents[i]) ) { // Error exit. } }
Before starting a read operation, each reader thread uses WaitForMultipleObjects to wait for the application-defined global variable hGlobalWriteEvent
and its own read event to be signaled. When WaitForMultipleObjects returns, the reader thread's auto-reset event has been reset to nonsignaled. This blocks the master thread from writing to the buffer until the reader thread uses the SetEvent function to set the event's state back to signaled.
VOID ThreadFunction(LPVOID lpParam) { DWORD dwWaitResult; HANDLE hEvents[2]; hEvents[0] = *(HANDLE*)lpParam; // thread's read event hEvents[1] = hGlobalWriteEvent; dwWaitResult = WaitForMultipleObjects( 2, // number of handles in array hEvents, // array of event handles TRUE, // wait till all are signaled INFINITE); // indefinite wait switch (dwWaitResult) { // Both event objects were signaled. case WAIT_OBJECT_0: // Read from the shared buffer. break; // An error occurred. default: printf("Wait error: %d/n", GetLastError()); ExitThread(0); } // Set the read event to signaled. if (! SetEvent(hEvents[0]) ) { // Error exit. } }
- Using Event Objects
- event objects 小记录
- Using Mutex Objects
- Using Semaphore Objects
- Using Vertex Buffer Objects
- Using Mutex Objects (MSDN2001)
- 2: Making & Using Objects
- Using SQLExec and Record Objects
- Java - Saving Objects Using DBObject
- Using C++ objects in Delphi
- Using proxy as Event
- Using event subclasses
- Win32 Thread API学习之Event Objects
- Win32多线程之事件(Event Objects)
- Using Struts With Java Data Objects
- Pattern matching on Java objects using Tom
- Using and Understanding Java Data Objects
- chap 2 making and using objects
- [转]大量正版软件下载链接
- 关于核对通过的过程
- pl/sql developer工具几点妙用
- 数据库连接字符串大全
- 第三十二期:CSDN论坛秀-MSSQL版-本期作秀:liuri(璇玑)
- Using Event Objects
- Name,Alias,ColDesc的作用
- 收到Windows Live Messenger邀请,纪录下。
- 几个版本的猴子和香蕉的故事
- VC中显示图片1
- Vtable做了一半,保存重起Jboss,Jboss报错
- JavaMail POP3 client
- debug的方法 *****
- c++程序课程设计的内容--职工工资管理系统