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。
时间: 2024-08-30 10:22:13

SETEVENT的使用的相关文章

CreateEvent、SetEvent、ResetEvent和WaitForSingleObject

事件对象就像一个开关:它只有两种状态---开和关.当一个事件处于"开"状态,我们称其为"有信号",否则称为"无信号".可以在一个线程的执行函数中创建一个事件对象,然后观察它的状态,如果是"无信号"就让该线程睡眠,这样该线程占用的CPU时间就比较少. 产生事件对象的函数如下: (1)CreateEvent 函数原型: HANDLE CreateEvent( LPSECURITY_ATTRIBUTES lpEventAttribu

事件函数SetEvent、PulseEvent与WaitForSingleObject详解

系统核心对象中的Event事件对象,在进程.线程间同步的时候是比较常用,发现它有两个出发函数,一个是SetEvent,还有一个PulseEvent, 两者的区别是: SetEvent为设置事件对象为有信号状态:而PulseEvent也是将指定的事件设为有信号状态, 不同的是如果是一个人工重设事件,正在等候事件的.被挂起的所有线程都会进入活动状态,函数随后将事件设回,并返回:如果是一个 自动重设事件,则正在等候事件的.被挂起的单个线程会进入活动状态,事件随后设回无信号,并且函数返回. 也就是说在自

setevent/waitforsingleobject

线程中CreateEvent和SetEvent及WaitForSingleObject的用法          博客分类: delphi 多线程WindowsSocket网络应用thread 首先介绍CreateEvent是创建windows事件的意思,作用主要用在判断线程退出,程锁定方面. CreateEvent 函功能描述:创建或打开一个命名的或无名的事件对象.EVENT有两种状态:发信号,不发信号. SetEvent/ResetEvent分别将EVENT置为这两种状态分别是发信号与不发信号

CreateEvent和SetEvent及WaitForSingleObject的使用方法

CreateEvent: 1.函数功能: 创建一个命名或匿名的事件对象 2.函数原型: HANDLE CreateEvent( LPSECURITY_ATTRIBUTES lpEventAttributes,  // pointer to security attributes   BOOL bManualReset,    // flag for manual-reset event   BOOL bInitialState,   // flag for initial state   LPC

CreateEvent和SetEvent及WaitForSingleObject的用法

CreateEvent: 1.函数功能: 创建一个命名或匿名的事件对象 2.函数原型: HANDLE CreateEvent( LPSECURITY_ATTRIBUTES lpEventAttributes,  // pointer to security attributes   BOOL bManualReset,    // flag for manual-reset event   BOOL bInitialState,   // flag for initial state   LPC

线程中CreateEvent和SetEvent及WaitForSingleObject的用法

线程中CreateEvent和SetEvent及WaitForSingleObject的用法 首先介绍CreateEvent是创建windows事件的意思,作用主要用在判断线程退出,程锁定方面. CreateEvent 函功能描述:创建或打开一个命名的或无名的事件对象. EVENT有两种状态:发信号,不发信号. SetEvent/ResetEvent分别将EVENT置为这两种状态分别是发信号与不发信号. WaitForSingleObject()等待,直到参数所指定的OBJECT成为发信号状态时

MyEvent.SetEvent; // 同步信号置位

MyEvent.SetEvent;   //  同步信号置位 TSimpleEvent.Create = TEvent.Create(nil, True, False, nil) = CreateEvent(nil, True, False, nil); 其中第三个参数表示同步信号初始化时状态 True表示置位Signaled,即SetEvent False表示复位nonSignaled,即ResetEvent WaitFor(Timeout) = (wrSignaled, wrTimeout,

03EventDemo

1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<process.h> 4 #include<windows.h> 5 6 HANDLE g_hEvent; 7 UINT __stdcall ThreadProc(LPVOID); 8 int main(int argc,char* argv[]) 9 { 10 unsigned uThreadId; 11 char szEventName[] = &qu

一种利用ADO连接池操作MySQL的解决方案(VC++)

VC++连接MySQL数据库 常用的方式有三种:ADO.mysql++,mysql API ; 本文只讲述ADO的连接方式. 为什么要使用连接池? 对于简单的数据库应用,完全可以先创建一个常连接(此连接永远不关闭,直接数进程退出),但是这样做至少会引起两个问题:(1)资源竞争,多个数据库请求操作不能同时进行,后一请求必须要等到前一请求完成后才能进行:(2)多线程情况下容易出现混乱,甚至出现资源异常释放.还有一种方法,就是使用数据库时创建连接,使用完后关闭连接回收资源.这种方式在数据库操作频繁的情