SETEVENT的使用

来源: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)\n", 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)\n", 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...\n");
 61 
 62     // Set ghWriteEvent to signaled
 63 
 64     if (! SetEvent(ghWriteEvent) ) 
 65     {
 66         printf("SetEvent failed (%d)\n", 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...\n");
 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...\n");
110             break;
111 
112         // An error occurred
113         default: 
114             printf("WaitForMultipleObjects failed (%d)\n", 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...\n", 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\n", 
146                    GetCurrentThreadId());
147             break; 
148 
149         // An error occurred
150         default: 
151             printf("Wait error (%d)\n", 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\n", GetCurrentThreadId());
161     return 1;
162 }

CreateEvent,SetEvent,ResetEvent这三个方法主要是用于线程同步,和通信。

是否需要使用ResetEvent是根据CreateEvent的第二个参数而定的

 TRUE,               // manual-reset event。

posted on 2015-07-30 10:18  liflying  阅读(1941)  评论(0编辑  收藏  举报

导航