Signaling
Event Completion to Other Threads or Processes
Events are used to signal the fact that an event has happened to one or more
threads. It is possible to use
semaphores, mutexes, or condition variables to perform the same task. The
threads waiting for an event to occur will wait on that event object. The
thread that completes the task will set the event into the signaled state and
the waiting threads are then released. Events can be of two types, a manually reset event type, which
requires the event to be reset before other threads will once again wait on it,
or an automatically reset type, which
will reset itself after a single thread has been allowed to pass.
Events are kernel objects, so the call to CreateEvent() will return a handle. The call requires four parameters. The first
parameter is the security attribute that determines whether the handle will be
inherited by child processes. The second parameter is a boolean that, when
true, indicates that the event requires a manual reset or, when false,
indicates that the event will automatically reset after a single thread has
been released. The third parameter indicates whether the event should be
created in a signaled state. The fourth parameter is an optional name for the
event.
Existing events can be opened using a call to OpenEvent(). This call requires three parameters. The first parameter is the access
permissions; if this is zero, default access per-missions are requested. The
second parameter is a boolean that indicates whether the handle should be
inherited by child processes. The third parameter is the name of the event.
Since the event is a kernel object, it should be freed with a call to CloseHandle(). A call to SetEvent() places
the event into the signaled state. This allows threads waiting on the event
using WaitForSingleObject to be
released. If the event requires a manual reset to get out of the signaled
state, then this can be achieved with a call to ResetEvent(), which also takes the handle to the event. If the event object resets
auto-matically, then only a single thread will be released before the event is
reset.
Listing 6.23 shows an example of using an event
object to order two threads. An event object is created by the call to CreateEvent(). This object requires manual reset and is created in the unsignaled
state. Two threads are then created. The first thread exe-cutes the routine thread1() and waits on the event. The second thread executes the routine thread2(), which prints a message and then signals the event object. The signal
allows the first thread to continue execution, and it prints a second message.
Listing 6.23 Using
an Event Object to Enforce Execution Order
#include <windows.h>
#include <process.h>
#include <stdio.h>
HANDLE
hevent;
unsigned int __stdcall thread1(void *param)
{
WaitForSingleObject(hevent,INFINITE);
printf("Thread 1 done\n"); return 0;
}
unsigned int __stdcall thread2(void *param)
{
printf("Thread 2 done\n");
SetEvent(hevent);
return 0;
}
int
_tmain(int argc, _TCHAR* argv[])
{
HANDLE hthread1, hthread2;
hevent=CreateEvent(0,0,0,0);
hthread1=(HANDLE)_beginthreadex(0,0,&thread1,0,0,0);
hthread2=(HANDLE)_beginthreadex(0,0,&thread2,0,0,0);
WaitForSingleObject(hthread1,INFINITE);
WaitForSingleObject(hthread2,INFINITE);
CloseHandle(hthread2);
CloseHandle(hthread1);
CloseHandle(hevent);
getchar();
return 0;
}
Related Topics
Privacy Policy, Terms and Conditions, DMCA Policy and Compliant
Copyright © 2018-2023 BrainKart.com; All Rights Reserved. Developed by Therithal info, Chennai.