Windows Thread Synchronization 12

 

 

 

 

 

Deadlock and Critical Section Program Example

 

The following program example uses critical section to demonstrate the deadlock situation. Keep in mind that other synchronization objects also will demonstrates the deadlock situation if not used properly.

Create a new empty Win32 console application project. Give a suitable project name and change the project location if needed.

 

Deadlock and Critical Section Program Example: Creating new C++ Win32 empty console application project

 

Then, add the source file and give it a suitable name.

 

Deadlock and Critical Section Program Example: Adding new C++ source file

 

Next, add the following source code.

 

#include <windows.h>

#include <stdio.h>

 

// Global variable

CRITICAL_SECTION csA, csB;

 

LONG WINAPI ThreadFunc(LONG);

 

int wmain(void)

{

      HANDLE hThread;

      DWORD dwThreadID;

     

      wprintf(L"The current process ID is %u\n", GetCurrentProcessId());

      // The main thread, Thread1...

      wprintf(L"The current thread ID is %u\n", GetCurrentThreadId());

 

      wprintf(L"\n");

 

      // Initializes a critical section objects

      // This function does not return a value

      InitializeCriticalSection(&csA);

      InitializeCriticalSection(&csB);

     

      // Creates a thread to execute within the virtual address space of the calling process (main()).

      hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadFunc,NULL,0,&dwThreadID);

     

      if(hThread != NULL)

            wprintf(L"CreateThread() is OK, thread ID is %u\n", dwThreadID);

      else

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

 

      // Closes the open thread handle.

      if(CloseHandle(hThread) != 0)

            wprintf(L"hThread handle was successfully closed!\n");

      else

            wprintf(L"Failed to close hThread handle, error %u\n", GetLastError());

 

      wprintf(L"\n");

 

      // While true...

      while(1)

      {    

            // Waits for ownership of the specified critical section object.

            // The function returns when the calling thread is granted ownership.

            // This function does not return a value.

            EnterCriticalSection(&csA);

            wprintf(L"Thread1 (%u) has entered Critical Section A but not B.\n", GetCurrentThreadId());       

            EnterCriticalSection(&csB);        

            wprintf(L"Thread1 (%u) has entered Critical Section A and B!\n", GetCurrentThreadId());       

            // Releases ownership of the specified critical section object.

            // This function does not return a value.

            LeaveCriticalSection(&csB);        

            wprintf(L"Thread1 (%u) has left Critical Section B but still owns A.\n", GetCurrentThreadId());       

            LeaveCriticalSection(&csA);        

            wprintf(L"Thread1 (%u) has left both critical sections, A and B...\n", GetCurrentThreadId());

           

            Sleep(50); 

      };

     

      return 0;

}

 

LONG WINAPI ThreadFunc(LONG lParam)

{

      // The child thread, Thread2...

 

      // While true

      while(1)

            {

                  EnterCriticalSection(&csB);

                  wprintf(L"Thread2 (%u) has entered Critical Section B but not A.\n", GetCurrentThreadId());

                  EnterCriticalSection(&csA);

                  wprintf(L"Thread2 (%u) has entered Critical Section B and A!\n", GetCurrentThreadId());

                  LeaveCriticalSection(&csA);

                  wprintf(L"Thread2 (%u) has left Critical Section A but still owns B.\n", GetCurrentThreadId());

                  LeaveCriticalSection(&csB);

                  wprintf(L"Thread2 (%u) has left both critical sections, A and B...\n", GetCurrentThreadId());

                  Sleep(50);

      };

}

 

Build and run the project. The following are the sample outputs.

Deadlock and Critical Section Program Example: Sample console output illustrating the deadlock in action

 

We can use Windows Task Manager to verify the threads creation.

 

Deadlock and Critical Section Program Example: Deadlock threads seen from the Task Manager

 

The following is another sample output.

 

Deadlock and Critical Section Program Example: Another sample console output

 

Deadlock and Critical Section Program Example: Verifying the threads count

 

Thread 1 has claimed critical section A and is suspended because it is waiting to enter critical section B, whereas Thread 2 owns critical section B and waits for Thread 1 to release critical section A, which will never happen, of course, because Thread 1 will not release critical section A before Thread 2 has released critical section B, which will never happen, of course and these processes repeat.

 

 

 

 

< Thread Synchronization 11 | Thread Synchronization Programming | Win32 Programming | Thread Synchronization 13 >