Thread 비교, 사용법
- 강제 종료는 강력히 권장하지 않음
//====================
* AfxBeginThread <- 권장
- 동작
- 내부적으로 CWinThread가 모든일을 함, CWinThread 리턴
- 스레드 생성을 위해 CWinThread::CreateThread 함수를 호출
- CWinThread::CreateThread 함수는 내부적으로 _beginthreadex 함수를 호출
- 강제종료 - 함수안 : AfxEndThread(), 함수 밖 : TerminateThread();
- CWinThread *pWinThread = AfxBeginThread( ThreadFunc1, &nMode);
hThread = pWinThread->m_hThread;
//===========================
* CreateThread <- 비권장
- 강제종료 : 함수안 : ExitThread(), 함수 밖 : TerminateThread();
- hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadFunc1, &nMode, 0, &dwThreadID);
* _begingthreadex
- 구 _begingthread 함수의 문제 :
쓰레드를 생성한후 바로 ::CloseHandle 함수를 호출하여 생성된 스레드의 핸들을 제거
-> _beginthread 함수 호출 이후에 이 스레드 핸들에 접근 불가
- 쓰레드 함수에서 ::CloseHandle 함수를 호출해 주어야 함
- 강제종료 : 함수안 : _endthreadex(), 함수 밖 : TerminateThread();
- hThread = (HANDLE)_beginthreadex(NULL, 0, (unsigned ( __stdcall *)( void * ))ThreadFunc1, &nMode, 0, (unsigned *)&dwThreadID);
* CWinThread
- UI 쓰레드(메시지 처리가능한 쓰레드)를 만들수 있음
- 사용법
- CWinThread를 상속 받는 자식클래스를 만든다.
- 생성자,소멸자를 public으로 만든다.
- virtual int Run();추가
- pThread = (apTestThread *)AfxBeginThread(RUNTIME_CLASS(apTestThread ) );
//===================================================================================
int g_bStopThread=0;
//
static DWORD ThreadFunc1(LPVOID lpParam)
{
int *pnMode = (int*)lpParam;
while( !g_bStopThread ){
TRACE(_T("ThreadFunc1-실행\n"));Sleep(1000);
}
switch(*pnMode)
{
case 1: ExitThread(1); break;//CreateThread
case 2: _endthreadex(1); break;//_beginthreadex
case 3: AfxEndThread(1); break;//AfxEndThread
}
return 1;
}
DWORD CTestDlgMfc6Dlg::ThreadTest()
{
DWORD dwThreadID=0;
HANDLE hThread = 0;
int nMode=0;
g_bStopThread = 0;
//==============================================================================
//1. API - CreateThread 사용 - Win API만 사용 가능, MFC, C 함수는 사용 불가
//TRACE(_T("ThreadTest-API-시작\n"));
//CreateThread 사용 - Win API만 사용 가능, MFC, C 함수는 사용 불가
nMode=1;
//hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadFunc1, &nMode, 0, &dwThreadID);
//ExitThread
//==============================================================================
//2. API - _beginthreadex 사용 - Win API, C함수 사용 가능
nMode=2;
//hThread = (HANDLE)_beginthreadex(NULL, 0, (unsigned ( __stdcall *)( void * ))ThreadFunc1, &nMode, 0, (unsigned *)&dwThreadID);
//_endthread
//==============================================================================
//3. MFC - AfxBeginThread
//TRACE(_T("ThreadTest-MFC-시작\n"));
nMode=3;
CWinThread *pWinThread = AfxBeginThread( (AFX_THREADPROC )ThreadFunc1, &nMode);
hThread = pWinThread->m_hThread;
//==============================================================================
//4. MFC - CWinThread
TRACE(_T("ThreadTest-MFC, CWinThread-시작\n"));
apTestThread* pThread = 0;
//시작 방법 1
//pThread = new apTestThread() ; pThread->CreateThread(CREATE_SUSPENDED) ;
//시작 방법 2
pThread = (apTestThread *)AfxBeginThread(RUNTIME_CLASS(apTestThread ) );
//pThread = (apTestThread *)AfxBeginThread(RUNTIME_CLASS(apTestThread ), THREAD_PRIORITY_NORMAL, CREATE_SUSPENDED, 0 );
//설정
pThread->m_bAutoDelete = false ; // 기본은 true
//pThread->sName = _T("Test") ; //
pThread->ResumeThread() ;
hThread = pThread->m_hThread;
//===============================================================================
// 쓰레드 종료
TRACE(_T("쓰레드-종료 기다림...\n"));
DWORD dwRetCode = ::WaitForSingleObject(hThread, 2000);//INFINITE
if (dwRetCode == WAIT_OBJECT_0){// 정상 종료
TRACE(_T("쓰레드-정상 종료\n"));
//ReleaseMutex(hMutex);
CloseHandle(hThread);//
//delete(pThread) ;//m_bAutoDelete = false인 경우
}else if(dwRetCode == WAIT_TIMEOUT) {
// 제한시간동안 쓰레드라 종료되지 않음
TRACE(_T("쓰레드-종료 되지 않음 - 시간 지남\n"));
//g_bStopThread = 1;//리소스 해제 할수 있음, ExitThread, _endthread, AfxEndThread
TerminateThread( hThread , 0);//리소스가 해제 안될수 있음
}else if (dwRetCode == WAIT_ABANDONED){// Mutex를 선점하던 Thread가 강제로 종료됨
TRACE(_T("쓰레드-Mutex를 선점하던 Thread가 강제로 종료됨\n"));
//ReleaseMutex(hMutex);
}else if (dwRetCode == WAIT_FAILED ){// WaitForSingleObject 함수 에러
TRACE(_T("쓰레드-WaitForSingleObject 함수 에러\n"));
}
//==============================================================================
//
TRACE(_T("ThreadTest-종료\n"));
return 1;
}
'Code' 카테고리의 다른 글
FFMPEG version up (0) | 2013.01.05 |
---|---|
힙에러 (0) | 2012.12.26 |
error log-2012/12 (0) | 2012.12.22 |
Visual Studio 2010 사용 관련 (2) | 2012.11.17 |
문자 코드 (0) | 2012.11.11 |