본문 바로가기

개발/mfc

mfc thread 만들기 - vs 2010, sample source

반응형

mfc 에서 멀티타스크를 하기 위해서는 OnTimer 를 쓰기도 하지만,

스레드를 쓰기도 한다.

 

방법.

1. 해더에 변수 추가

2. 스래드 시작 함수 부르기

3. 스레드 시작 함수

4. 실행될 스레드 함수

5. 스레드 잠시 멈춤 함수

6. 스레드 끝내기 함수

 

스레드 잠시 멈춤 함수부르기와 끝내기 함수 부르기는  따로 만들어 주셔야 합니다.

여기서는 귀찮아서 그냥 만들고 10 초뒤 잠시 멈추고 10초뒤 재시작, 10초뒤 끝

으로 하였읍니다.

 

코드는 VIsual Studio 2010 으로 하였읍니다.

 

 

=======================================

1. 해더에 변수 추가

아래 Dialog 이름 DLG_Main 은 다른것으로 바꾸어도 됩니다.


// CDlg_Main dialog
class CDlg_Main : public CDialog
{
// Construction
public:
  CDlg_Main(CWnd* pParent = NULL);  // standard constructor
  void ShowServerInfo(string sValue);

// Dialog Data
  enum { IDD = IDD_Main_DIALOG };

  protected:
  virtual void DoDataExchange(CDataExchange* pDX);  // DDX/DDV support
// 생략
///////////  Thread Task
  BOOL m_isThreadTask;      // start 여부
  CWinThread* m_pThreadTask;    // 스레드 함수 포인터
  t_ThreadState m_State_ThreadTask;  // 스레드 상태
  static UINT threadTask(LPVOID param);  // 실행 될 스레드
  void threadTask_start();    // 스레드 시작(재시작)시키는 함수
  void threadTask_pause();    // 스레드 잠시 멈추는 함수
  void threadTask_stop();      // 스레드 중단 함수
  void thTask_do();        // 스레드에서 부르는 함수
// 생략
};

 

 

 

=======================================

2. 스래드 시작 함수 부르기

다이알로그 시작 함수 CDlg_Main::OnInitDialog() 에서 부른든 아니면 따로 만들어 부른든 하시면 됩니다.

/////////////////////////////////////////////////////////
BOOL CDlg_Main::OnInitDialog()
{
  CDialog::OnInitDialog();
//  CEdit *eb1 ;
  int nCount = 0;
  CString  dName;
  // Add "About..." menu item to system menu.
  // IDM_ABOUTBOX must be in the system command range.
  ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
  ASSERT(IDM_ABOUTBOX < 0xF000);

  CMenu* pSysMenu = GetSystemMenu(FALSE);
  if (pSysMenu != NULL)
  {
    CString strAboutMenu;
    strAboutMenu.LoadString(IDS_ABOUTBOX);
    if (!strAboutMenu.IsEmpty())
    {
      pSysMenu->AppendMenu(MF_SEPARATOR);
      pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
    }
  }

  // Set the icon for this dialog.  The framework does this automatically
  //  when the application's main window is not a dialog
  SetIcon(m_hIcon, TRUE);      // Set big icon
  SetIcon(m_hIcon, FALSE);    // Set small icon
// 생략
/////////////////////////////////////////////////////////
  m_pThreadTask=NULL; m_State_ThreadTask=STOP;
  threadTask_start(); // 주 타스크 쓰레드 시작 하기 
  Sleep(10000); threadTask_pause();    // 잠시 멈춤
  Sleep(10000); threadTask_start();    // 재시작
  Sleep(10000); threadTask_stop();    // 끝
/////////////////////////////////////////////////////////
// 생략
  return TRUE;  // return TRUE  unless you set the focus to a control
}

 

 

 

 

=======================================

3. 스레드 시작 함수

enum t_ThreadState {
  STOP = 0,
  RUN  = 1,
  PAUSE = 2
};

void CDlg_Main::threadTask_start(){
  if(m_pThreadTask == NULL){    // 스레드가 시작 되지 않았으면
    m_pThreadTask=AfxBeginThread(threadTask, this);  // 스레드 threadTask 를 시작해 m_pThreadTask에 저장
    if(m_pThreadTask==NULL){    // 안만들어 지면 에러
      AfxMessageBox(_T("Err: threadTask Start"));
    }
    
    m_pThreadTask->m_bAutoDelete = FALSE;    // 자동 삭재 방지
    m_State_ThreadTask = RUN;    //
    AfxMessageBox(_T("threadTask Started"));  // 상태를 RUN 으로 변수에 저장
  } else {    // 스레드가 시작되었으면
    if(m_State_ThreadTask==PAUSE)    // 잠시 멈춤이면,
    {
      m_pThreadTask->ResumeThread();    // 다시 진행
      m_State_ThreadTask = RUN;  //
      AfxMessageBox(_T("threadTask ReStarted"));
    }
  }
}

 

=======================================

4. 실행될 스레드 함수

void CDlg_Main::thTask_do(){    //  스레드에서 부르는 함수 ,  thread  무한 루프 도는데
   AfxMessageBox(_T("Run"));    Sleep(1800); // 1.8 초 자빠져 자기
}

UINT CDlg_Main::threadTask(LPVOID param){    // thread 처리 루틴
  CDlg_Main* pDlg = (CDlg_Main*)AfxGetApp()->m_pMainWnd;

  while(pDlg->m_State_ThreadTask == RUN){
    pDlg->thTask_do();    // 필요에 따라 다른 함수 부르기
  }
  return 0;
}

 

=======================================

5. 스레드 잠시 멈춤 함수

void CDlg_Main::threadTask_pause(){
  if(m_pThreadTask == NULL){
    AfxMessageBox(_T("Err: threadTask Pause"));
  } else {
    m_pThreadTask->SuspendThread();
    m_State_ThreadTask = PAUSE;    //
    AfxMessageBox(_T("threadTask Pause"));
  }
}

 

=======================================

6. 스레드 끝내기 함수

 

void CDlg_Main::threadTask_stop(){
  if(m_pThreadTask == NULL){
    AfxMessageBox(_T("Err: threadTask Stop"));
  } else {
    m_pThreadTask->SuspendThread();

    DWORD dwResult;
    ::GetExitCodeThread(m_pThreadTask->m_hThread, &dwResult);

    delete m_pThreadTask;
    m_pThreadTask = NULL;

    m_State_ThreadTask = STOP;    //
    AfxMessageBox(_T("threadTask Stop"));
  }
}

 

 

=======================================

 

 

 

반응형