Thread Synchronization using events

d_arin100's Avatar author of Thread Synchronization using events
This is an article on Thread Synchronization using events in MFC.

Introduction



Event is one type of kernel object that Windows provides for thread synchronization. Here I shall describe the Win32 event as well as MFC event. MFC's CEvent class encapsulates Win32 event objects. Generally events are used in cases when one thread is supposed to start its job after a specified job has over. For example, a thread might wait until the necessary data is read and then start writes in the hard disk.

Background



There are two kinds of events (i) manual reset and another is (ii) auto reset. By using an event we simply can notify another thread that a specified action has occurred. An event can be either in the signaled (or true) state or in the nonsignaled (or false) state. A manual reset eventobject stays in the state unless and until the [inlincecode]SetEvent()[/inlinecode] or [inlinecode]ResetEvent()[/inlinecod] function is called. But in auto reset eventobject automatically returns to a nonsignaled (unavailable) state after at least one thread is released.

Win32 Event Object:



The CreateEvent() function is used to create an event thread synchronization object. The manual or auto reset event can be mentioned at the CreateEvent() function parameter. The WaitForSingleObject()or WaitForMultipleObjects() are use for waiting thread for a particular event occurs. The CreateEvent() function is used to create named and unnamed event objects and also we can specify the initial state of the event object. Now if the named event is already available, then the OpenEvent() function is used to access the event previously created by the CreateEvent() function. The SetEvent() function is used to set the event object to signal state and the ResetEvent() function is used to set the event object to non-signaled state.

Code: Cpp
HANDLE g_Event;
/// Creating a manual reset event
g_Event = CreateEvent(NULL, TRUE, TRUE, "MyEvent")
ResetEvent(g_Event);
/// If reading complete
SetEvent(g_Event);

MFC Event Object::



MFC's CEvent class encapsulates Win32 event objects. The CEvent class is derived from the abstract CSyncObject Class. The CSyncObject is derived from the CObject. The CEvent constructor specifies the manual or auto reset event options.
Code: Cpp
CEvent (BOOL bInitiallyOwn = FALSE,
    BOOL bManualReset = FALSE, LPCTSTR lpszName = NULL,
    LPSECURITY_ATTRIBUTES lpsaAttribute = NULL)
The Manual event object signaled/non-signaled uses SetEvent() or ResetEvent() member function.

Now the question is when we choose auto reset or manual reset events:

i) We use auto reset event when only one thread will be triggered by the event and release the waiting thread with SetEvent(). There's no need to call ResetEvent() because the event is reset automatically when the thread is released.
ii) We use manual reset event when two or more threads will be triggered by the event.

It is important to use PulseEvent() to pull the trigger on a manual reset event. Now if we use PulseEvent() then also no need to call ResetEvent() because PulseEvent() resets the event after releasing the threads. If we use SetEvent() and ResetEvent(), then there is no guarantee that all waiting threads will be released. But PulseEvent() sets and resets the event as well as ensures that all the waiting threads on the event are released before resetting the event.

Code: Cpp
// CEvent auto reset object initially nonsignaled
CEvent g_event; 
/// First thread release for second thread
g_event.SetEvent ();   
/// Second thread wait for a signal
g_event.Lock ();
In the above code second thread calls Lock() member function to block on the event object. The second thread blocks until the first thread sets the event.
shabbir's Avatar, Join Date: Jul 2004
Go4Expert Founder
Nominate this article for Article of the month - Oct 2009
rasd123's Avatar
Banned
Thanks for the info, I appreciate it.