来源:https://msdn.microsoft.com/en-us/library/windows/desktop/ms686915(v=vs.85).aspx
昨天看到这个SetEvent的方法,感觉很新鲜。今天记录一下
The following example 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 whose initial state is nonsignaled. Then it creates several reader threads. The master thread performs a write operation and then sets the event object to the signaled state when it has finished writing.
Before starting a read operation, each reader thread uses WaitForSingleObject to wait for the manual-reset event object to be signaled. When WaitForSingleObject returns, this indicates that the main thread is ready for it to begin its read operation.
1 #include <windows.h> 2 #include <stdio.h> 3 4 #define THREADCOUNT 4 5 6 HANDLE ghWriteEvent; 7 HANDLE ghThreads[THREADCOUNT]; 8 9 DWORD WINAPI ThreadProc(LPVOID); 10 11 void CreateEventsAndThreads(void) 12 { 13 int i; 14 DWORD dwThreadID; 15 16 // Create a manual-reset event object. The write thread sets this 17 // object to the signaled state when it finishes writing to a 18 // shared buffer. 19 20 ghWriteEvent = CreateEvent( 21 NULL, // default security attributes 22 TRUE, // manual-reset event 23 FALSE, // initial state is nonsignaled 24 TEXT("WriteEvent") // object name 25 ); 26 27 if (ghWriteEvent == NULL) 28 { 29 printf("CreateEvent failed (%d) ", GetLastError()); 30 return; 31 } 32 33 // Create multiple threads to read from the buffer. 34 35 for(i = 0; i < THREADCOUNT; i++) 36 { 37 // TODO: More complex scenarios may require use of a parameter 38 // to the thread procedure, such as an event per thread to 39 // be used for synchronization. 40 ghThreads[i] = CreateThread( 41 NULL, // default security 42 0, // default stack size 43 ThreadProc, // name of the thread function 44 NULL, // no thread parameters 45 0, // default startup flags 46 &dwThreadID); 47 48 if (ghThreads[i] == NULL) 49 { 50 printf("CreateThread failed (%d) ", GetLastError()); 51 return; 52 } 53 } 54 } 55 56 void WriteToBuffer(VOID) 57 { 58 // TODO: Write to the shared buffer. 59 60 printf("Main thread writing to the shared buffer... "); 61 62 // Set ghWriteEvent to signaled 63 64 if (! SetEvent(ghWriteEvent) ) 65 { 66 printf("SetEvent failed (%d) ", GetLastError()); 67 return; 68 } 69 } 70 71 void CloseEvents() 72 { 73 // Close all event handles (currently, only one global handle). 74 75 CloseHandle(ghWriteEvent); 76 } 77 78 int main( void ) 79 { 80 DWORD dwWaitResult; 81 82 // TODO: Create the shared buffer 83 84 // Create events and THREADCOUNT threads to read from the buffer 85 86 CreateEventsAndThreads(); 87 88 // At this point, the reader threads have started and are most 89 // likely waiting for the global event to be signaled. However, 90 // it is safe to write to the buffer because the event is a 91 // manual-reset event. 92 93 WriteToBuffer(); 94 95 printf("Main thread waiting for threads to exit... "); 96 97 // The handle for each thread is signaled when the thread is 98 // terminated. 99 dwWaitResult = WaitForMultipleObjects( 100 THREADCOUNT, // number of handles in array 101 ghThreads, // array of thread handles 102 TRUE, // wait until all are signaled 103 INFINITE); 104 105 switch (dwWaitResult) 106 { 107 // All thread objects were signaled 108 case WAIT_OBJECT_0: 109 printf("All threads ended, cleaning up for application exit... "); 110 break; 111 112 // An error occurred 113 default: 114 printf("WaitForMultipleObjects failed (%d) ", GetLastError()); 115 return 1; 116 } 117 118 // Close the events to clean up 119 120 CloseEvents(); 121 122 return 0; 123 } 124 125 DWORD WINAPI ThreadProc(LPVOID lpParam) 126 { 127 // lpParam not used in this example. 128 UNREFERENCED_PARAMETER(lpParam); 129 130 DWORD dwWaitResult; 131 132 printf("Thread %d waiting for write event... ", GetCurrentThreadId()); 133 134 dwWaitResult = WaitForSingleObject( 135 ghWriteEvent, // event handle 136 INFINITE); // indefinite wait 137 138 switch (dwWaitResult) 139 { 140 // Event object was signaled 141 case WAIT_OBJECT_0: 142 // 143 // TODO: Read from the shared buffer 144 // 145 printf("Thread %d reading from buffer ", 146 GetCurrentThreadId()); 147 break; 148 149 // An error occurred 150 default: 151 printf("Wait error (%d) ", GetLastError()); 152 return 0; 153 } 154 155 // Now that we are done reading the buffer, we could use another 156 // event to signal that this thread is no longer reading. This 157 // example simply uses the thread handle for synchronization (the 158 // handle is signaled when the thread terminates.) 159 160 printf("Thread %d exiting ", GetCurrentThreadId()); 161 return 1; 162 }
CreateEvent,SetEvent,ResetEvent这三个方法主要是用于线程同步,和通信。
是否需要使用ResetEvent是根据CreateEvent的第二个参数而定的
TRUE, // manual-reset event。