티스토리 뷰
[원본 - 2013년 이글루스]
MFC없이 Win32 API 만을 이용해 Thread 프로그래밍을 하던 중
자바나 C#의 Thread 클래스처럼 class화 해서 사용할 수 있으면 좋겠다고 생각해서 대충 생각나는대로 디자인을 해봤다
일단 간단한 Thread 프로그래밍에는 그럭저럭 만족스러운 모습을 보여주었다
#ifndef _BASIC_THREAD_H_
#define _BASIC_THREAD_H_
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
/*=======================================================================
** File : BasicThread.h
** Desc : 기본적인 Thread Class
** Author : Jin-Gyu Choi
** Create : 2013.03.28
** Last Modify : 2013.03.28
========================================================================*/
class BasicThread
{
protected:
HANDLE m_hThread; // Window Thread Handle
DWORD m_nThreadID; // Window Thread ID
private:
BasicThread( const BasicThread& bt ) {} // 해당 Thread의 복제를 막는다
BasicThread& operator = ( const BasicThread& bt ) {} // 해당 Thread의 복제를 막는다
static DWORD WINAPI StaticThreadStart( LPVOID lpParam ) // 실제 Thread의 시작부분
{
BasicThread* pThread = (BasicThread*)lpParam;
return pThread->Run();
}
protected:
virtual DWORD Run(void) = 0; // Protected로 사용자가 직접 호출하는 것을 막음
public:
BasicThread() : m_hThread( NULL ), m_nThreadID( 0 )
{
}
virtual ~BasicThread()
{
if( m_hThread ) CloseHandle( m_hThread );
}
public:
//----------------------------------------------------------------
// public functions
//----------------------------------------------------------------
bool Start() // Thread 시작
{
if( m_hThread ) // 이미 Thread가 생성되어 있는 경우
{
if( WaitForSingleObject( m_hThread, 0 ) == WAIT_TIMEOUT ) { // Thread Still Running
return false; // Start 거부
}
CloseHandle( m_hThread );
}
// Thread 생성
m_hThread = CreateThread(
NULL, // default security attributes
0, // default stack size
(LPTHREAD_START_ROUTINE)BasicThread::StaticThreadStart,
this, // thread function argument = this class
0, // default creation flags
&m_nThreadID // receive thread identifier
);
if( m_hThread != NULL ) return true;
return false;
}
void Stop() // Thread 강제 종료 - 비추!!
{
if( this->IsRunning() ) {
// 강제 Terminate이므로 정상적인 자원 해제를 기대할 수 없음
// 공유자원 등을 물고 있을 경우 deadlock 등의 위험이 있을 수 있음
::TerminateThread( m_hThread, -1 );
}
if( m_hThread ){
CloseHandle( m_hThread );
m_hThread = NULL;
}
}
public:
//----------------------------------------------------------------
// inline functions
//----------------------------------------------------------------
// Getter
inline HANDLE GetThreadHandle() { return m_hThread; }
inline DWORD GetThreadID() { return m_nThreadID; }
// Status
inline bool IsRunning()
{
if( m_hThread ){
DWORD dwExitCode = 0;
::GetExitCodeThread( m_hThread, &dwExitCode );
if( dwExitCode == STILL_ACTIVE ) return true;
}
return false;
}
// Join - Wait For Thread Done
inline void Join()
{
::WaitForSingleObject( m_hThread, INFINITE );
}
// Yeild - Yeild Execution to Another Thread
inline BOOL Yeild()
{
return ::SwitchToThread();
}
// Sleep - Suspends the execution of the current thread until the time-out interval elapses
inline void Sleep( DWORD dsMilliiseconds )
{
::Sleep( dsMilliiseconds );
}
// Suspend - Suspend Thread
inline DWORD Suspend()
{
return ::SuspendThread( m_hThread );
}
// Resume - Resume Thread
inline DWORD Resume()
{
return ::ResumeThread( m_hThread );
}
};
#endif
BasicThread 클래스 그 자체로는 Run이 정의되어 있지 않기 때문에 그대로 사용하는 것은 안되고
실제로 사용하기 위해서는 BasicThread 클래스를 상속받아 Run() 함수를 구현해서 사용하면 된다
대략 사용한다면 이런 느낌???
물론 원한다면 맴버변수, static 변수 모두 사용 가능하다
#include <stdio.h>
#include "BasicThread.h"
class TestThread : public BasicThread
{
protected:
DWORD Run(void)
{
printf("Thread %d Start\n", GetThreadID());
for( int i = 0; i < 5; i++ )
{
printf("Thread %d : Count %d\n", GetThreadID(), i);
this->Sleep( 1000 );
}
printf("Thread %d End\n", GetThreadID());
return 0;
}
};
int main(void)
{
TestThread* pThread[5];
for( int i = 0 ; i < 5; i++ )
{
pThread[i] = new TestThread();
pThread[i]->Start();
}
for( int i = 0 ; i < 5; i++ )
{
pThread[i]->Join();
delete pThread[i];
}
return 0;
}
'개발 관련 정리 (구 블로그에서 백업) > Language (OS 종속) 관련' 카테고리의 다른 글
[WINAPI] WinSock2 와 Windows 헤더 충돌 문제 (0) | 2018.11.26 |
---|---|
[WINAPI] 프로세스 잘(?) 죽이기 - Terminate Process Nicely(?) (0) | 2018.11.26 |
[WIN32] WINAPI 마우스 움직이기 mouse_event() vs. SetCursorPos() 그 첫번째 실험... (0) | 2018.11.26 |
댓글