///////////////////////////////////////////////////////////////////////////////
//
// 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;
}
 
2007/09/23 23:50 2007/09/23 23:50

글 걸기 주소 : 이 글에는 트랙백을 보낼 수 없습니다

덧글을 달아 주세요