• 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)
    ", 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。
  • 相关阅读:
    驯服 Tiger: 并发集合 超越 Map、Collection、List 和 Set
    模块化Java:声明式模块化
    模块化Java:静态模块化
    用 Apache Tika 理解信息内容
    Refactoring: Encapsulate Collection
    新型的几乎万能的数据结构CDO
    CDO数据结构基础(1) 转载
    模块化Java简介(转载infoq)
    模块化Java:动态模块化
    责任链模式(C++)
  • 原文地址:https://www.cnblogs.com/liflying/p/4688406.html
Copyright © 2020-2023  润新知