Using the Windows mutex object related functions for thread synchronization

 

 

 

 

// For WinXp as a target, change appropriately

#define _WIN32_WINNT 0x0501

#include <windows.h>

#include <stdio.h>

 

// Number of thread

#define THREADCOUNT 2

 

// Global var

HANDLE ghMutex;

 

// Simulated function

DWORD WINAPI WriteToDatabase(LPVOID);

 

int wmain( void )

{

HANDLE aThread[THREADCOUNT];

DWORD ThreadID;

int i;

 

// Create a mutex with no initial owner

ghMutex = CreateMutex(

NULL, // default security attributes

FALSE, // initially not owned

NULL); // unnamed mutex

if (ghMutex == NULL)

{

wprintf(L"CreateMutex() error %d\n", GetLastError());

return 1;

}

else

wprintf(L"Unnamed mutex object successfully created!\n");

 

// Create worker threads

for( i=0; i < THREADCOUNT; i++ )

{

aThread[i] = CreateThread(

NULL, // default security attributes

0, // default stack size

(LPTHREAD_START_ROUTINE) WriteToDatabase,

NULL, // no thread function arguments

0, // default creation flags

&ThreadID); // receive thread identifier

 

if( aThread[i] == NULL )

{

wprintf(L"CreateThread() error %d\n", GetLastError());

return 1;

}

else

wprintf(L"CreatThread() is OK. Thread #%d, ID: %d was successfully created!\n", i, GetCurrentThreadId());

}

 

wprintf(L"\n");

// Wait for all threads to terminate

WaitForMultipleObjects(THREADCOUNT, aThread, TRUE, INFINITE);

// Close thread and mutex handles

for( i=0; i < THREADCOUNT; i++ )

{

if(CloseHandle(aThread[i]) != 0)

wprintf(L"Thread #%d handle with ID: %d was successfully closed!\n", i, GetCurrentThreadId());

else

wprintf(L"Failed to close thread #%d handle, error %d!\n", i, GetLastError());

}

if(CloseHandle(ghMutex) != 0)

wprintf(L"Mutex object handle was successfully closed!\n", i);

else

wprintf(L"Failed to close mutex object handle, error %d!\n", i, GetLastError());

return 0;

}

 

DWORD WINAPI WriteToDatabase(LPVOID lpParam)

{

// lpParam not used in this example

UNREFERENCED_PARAMETER(lpParam);

DWORD dwCount=0, dwWaitResult;

// Request ownership of mutex

while( dwCount < 10 )

{

dwWaitResult = WaitForSingleObject(

ghMutex, // handle to mutex

INFINITE); // no time-out interval

switch (dwWaitResult)

{

// The thread got ownership of the mutex

case WAIT_OBJECT_0:

__try {

// TODO: Write to the database

wprintf(L"Thread %d writing to database...\n", GetCurrentThreadId());

dwCount++;

}

__finally {

// Release ownership of the mutex object

if (!ReleaseMutex(ghMutex))

{

// Handle error.

wprintf(L" ReleaseMutex() error %d\n", GetLastError());

}

else

wprintf(L" ReleaseMutex() - Handle to mutex object was released!\n");

}

break;

// The thread got ownership of an abandoned mutex. The database is in an indeterminate state

case WAIT_ABANDONED:

{

wprintf(L"WAIT_ABANDONED...\n");

return FALSE;

}

}

}

return TRUE;

}

 

Output example:

 

Unnamed mutex object successfully created!

CreatThread() is OK. Thread #0, ID: 3144 was successfully created!

Thread 484 writing to database...

ReleaseMutex() - Handle to mutex object was released!

Thread 2516 writing to database...

CreatThread() is OK. Thread #1, ID: 3144 was successfully created!

ReleaseMutex() - Handle to mutex object was released!

Thread 484 writing to database...

ReleaseMutex() - Handle to mutex object was released!

Thread 2516 writing to database...

ReleaseMutex() - Handle to mutex object was released!

Thread 484 writing to database...

ReleaseMutex() - Handle to mutex object was released!

Thread 2516 writing to database...

ReleaseMutex() - Handle to mutex object was released!

Thread 484 writing to database...

ReleaseMutex() - Handle to mutex object was released!

Thread 2516 writing to database...

ReleaseMutex() - Handle to mutex object was released!

Thread 484 writing to database...

ReleaseMutex() - Handle to mutex object was released!

Thread 2516 writing to database...

ReleaseMutex() - Handle to mutex object was released!

Thread 484 writing to database...

ReleaseMutex() - Handle to mutex object was released!

Thread 2516 writing to database...

ReleaseMutex() - Handle to mutex object was released!

Thread 484 writing to database...

ReleaseMutex() - Handle to mutex object was released!

Thread 2516 writing to database...

ReleaseMutex() - Handle to mutex object was released!

Thread 484 writing to database...

ReleaseMutex() - Handle to mutex object was released!

Thread 2516 writing to database...

ReleaseMutex() - Handle to mutex object was released!

Thread 484 writing to database...

ReleaseMutex() - Handle to mutex object was released!

Thread 2516 writing to database...

ReleaseMutex() - Handle to mutex object was released!

Thread 484 writing to database...

ReleaseMutex() - Handle to mutex object was released!

Thread 2516 writing to database...

ReleaseMutex() - Handle to mutex object was released!

Thread #0 handle with ID: 3144 was successfully closed!

Thread #1 handle with ID: 3144 was successfully closed!

Mutex object handle was successfully closed!

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 Windows mutex object and related functions for thread synchronization

To show: The Windows process and thread related functions manipulation - using mutex object

 

 

C and C++ Programming Resources | C & C++ Code Example Index