출처 : http://codens.info/678
쓰레드 생성
- AfxBeginThread 권장
- CWinThread::m_bAutoDelete
- 기본은 TRUE, 자동으로 개체(핸들포함)가 삭제됨 <- 권장
- FALSE로 설정하려면 CREATE_SUSPENED 로 시작해서 설정후 ResumeThread()해줘야함
- 해제시 핸들을 닫으면 안되고 CWinThread개체를 delete 해야 함
- AfxEndThread()는 강제 종료 함수로 권장 안함
- CreateThread() 권장 안함
* 쓰레드 종료 대기
- WaitForSingleObject 사용 권장
- GetExitCodeThread 는 bAutoDelete = TRUE시 문제 있음,
- CreateThread()때만 사용, 하지만 권장 안함
//======================================= //AfxBeginThread //시작 CWinThread * CSimpleTestDlg::MFC_TrdStart( bool _bAutoDel) { char *str = "MFC_TrdStart"; g_pstr[0]=str;m_pstr[0] = str; //쓰레드 생성 m_bStop=false; CWinThread *pWThd=0; // if( _bAutoDel == false){ _DbgStr(_T("MFC_TrdStart- 자동삭제=false")); //값을 바꾸기위해서는 멈춤->설정->시작 pWThd = AfxBeginThread( MFC_TrdFunc, this, 0, 0, CREATE_SUSPENDED );//멈춤 pWThd->m_bAutoDelete = FALSE; //기본값은 TRUE, 설정 pWThd->ResumeThread();//시작 }else{ _DbgStr(_T("MFC_TrdStart- 자동삭제=true")); pWThd = AfxBeginThread( MFC_TrdFunc, this, 0, 0, 0 );//<- 권장 } if( !pWThd ) return 0; m_hThread = pWThd->m_hThread; _DbgStr(_T("MFC_TrdStart- 끝=%X"), m_hThread); return pWThd; } //쓰레드 트리거 함수 UINT __cdecl CSimpleTestDlg::MFC_TrdFunc( LPVOID pParam ) { char *str = "MFC_TrdFunc";g_pstr[1]=str; CSimpleTestDlg *pClass = (CSimpleTestDlg *)pParam; pClass->MFC_TrdProc(); _DbgStr(_T("쓰레드 종료 MFC_TrdFunc"));//MFC_TrdProc()에 AfxEndThread()가 있으면 여기까지 실행이 안됨 return 1; } //실제 쓰레드 동작 int CSimpleTestDlg::MFC_TrdProc() { char *str = "MFC_TrdProc";g_pstr[2]=str; m_pstr[2] = str; while(1) { if( m_bStop ){ _DbgStr(_T("쓰레드 종료신호 MFC_TrdProc")); break; } Sleep(1000); _DbgStr(_T("쓰레드 실행중 MFC_TrdProc")); } _DbgStr(_T("쓰레드 종료 MFC_TrdProc-1-%d"), (UINT)GetTime() ); //AfxEndThread(0);//쓰레드가 강제 종료됨, 사용하면 안됨 TerminateThread()와 같음 _DbgStr(_T("쓰레드 종료 MFC_TrdProc-2-%d"), (UINT)GetTime() );// return 1; } //=============================================== //쓰레드 종료를 기다린다 //WaitForSingleObject 사용 권장 // CreadThread()로 시작한 쓰레드만 대기, AfxBeginThread() 로 시작한 쓰레드는 사용하면 안됨 int WaitThreadEndH(HANDLE _hThread, int _nWaitMilSec , LPCTSTR _sMsg, bool _bClose) { if( !_hThread ) return 0; _DbgStr(_T("WaitThreadEnd-시작-%s-%X-%d"),_sMsg, _hThread, GetTickCount() ); //bFinishThread == TRUE; // 종료를 위한 변수설정 후 3초간 대기 DWORD dwExit=0; DWORD dwRetCode = WaitForSingleObject(_hThread, _nWaitMilSec); if(dwRetCode == WAIT_OBJECT_0) // 정상종료 { _DbgStr(_T("WaitThreadEnd-정상 종료-%s-%X-%d"),_sMsg, _hThread, GetTickCount() ); } else if(dwRetCode == WAIT_TIMEOUT) // 타임아웃 { //::TerminateThread(_hThread, 0 ); _DbgStr(_T("WaitThreadEnd-강제종료-%s-%X-%d"),_sMsg, _hThread, GetTickCount() ); } if( _bClose){ //AfxBeginThread()로 생성된 쓰레드는 핸들을 닫으면 안된다. CWinThread를 delete 해야한다. //m_bAutoDelete == TRUE 일때는 호출하면 안된다 CloseHandle( _hThread ); } _DbgStr(_T("WaitThreadEnd-끝-%s-%X-%d"),_sMsg, _hThread, GetTickCount() ); return 1; } //AfxBeginThread() 로 시작한 쓰레드는 이함수로 종료해야 함 int WaitThreadEndW(CWinThread *_pWinThread, int _nWaitMilSec, LPCTSTR _sMsg) { if( !_pWinThread ) return 0; HANDLE _hThread = _pWinThread->m_hThread; _DbgStr(_T("WaitThreadEnd(W)-시작-%s-%X-%d"),_sMsg, _hThread, GetTickCount() ); //bFinishThread == TRUE; // 종료를 위한 변수설정 후 3초간 대기 bool bAutoDel = _pWinThread->m_bAutoDelete; DWORD dwExit=0; DWORD dwRetCode = WaitThreadEndH( _pWinThread->m_hThread, _nWaitMilSec, _sMsg, false );//핸들을 닫으면 안된다. //m_bAutoDelete = FALSE의 경우 스레드의 삭제 if(bAutoDel==false) { GetExitCodeThread(_pWinThread->m_hThread, &dwExit); _DbgStr(_T("WaitThreadEnd(W)-쓰레드 클래스 삭제(code=%d)", dwExit)); //if( _bClose) CloseHandle( _hThread );//하면 안됨클래스 해제시 자동 해제 된다. delete _pWinThread; } _DbgStr(_T("WaitThreadEnd(W)-끝-%s-%X-%d"),_sMsg, _hThread, GetTickCount() ); return 1; } //===================================================================
'Programming' 카테고리의 다른 글
[MFC] Serial통신 코드 (0) | 2015.09.25 |
---|---|
전처리문의 종류(#include, #define, #ifdef, ... ) (0) | 2015.09.22 |
[MFC] UpdateData(TRUE)와 UpdateData(FALSE) (0) | 2015.09.16 |
미리 컴파일된 헤더 사용을 찾을 때 건너뛰었습니다. (0) | 2015.09.14 |
[MFC] LPSTR, LPCSTR, LPTSTR, LPCTSTR , LPWSTR, LPCWSTR 의미 (0) | 2015.09.14 |