[MFC] Thread

시리얼 통신을 테스트 할 수 있는 프로그램을 만들었다.
음.. 핵심 코드는 오리가 만들어 놓은 것을 사용하였다.
여기서 Thread 부분이 제일 이해가 안가서 이 부분을 공부 할 겸 정리 하고자 한다. ㅎ
이론적인 부분은 책과 MSDN을 참고한 내용 정리 + 실제 코드 부분을 인용해서... 나름 정리 해 보려 한다. ㅎ
여기서 MSDN은 별로 안 봤다 _-;;;

틀린 부분은 언제든지 수정 바람. !!

↓ 참고한 책 !
Visual C++ 6 완벽가이드 2nd Edition
김용성 지음 / 영진.com(영진닷컴)
나의 점수 : ★★★★

Visual studio 2008을 쓰고있는데,
이 책은 6.0 기반이다..
출판 된지 오래됐으니까. ㅎ
2008이 절판되서 안나와서 ㅠ 못구하고있다.;

큰 차이점은 못 느끼겠다;ㅎ
아직 잘 몰라서 그런가_-;
그래서 이래저래 보면서 참고하고있는 책이다.

------------------------------------------------------------------------------------------------------------------
1. 프로세스와 스레드
    + 프로세스 : 프로그램이 실행되어 동작하고 있는 상태 (task 라고도 함). 인스턴스라고도 함. 
                     인스턴스 - 프로그램이 메모리에 로딩 되어 있는 상태
                     프로세스 - 메모리 상에서 실행되고 있는 상태
    + 스레드 : 하나의 프로그램을 여러 개의 프로세스로 나누어 동시에 실행.
                    ex) 한글 프로그램에서 맞춤법 검사 기능 : 
                                            하나의 프로세스로 구현하면 맞춤법 검사 하는 동안은 문서 작성 x
                                            맞춤법 검사를 독립된 스레드로 구현 -> 문서 작성 ok, 맞춤법 검사 ok
                    ex) 프린트 기능을 독립 스레드로 구현 : 프린트 하면서 다른 작업 ok
                    ex) 멀티미디어 플레이 : 
                                             멀티미디어 데이터를 데이터량이 많으므로 MPEG, DIVX, MP3 등과 같은 형태로 저장
                                             데이터 읽고, 압축 풀고, 화면이나 사운드 카드로 출력 하는 것을 각 스레드로 구현 
                                                   -> 구현이 단순해 지고, 프로그램의 성능도 향상. 
    + 멀티 태스킹은 OS가 알아서 해주지만, 멀티 스레드는 프로그래머가 잘 구현해야한다. 
        멀티 스레드를 굳이 안써도 되지만, 사용하면 유용하다. 위의 예처럼.... 버벅 거리는 일이 줄어들겠지? 아마도 _-;

2. 멀티 스레드 프로그래밍
    ㄱ. 작업자 스레드(Worker thread) : 어떤 단일 작업을 수행하기 위해 사용 하는 것.  


        AfxBeginThread 함수를 호출


  CWinThread* m_hThreadCom;

  m_hThreadCom = ::AfxBeginThread(ThreadCom,              // 스레드 구동 시킬 함수 이름
                                 this,                                                   // 스레드 함수에 넘겨줄 매개변수
                                 THREAD_PRIORITY_ABOVE_NORMAL,// 스레드 실행 우선순위
                                 0,                                                       // 스레드가 사용할 스택의 최대 크기
                                                                                           // 0은 1MB 까지 스택 사용
                                 CREATE_SUSPENDED,                       // 스레드 생성 후 바로 실행(0),
                                                                                           // Resume Thread 함수호출까지 wait  
                                 NULL);                                               // 보안 설정


        스레드 구동할 함수 : ThreadCom - 직접 구현


