[WinAPI] WaitForSingleObject, 쓰레드 동기화

Windows 운영체제에 의해 생성되는 커널 오브젝트의 상태는 두가지로 결정이 됩니다.
Non-Signal과 Signal 상태가 있는데 프로세스가 생성 되면 Non-Signal이였다가 프로세스가 종료 되면 Signal로 변하게 되는 것입니다.

윈도우에서는 여러가지 핸들이 존재하는데 이를 이용하여 핸들의 커널 오브젝트 상태를 보고, 프로세스가 실행 중인지, 종료 중인지 판단 할 수 있습니다.

커널 오브젝트 상태를 확인하는 함수는 WaitForSingleObject이며 사용법은 아래와 같습니다.

DWORD WaitForSingleObject( HANDLE 핸들, DWORD 대기시간(밀리초) );

프로젝트 하나 생성해 주시고 쓰레드 두개를 만들어 줍니다.

// .h
CWinThread *m_pThread1;
CWinThread *m_pThread2;
// .cpp
m_pThread1 = ::AfxBeginThread( TestThread1, (LPVOID)this );
m_pThread2 = ::AfxBeginThread( TestThread2, (LPVOID)m_pThread1->m_hThread );

첫번째 쓰레드의 실행 함수는 아래와 같습니다.

UINT CWaitForSingleObjectDlg::TestThread1( LPVOID lpVoid )
{
	CWaitForSingleObjectDlg *pDlg = (CWaitForSingleObjectDlg*)lpVoid;

	TRACE( _T( "Thread 1 Start\r\n" ) );

	for ( int iLoop = 0; iLoop < 10 ; iLoop++ )
	{
		TRACE( _T( "Thread 1 : %d\r\n" ), iLoop );

		Sleep( 100 );
	}

	TRACE( _T( "Thread 1 End\r\n" ) );

	return 0;
}

두번째 쓰레드의 실행 함수는 아래와 같습니다.

UINT CWaitForSingleObjectDlg::TestThread2( LPVOID lpVoid )
{
	HANDLE hThread = (HANDLE)lpVoid;
	DWORD dwRes;
	
	TRACE( _T( "Thread 2 Start\n" ) );

	dwRes = ::WaitForSingleObject( hThread, INFINITE );

	if ( WAIT_FAILED == dwRes )
	{
		TRACE( _T( "WAIT_FAILED\n" ) );
	}
	else if ( WAIT_ABANDONED == dwRes )
	{
		TRACE( _T( "WAIT_ABANDONED\n" ) );
	}
	else if ( WAIT_OBJECT_0 == dwRes )
	{
		TRACE( _T( "WAIT_OBJECT_0\n" ) );
	}
	else if ( WAIT_TIMEOUT == dwRes )
	{
		TRACE( _T( "WAIT_TIMEOUT\n" ) );
	}
	else
	{
		TRACE( _T( "UNKNOWN\n" ) );
	}

	for ( int iLoop = 0; iLoop < 10 ; iLoop++ )
	{
		TRACE( _T( "Thread 2 : %d\n" ), iLoop );

		Sleep( 100 );
	}

	TRACE( _T( "Thread 2 End\n" ) );

	return 0;
}

이 상태로 실행시켜 보면 TRACE에 출력된 내용은 아래와 같습니다.

visual studio 2015\waitfor\waitforsingleobject\waitforsingleobjectdlg.cpp(201) : atlTraceGeneral - Thread 1 Start
visual studio 2015\waitfor\waitforsingleobject\waitforsingleobjectdlg.cpp(206) : atlTraceGeneral - Thread 1 : 0
visual studio 2015\waitfor\waitforsingleobject\waitforsingleobjectdlg.cpp(229) : atlTraceGeneral - Thread 2 Start
visual studio 2015\waitfor\waitforsingleobject\waitforsingleobjectdlg.cpp(206) : atlTraceGeneral - Thread 1 : 1
visual studio 2015\waitfor\waitforsingleobject\waitforsingleobjectdlg.cpp(206) : atlTraceGeneral - Thread 1 : 2
visual studio 2015\waitfor\waitforsingleobject\waitforsingleobjectdlg.cpp(206) : atlTraceGeneral - Thread 1 : 3
visual studio 2015\waitfor\waitforsingleobject\waitforsingleobjectdlg.cpp(206) : atlTraceGeneral - Thread 1 : 4
visual studio 2015\waitfor\waitforsingleobject\waitforsingleobjectdlg.cpp(206) : atlTraceGeneral - Thread 1 : 5
visual studio 2015\waitfor\waitforsingleobject\waitforsingleobjectdlg.cpp(206) : atlTraceGeneral - Thread 1 : 6
visual studio 2015\waitfor\waitforsingleobject\waitforsingleobjectdlg.cpp(206) : atlTraceGeneral - Thread 1 : 7
visual studio 2015\waitfor\waitforsingleobject\waitforsingleobjectdlg.cpp(206) : atlTraceGeneral - Thread 1 : 8
visual studio 2015\waitfor\waitforsingleobject\waitforsingleobjectdlg.cpp(206) : atlTraceGeneral - Thread 1 : 9
visual studio 2015\waitfor\waitforsingleobject\waitforsingleobjectdlg.cpp(212) : atlTraceGeneral - Thread 1 End
0x4d24 스레드가 종료되었습니다(코드: 0 (0x0)).
visual studio 2015\waitfor\waitforsingleobject\waitforsingleobjectdlg.cpp(243) : atlTraceGeneral - WAIT_OBJECT_0
visual studio 2015\waitfor\waitforsingleobject\waitforsingleobjectdlg.cpp(256) : atlTraceGeneral - Thread 2 : 0
visual studio 2015\waitfor\waitforsingleobject\waitforsingleobjectdlg.cpp(256) : atlTraceGeneral - Thread 2 : 1
visual studio 2015\waitfor\waitforsingleobject\waitforsingleobjectdlg.cpp(256) : atlTraceGeneral - Thread 2 : 2
visual studio 2015\waitfor\waitforsingleobject\waitforsingleobjectdlg.cpp(256) : atlTraceGeneral - Thread 2 : 3
visual studio 2015\waitfor\waitforsingleobject\waitforsingleobjectdlg.cpp(256) : atlTraceGeneral - Thread 2 : 4
visual studio 2015\waitfor\waitforsingleobject\waitforsingleobjectdlg.cpp(256) : atlTraceGeneral - Thread 2 : 5
visual studio 2015\waitfor\waitforsingleobject\waitforsingleobjectdlg.cpp(256) : atlTraceGeneral - Thread 2 : 6
visual studio 2015\waitfor\waitforsingleobject\waitforsingleobjectdlg.cpp(256) : atlTraceGeneral - Thread 2 : 7
visual studio 2015\waitfor\waitforsingleobject\waitforsingleobjectdlg.cpp(256) : atlTraceGeneral - Thread 2 : 8
visual studio 2015\waitfor\waitforsingleobject\waitforsingleobjectdlg.cpp(256) : atlTraceGeneral - Thread 2 : 9
visual studio 2015\waitfor\waitforsingleobject\waitforsingleobjectdlg.cpp(261) : atlTraceGeneral - Thread 2 End
0x3bc0 스레드가 종료되었습니다(코드: 0 (0x0)).

위에 보시면 Thread 1, Thread 2가 실행되고 Thread 1이 작업을 완료하면 Thread 2에서 WAIT_OBJECT_0(Signal상태)가 되면서 실행 되는 것을 보실 수 있습니다.