Synchronization Using Mutexes Program Example
A mutex is a kernel object that provides a thread with mutually exclusive access to a single resource. The state of a mutex object is set to signaled when it is not owned by any thread, and nonsignaled when it is owned. Only one thread at a time can own a mutex object, whose name comes from the fact that it is useful in coordinating mutually exclusive access to a shared resource. Any thread of the calling process can specify the mutex-object handle in a call to one of the wait functions. The single-object wait functions return when the state of the specified object is signaled. When the state of the mutex is signaled, one waiting thread is granted ownership, the state of the mutex changes to nonsignaled, and the wait function returns. The owning thread uses the ReleaseMutex function to release its ownership. The next example looks at the use of mutexes to coordinate access to a shared resource and to handshake between two threads.
Create a new empty Win32 console application project. Give a suitable project name and change the project location if needed.
Then, add the source file and give it a suitable name.
Next, add the following source code.
#include <Windows.h>
#include <stdio.h>
#define SHARED_SIZE 1024
// Shared global variables
WCHAR shared_area[SHARED_SIZE];
LPCTSTR lpszMutex = LNamedMutex;
HANDLE shared_mutex;
DWORD WINAPI thread_function(LPVOID arg)
{
DWORD dwWfSO, dwWfSO1;
// Opens an existing named mutex object.
HANDLE hMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, lpszMutex);
if(hMutex == NULL)
wprintf(LOpenMutex() failed, error %u\n, GetLastError());
else
wprintf(L%s mutex handle successfully opened!\n, lpszMutex);
dwWfSO = WaitForSingleObject(hMutex, INFINITE);
wprintf(LWaitForSingleObject() 1 returned value is 0X%.8X\n, dwWfSO);
while(wcsncmp(Ldone, shared_area, 4) != 0)
{
wprintf(LYou input %d characters...\n, wcslen(shared_area) -1);
// Releases ownership of the specified mutex object.
// If the function succeeds, the return value is nonzero.
// If the function fails, the return value is zero.
if(ReleaseMutex(hMutex) != 0)
wprintf(LhMutex handle was released!\n);
else
wprintf(LFailed to release the hMutex handle, error %u\n, GetLastError());
dwWfSO1 = WaitForSingleObject(hMutex, INFINITE);
wprintf(LWaitForSingleObject() 2 returned value is 0X%.8X\n, dwWfSO1);
}
if(ReleaseMutex(hMutex) != 0)
wprintf(LhMutex handle was released!\n);
else
wprintf(LFailed to release the hMutex handle, error %u\n, GetLastError());
if(CloseHandle(hMutex) != 0)
wprintf(LhMutex handle was closed successfully!\n);
else
wprintf(LFailed to close hMutex handle, error %u\n, GetLastError());
return 0;
}
int wmain()
{
HANDLE a_thread;
DWORD a_threadId, dwMWfSO1, dwMWfSO2;
DWORD thread_result;
// Create a mutex with no initial owner
shared_mutex = CreateMutex( NULL, TRUE, lpszMutex );
if (shared_mutex == NULL)
{
wprintf(LCreateMutex() - Mutex initialization failed, error %u\n, GetLastError());
exit(EXIT_FAILURE);
}
else
wprintf(LCreateMutex() is OK! A Mutex was created successfully!\n);
// Create a new thread.
a_thread = CreateThread(NULL, 0, thread_function, (LPVOID)NULL, 0,&a_threadId);
if (a_thread == NULL)
{
wprintf(LCreateThread() - Thread creation failed, error %u, GetLastError());
exit(EXIT_FAILURE);
}
else
wprintf(LCreateThread() is OK, thread ID is %u\n, a_threadId);
wprintf(L\nInput some text. Enter 'done' to finish\n);
wprintf(L\n);
while(wcsncmp(Ldone, shared_area, 4) != 0)
{
fgetws(shared_area, SHARED_SIZE, stdin);
if(ReleaseMutex(shared_mutex) != 0)
wprintf(Lshared_mutex handle was released!\n);
else
wprintf(LFailed to release the shared_mutex handle, error %u\n, GetLastError());
dwMWfSO1 = WaitForSingleObject(shared_mutex, INFINITE);
wprintf(LWaitForSingleObject() 3 returned value is 0X%.8X\n, dwMWfSO1);
wprintf(L\n);
}
if(ReleaseMutex(shared_mutex) != 0)
wprintf(Lshared_mutex handle was released!\n);
else
wprintf(LFailed to release the shared_mutex handle, error %u\n, GetLastError());
wprintf(LWaiting for thread to finish...\n);
dwMWfSO2 = WaitForSingleObject(a_thread, INFINITE);
wprintf(LWaitForSingleObject() 4 returned value is 0X%.8X\n, dwMWfSO1);
if(dwMWfSO2 != WAIT_OBJECT_0)
{
wprintf(LWaitForSingleObject() failed, thread join failed, error %u\n, GetLastError());
exit(EXIT_FAILURE);
}
else
wprintf(LWaitForSingleObject() 4 is OK!\n);
// Retrieve the code returned by the thread.
if(GetExitCodeThread(a_thread, &thread_result) != 0)
wprintf(LGetExitCodeThread() is OK! Thread joined, exit code %u\n, thread_result);
else
wprintf(LGetExitCodeThread() failed, error %u\n, GetLastError());
if(CloseHandle(shared_mutex) != 0)
wprintf(Lshared_mutex handle was closed successfully!\n);
else
wprintf(LFailed to close shared_mutex handle, error %u\n, GetLastError());
return 0;
}
Build and run the project. The following screenshot is a sample output.