Thread 비교, 사용법

Code 2012. 12. 23. 21:57

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
Posted by codens