Listing 1 is example code for Windows that successfully deadlocks. It would deadlock over and over, recursively, if it didn't hang from a deadlock at the outset of its recursion.
/* Listing 1: Deadlock demonstration */
#include <windows.h>
#include <stdio.h>
// Constants
const long kSuccess = 0;
const long kFailure = 1;
const long kTextAreaSize = 100;
const short kNumThreads = 2;
// Globals
CRITICAL_SECTION L1;
CRITICAL_SECTION L2;
int iSharedIntegerCounter = 0x61; // ASCII 'a'
char szSharedTextBase[kTextAreaSize];
char *pSharedText = szSharedTextBase;
// Function prototypes
DWORD WINAPI FuncA(void *vp);
DWORD WINAPI FuncB(void *vp);
// The following code deadlocks.
long main(long argc, char **argv)
{
long status = kSuccess;
HANDLE hThreads[kNumThreads];
DWORD TID1, TID2;
InitializeCriticalSection(&L1);
InitializeCriticalSection(&L2);
// Create two threads.
hThreads[0] = CreateThread(NULL,
0,
&FuncA,
(void *)1,
0,
&TID2);
if (hThreads[0] == NULL)
{
printf("Error creating thread.\n");
status = kFailure;
}
else
{
hThreads[1] = CreateThread(NULL,
0,
&FuncB,
(void *)1,
0,
&TID2);
if (hThreads[1] == NULL)
{
printf("Error creating thread.\n");
status = kFailure;
}
}
if (status == kSuccess)
{
DWORD wfmo =
WaitForMultipleObjects(kNumThreads, hThreads, TRUE, INFINITE);
int LastError = GetLastError();
DeleteCriticalSection(&L1);
DeleteCriticalSection(&L2);
// Close the thread handles.
CloseHandle(hThreads[0]);
CloseHandle(hThreads[1]);
}
// Add a NULL terminator to our 'a' - 'z' string, and display it.
*pSharedText = '\0';
printf("%s\n", szSharedTextBase);
return(status);
}
DWORD WINAPI FuncA(void *vp)
{
static int count = 13;
EnterCriticalSection(&L1);
if (count-- > 0)
{
*(pSharedText++) = iSharedIntegerCounter++;
FuncB(vp);
LeaveCriticalSection(&L1);
}
ExitThread(0);
return(0);
}
DWORD WINAPI FuncB(void *vp)
{
static int count = 13;
EnterCriticalSection(&L2);
if (count-- > 0)
{
*(pSharedText++) = iSharedIntegerCounter++;
FuncA(vp);
LeaveCriticalSection(&L2);
}
ExitThread(0);
return(0);
}