unsigned int ThreadCom(LPVOID dParameter)
{
    CSerialCom* pObj = (CSerialCom*)dParameter;

    OVERLAPPED comReader;
    BYTE szBuff[BUFFER_SIZE];
    DWORD dwIndex,dwRead = 0; // bytes actually read 
    DWORD dwCommEvent;

    
    ZeroMemory(&comReader, sizeof(comReader));
    ZeroMemory(&szBuff, sizeof(szBuff));


    //Creating overlapped event handle
    comReader.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    SetCommMask(pObj->m_hComm, EV_RXCHAR);

    while(pObj->m_bConnect)
    {
        if(pObj->m_bWait == FALSE)
        {
            dwCommEvent = 0;

            WaitCommEvent(pObj->m_hComm, &dwCommEvent, &comReader);
            if(((dwCommEvent & EV_RXCHAR) == EV_RXCHAR)
                /*WaitForSingleObject(comReader.hEvent, INFINITE) == WAIT_OBJECT_0*/)
            {
                ZeroMemory(szBuff, sizeof(szBuff));

                do
                {
                    dwRead = pObj->ReadComm(szBuff, sizeof(szBuff));
                    if(dwRead > 0)
                    {
                        for(dwIndex = 0; dwIndex < dwRead; dwIndex++)
                        {
                            pObj->m_byBuffer[pObj->m_uiBufferCnt++] = (BYTE)szBuff[dwIndex];
                        }

                        pObj->m_pOwner->PostMessage(pObj->m_uiEvt, dwRead, 0);
                    }
                } while(dwRead > 0);
            }
           Sleep(20);                                                            // 스레드 휴식 (1초 = 1000)
        }
        Sleep(0);                                                                // 우선순위가 높거나 같은 다른 스레드에게 cpu사용권 넘어감
                                                                                    // 기다리고있는 스레드 없으면 아무 일 x
                                                                                    // starvation 발생 하지 않도록 하기 위한 방법
   }

    CloseHandle(comReader.hEvent);
    CloseHandle(pObj->m_hComm);

    pObj->m_hThreadCom = NULL;

    return 0;
}

        
        스레드 멈추기

  m_hThreadCom->SuspendThread();            // 스레드 동작 stop
 
  m_hThreadCom->ResumeThread();             // 스레드 다시 실행

        스레드 종료
    : 스레드는 자체적으로 메시지 큐를 가지고 있기 때문에 "WM_QUIT" 메시지를 날리면 스레드가 종료

  TerminateThread 함수 호출 -> 강제 종료 -> 좋은 방법 x

    TerminateThread(m_hThreadCom->m_hThread, 0);
    
    : 전체 소스 중에서 이 함수 부분만 가지고 온 것임.
  외부에서 flag를 설정하여 안전하게 종료

     static BOOL bContinue = FALSE;            // FALSE = 종료, TRUE = 실행  
   
     CWindThread *pThread = ::AfxBeginThread(ThreadFunc, &bCountinue);
  완전히 종료 되었는지 확인 필요 - 이후 작업 처리
   WaitForSingleObject 함수 호출 - m_hThreadCom이 가리키는 스레드가 종료 될 때 까지 프로세스 실행 stop
    
    if(::WaitForSingleObject(m_hThreadCom->m_hThread, 0) == WAIT_TIMEOUT)
    {
        if(::WaitForSingleObject(m_hThreadCom->m_hThread, 2000) == WAIT_TIMEOUT)        
                                                                        // 2초 동안 기다려 보고 종료 됐으면, 강제로 종료 함

      TerminateThread(m_hThreadCom->m_hThread, 0);
            m_hThreadCom = NULL;
            CloseHandle(m_hComm);
                    
            m_hComm = INVALID_HANDLE_VALUE;                    
         }
    }
          


-_-... 대충 이 정도 밖에 모르겠다...;
완성본 소스와.. 디테일한 설명은..  언젠가 또.. 한 번 정리를 -_-;

by reum | 2009/02/16 14:21 | Study | 트랙백 | 핑백(1) | 덧글(4)

트랙백 주소 : http://fruitamy.egloos.com/tb/4152329
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]
Linked at Thread (Worker.. at 2012/04/10 00:39

... ntation of Threads in MFC [MFC] Worker Thread and User Interface Thread by Mhspecial [MFC] Thread by reum Introduction to MFC Thread Programming by nphanindrakumar by Skotlex in General ... more

Commented by op at 2009/04/09 20:33
우와! 정말 정리 잘하셨어요^^
Commented by grayowl at 2009/06/03 11:19
Thread 종료 방법을 찾아서 해매다가, 여기서 도움 받고 갑니다. 좋은 정보 감사합니다.
그나저나 부럽네요 2005 사용..
저는 아직도 vc6++ 인데 ㅜ.ㅜ;
Commented by CalmToT at 2009/11/13 10:32
우왓?! 정리 잘하셨네요 잘 보고 갑니다 ㅋㄷㅋ
Commented by 반갑습니다 at 2010/09/01 01:29
외부에서 flag를 설정하여 안전하게 종료 부분에서 CWinThread가 CWindThread로 잘못 표기되었네요

:         :

:

비공개 덧글

<< 이전 페이지     다음 페이지 >>