///////////////////////////////////////////////////////////////////////////////
//
// DeadLockDemo.cpp
//
// Author: Oleg Starodumov (www.debuginfo.com)
//
// This application simulates a deadlock
//
//
///////////////////////////////////////////////////////////////////////////////
// Include files
//
#include <windows.h>
#include <tchar.h>
#include <process.h>
#include <stdio.h>
///////////////////////////////////////////////////////////////////////////////
// Helper macros
//
// _beginthreadex wrapper macro (source: J.Richter, "Advanced Windows")
typedef unsigned (__stdcall *PTHREAD_START) (void*);
#define BEGINTHREADEX(lpsa, cbStack, lpStartAddr,\
lpvThreadParm, fdwCreate, lpIDThread) \
((HANDLE)_beginthreadex( \
(void*)(lpsa), \
(unsigned)(cbStack), \
(PTHREAD_START)(lpStartAddr), \
(void*)(lpvThreadParm), \
(unsigned)(fdwCreate), \
(unsigned*)(lpIDThread)))
///////////////////////////////////////////////////////////////////////////////
// Critical section wrapper classes
//
class CCriticalSection
{
public:
CCriticalSection()
{
InitializeCriticalSection( &m_cs );
}
~CCriticalSection()
{
DeleteCriticalSection( &m_cs );
}
void Lock()
{
EnterCriticalSection( &m_cs );
}
void Unlock()
{
LeaveCriticalSection( &m_cs );
}
private:
// Copy protection
CCriticalSection( const CCriticalSection& );
CCriticalSection& operator=( const CCriticalSection& );
private:
// Critical section structure
CRITICAL_SECTION m_cs;
};
class CCritSecLock
{
public:
CCritSecLock( CCriticalSection& cs )
: m_rcs( cs )
{
m_rcs.Lock();
}
~CCritSecLock()
{
m_rcs.Unlock();
}
private:
// CCriticalSection object reference
CCriticalSection& m_rcs;
};
///////////////////////////////////////////////////////////////////////////////
// Function declarations
//
DWORD WINAPI ThreadOne( LPVOID lpParam );
DWORD WINAPI ThreadTwo( LPVOID lpParam );
///////////////////////////////////////////////////////////////////////////////
// Global variables
//
CCriticalSection CritSecOne;
CCriticalSection CritSecTwo;
///////////////////////////////////////////////////////////////////////////////
// main()
//
int _tmain( int argc, TCHAR* argv[] )
{
// Start worker threads
_tprintf( _T("Starting worker threads...\n") );
HANDLE hThread = NULL;
DWORD ThreadId = 0;
hThread = BEGINTHREADEX(0, 0, ThreadOne, 0, 0, &ThreadId );
if( hThread == NULL )
{
_tprintf( _T("Cannot start thread. Error: %u\n"), GetLastError() );
return 0;
}
hThread = BEGINTHREADEX(0, 0, ThreadTwo, 0, 0, &ThreadId );
if( hThread == NULL )
{
_tprintf( _T("Cannot start thread. Error: %u\n"), GetLastError() );
return 0;
}
// Worker threads started
_tprintf( _T("Worker threads started.\n") );
Sleep( 60 * 60 * 1000 );
// Complete
_tprintf( _T("Test complete.\n") );
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// Worker threads
//
DWORD WINAPI ThreadOne( LPVOID lpParam )
{
_tprintf( _T("ThreadOne[%u] started.\n"), GetCurrentThreadId() );
while( 1 )
{
CCritSecLock LockOne( CritSecOne );
_tprintf( _T("ThreadOne[%u] acquired CritSecOne\n"), GetCurrentThreadId() );
{
CCritSecLock LockTwo( CritSecTwo );
_tprintf( _T("ThreadOne[%u] acquired CritSecTwo.\n"), GetCurrentThreadId() );
}
}
return 0;
}
DWORD WINAPI ThreadTwo( LPVOID lpParam )
{
_tprintf( _T("ThreadTwo[%u] started.\n"), GetCurrentThreadId() );
while( 1 )
{
CCritSecLock LockTwo( CritSecTwo );
_tprintf( _T("ThreadTwo[%u] acquired CritSecTwo\n"), GetCurrentThreadId() );
{
CCritSecLock LockOne( CritSecOne );
_tprintf( _T("ThreadTwo[%u] acquired CritSecOne\n"), GetCurrentThreadId() );
}
}
return 0;
}
//
// DeadLockDemo.cpp
//
// Author: Oleg Starodumov (www.debuginfo.com)
//
// This application simulates a deadlock
//
//
///////////////////////////////////////////////////////////////////////////////
// Include files
//
#include <windows.h>
#include <tchar.h>
#include <process.h>
#include <stdio.h>
///////////////////////////////////////////////////////////////////////////////
// Helper macros
//
// _beginthreadex wrapper macro (source: J.Richter, "Advanced Windows")
typedef unsigned (__stdcall *PTHREAD_START) (void*);
#define BEGINTHREADEX(lpsa, cbStack, lpStartAddr,\
lpvThreadParm, fdwCreate, lpIDThread) \
((HANDLE)_beginthreadex( \
(void*)(lpsa), \
(unsigned)(cbStack), \
(PTHREAD_START)(lpStartAddr), \
(void*)(lpvThreadParm), \
(unsigned)(fdwCreate), \
(unsigned*)(lpIDThread)))
///////////////////////////////////////////////////////////////////////////////
// Critical section wrapper classes
//
class CCriticalSection
{
public:
CCriticalSection()
{
InitializeCriticalSection( &m_cs );
}
~CCriticalSection()
{
DeleteCriticalSection( &m_cs );
}
void Lock()
{
EnterCriticalSection( &m_cs );
}
void Unlock()
{
LeaveCriticalSection( &m_cs );
}
private:
// Copy protection
CCriticalSection( const CCriticalSection& );
CCriticalSection& operator=( const CCriticalSection& );
private:
// Critical section structure
CRITICAL_SECTION m_cs;
};
class CCritSecLock
{
public:
CCritSecLock( CCriticalSection& cs )
: m_rcs( cs )
{
m_rcs.Lock();
}
~CCritSecLock()
{
m_rcs.Unlock();
}
private:
// CCriticalSection object reference
CCriticalSection& m_rcs;
};
///////////////////////////////////////////////////////////////////////////////
// Function declarations
//
DWORD WINAPI ThreadOne( LPVOID lpParam );
DWORD WINAPI ThreadTwo( LPVOID lpParam );
///////////////////////////////////////////////////////////////////////////////
// Global variables
//
CCriticalSection CritSecOne;
CCriticalSection CritSecTwo;
///////////////////////////////////////////////////////////////////////////////
// main()
//
int _tmain( int argc, TCHAR* argv[] )
{
// Start worker threads
_tprintf( _T("Starting worker threads...\n") );
HANDLE hThread = NULL;
DWORD ThreadId = 0;
hThread = BEGINTHREADEX(0, 0, ThreadOne, 0, 0, &ThreadId );
if( hThread == NULL )
{
_tprintf( _T("Cannot start thread. Error: %u\n"), GetLastError() );
return 0;
}
hThread = BEGINTHREADEX(0, 0, ThreadTwo, 0, 0, &ThreadId );
if( hThread == NULL )
{
_tprintf( _T("Cannot start thread. Error: %u\n"), GetLastError() );
return 0;
}
// Worker threads started
_tprintf( _T("Worker threads started.\n") );
Sleep( 60 * 60 * 1000 );
// Complete
_tprintf( _T("Test complete.\n") );
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// Worker threads
//
DWORD WINAPI ThreadOne( LPVOID lpParam )
{
_tprintf( _T("ThreadOne[%u] started.\n"), GetCurrentThreadId() );
while( 1 )
{
CCritSecLock LockOne( CritSecOne );
_tprintf( _T("ThreadOne[%u] acquired CritSecOne\n"), GetCurrentThreadId() );
{
CCritSecLock LockTwo( CritSecTwo );
_tprintf( _T("ThreadOne[%u] acquired CritSecTwo.\n"), GetCurrentThreadId() );
}
}
return 0;
}
DWORD WINAPI ThreadTwo( LPVOID lpParam )
{
_tprintf( _T("ThreadTwo[%u] started.\n"), GetCurrentThreadId() );
while( 1 )
{
CCritSecLock LockTwo( CritSecTwo );
_tprintf( _T("ThreadTwo[%u] acquired CritSecTwo\n"), GetCurrentThreadId() );
{
CCritSecLock LockOne( CritSecOne );
_tprintf( _T("ThreadTwo[%u] acquired CritSecOne\n"), GetCurrentThreadId() );
}
}
return 0;
}
덧글을 달아 주세요