Using the Windows WaitForMultipleObjects() and events
/* The following example uses the CreateEvent() function to create two event objects and the CreateThread() function
to create a thread. It then uses the WaitForMultipleObjects() function to wait for the thread to set the state of
one of the objects to signaled using the SetEvent() function. */
// For WinXp as a target, change appropriately
#define _WIN32_WINNT 0x0501
#include <windows.h>
#include <stdio.h>
// Global variable
HANDLE ghEvents[2];
// Prototype
DWORD WINAPI ThreadProc( LPVOID );
int wmain(void)
{
HANDLE hThread;
DWORD i, dwEvent, dwThreadID;
wprintf(L"The current thread ID is: %d\n", GetCurrentThreadId());
// Create two event objects
for (i = 0; i < 2; i++)
{
ghEvents[i] = CreateEvent(
NULL, // default security attributes
FALSE, // auto-reset event object
FALSE, // initial state is nonsignaled
NULL); // unnamed object
if (ghEvents[i] == NULL)
{
wprintf(L"CreateEvent() #%d error: %d\n", i, GetLastError() );
ExitProcess(0);
}
else
wprintf(L"CreateEvent() #%d is OK!\n", i);
}
// Create a thread
hThread = CreateThread(
NULL, // default security attributes
0, // default stack size
(LPTHREAD_START_ROUTINE) ThreadProc,
NULL, // no thread function arguments
0, // default creation flags
&dwThreadID); // receive thread identifier
if( hThread == NULL )
{
wprintf(L"CreateThread() error: %d\n", GetLastError());
return 1;
}
else
wprintf(L"CreateThread() should be fine!\n");
// Wait for the thread to signal one of the event objects
dwEvent = WaitForMultipleObjects(
2, // number of objects in array
ghEvents, // array of objects
FALSE, // wait for any object
3000); // three-second wait
wprintf(L"WaitForMultipleObjects() returns %d\n", dwEvent);
// The return value indicates which event is signaled
switch (dwEvent)
{
// ghEvents[0] was signaled
case WAIT_OBJECT_0 + 0:
// TODO: Perform tasks required by this event
Sleep(3000);
wprintf(L"First event was signaled...\n");
break;
// ghEvents[1] was signaled
case WAIT_OBJECT_0 + 1:
// TODO: Perform tasks required by this event
Sleep(2000);
wprintf(L"Second event was signaled...\n");
break;
case WAIT_TIMEOUT:
wprintf(L"Wait timed out...\n");
break;
// Return value is invalid.
default:
wprintf(L"Wait error: %d\n", GetLastError());
ExitProcess(0);
}
// Close event handles
for (i = 0; i < 2; i++)
{
CloseHandle(ghEvents[i]);
wprintf(L"Closing the event handle #%d\n", i);
}
return 0;
}
DWORD WINAPI ThreadProc(LPVOID lpParam)
{
// lpParam not used in this example
UNREFERENCED_PARAMETER( lpParam);
// Set one event to the signaled state
if (!SetEvent(ghEvents[0]))
{
wprintf(L"SetEvent() failed, error %d\n", GetLastError());
return 1;
}
else
wprintf(L"SetEvent() is pretty fine, one event was signaled!\n");
wprintf(L"The current thread ID is: %d\n", GetCurrentThreadId());
return 0;
}
Output example:
The current thread ID is: 5752
CreateEvent() #0 is OK!
CreateEvent() #1 is OK!
CreateThread() should be fine!
SetEvent() is pretty fine, one event was signaled!
WaitForMultipleObjects() returns 0
The current thread ID is: 1100
First event was signaled...
Closing the event handle #0
Closing the event handle #1
Press any key to continue . . .
Compiler: Visual C++ Express Edition 2005
Compiled on Platform: Windows XP Pro SP2
Target platform: none, just for learning and fun
Header file: Standard and Windows
Additional library: Windows Platform SDK
Additional project setting: Set project to be compiled as C
Project -> your_project_name Properties -> Configuration Properties -> C/C++ -> Advanced -> Compiled As: Compiled as C Code (/TC)
Other info: non-CLR or unmanaged
To do: Using the WaitForMultipleObjects() and events for thread synchronization
To show: The Windows process and thread related functions usage