對於Worker執行緒,終止執行緒可以使用執行緒的退出碼作為傳回值從執行緒函數返回。
  對於UI執行緒,因為有消息迴圈,需要發送一個WM_QUIT消息到執行緒的訊息佇列,當執行緒接收到WM_QUIT消息時退出消息迴圈。因此,結束執行緒可以線上程內部調用SDK的PostQuitMessage函數,發送WM_QUIT消息。
  PostQuitMessage函數的定義如下:
  void PostQuitMessage(int nExitCode);
  其中:
  nExitCode:執行緒的退出碼。
  MFC還提供了AfxEndThread函數,Worker執行緒和UI執行緒都可以通過線上程內部調用AfxEndThread函數結束執行緒。
  AfxEndThread函數的定義如下:
  void AfxEndThread(UINT nExitCode, BOOL bDelete = TRUE);
  其中:
  nExitCode:執行緒的退出碼。
  在MFC的THRDCORE.CPP中,AfxEndThread函數的相關代碼如下:
  // THRDCORE.CPP
  void AFXAPI AfxEndThread(UINT nExitCode, BOOL bDelete)
  {
  // remove current CWinThread object from memory
  AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
  CWinThread* pThread = pState->m_pCurrentWinThread;
  if (pThread != Null)
  {
  ASSERT_VALID(pThread);
  ASSERT(pThread != AfxGetApp());
  // cleanup OLE if required
  if (pThread->m_lpfnOleTermOrFreeLib != Null)
  (*pThread->m_lpfnOleTermOrFreeLib)(TRUE, FALSE);
  if (bDelete)
  pThread->Delete();
  pState->m_pCurrentWinThread = Null;
  }
  // allow cleanup of any thread local objects
  AfxTermThread();
  // allow C-runtime to cleanup, and exit the thread
  _endthreadex(nExitCode);
  }
  從MFC代碼中可以看出,AfxEndThread函數通過調用_endthreadex函數終止執行緒。此外,函數還進行釋放執行緒的堆疊、刪除線程物件等工作。
  如果在其它執行緒中終止該執行緒,必須採用執行緒通信的方法實現。其中一種簡單的方法是建立一個變數,讓執行緒監視該變數,當該變數為某個值時,則終止執行緒。
  (1)創建1個基於對話方塊的應用程式,名稱為Demo。
  (2)在IDD_DEMO_DIALOG對話方塊資源中添加控制項,如表所示。
  類型
  ID
  標題
  Static
  IDC_STATIC
  資料:
  Edit
  IDC_DATA  
  Button
  IDC_BEGIN_THREAD
  啟動執行緒
  Button
  IDC_END_THREAD
  終止執行緒


(3)在檔中定義執行緒傳遞參數的資料結構,代碼如下:
  // DemoDlg.h
  typedef struct THREAD_PARAM
  {
  HWND hWnd;
  int nData;
  BOOL bExit;
  }_THREAD_PARAM;
  (4)在CDemoDlg類中添加成員變數,代碼如下:
  // DemoDlg.h
  protected:
  CWinThread* m_pThread;
  THREAD_PARAM m_ThreadParam;
  (5)在CDemoDlg类的构造函数中初始化成员变量,代码如下:
  // DemoDlg.cpp
  CDemoDlg::CDemoDlg(CWnd* pParent /*=NULL*/)
  : CDialog(CDemoDlg::IDD, pParent)
  {
  // ...
  m_pThread = NULL;
  m_ThreadParam.nData = 0;
  }
  (6)在CDemoDlg类的OnInitDialog函数中添加如下代码:
  // DemoDlg.cpp  
   BOOL CDemoDlg::OnInitDialog()
  {
  CDialog::OnInitDialog();
  // …
  SetDlgItemInt(IDC_DATA, m_nData);
  return TRUE;
  }
  (7)在文件中定义线程消息,代码如下:
  // DemoDlg.h
  #define WM_THREADMSG WM_USER+1
  (8)在文件中定义线程函数,代码如下:
  // DemoDlg.h
  UINT ThreadProc(LPVOID pParam);
  // DemoDlg.cpp
  UINT ThreadProc(LPVOID pParam)
  {
  //线程参数
  THREAD_PARAM* pThreadParam = (THREAD_PARAM*)pParam;
  while (!pThreadParam->bExit)
  {
  Sleep(100);
  pThreadParam->nData++;
  //向主线程窗口发送消息
  ::PostMessage(pThreadParam->hWnd, WM_THREADMSG, 0, 0);
  }
  return 0;
  }
  (9)在CDemoDlg类中分别为Button控件添加BN_CLICKED添加消息处理函数,代码如下:
  // DemoDlg.cpp
  void CDemoDlg::OnBeginThread()
  {
  if (m_pThread != NULL)
  {
  AfxMessageBox(_T("线程已经启动。"));
  return;
  }
  m_ThreadParam.hWnd = m_hWnd;
  m_ThreadParam.bExit = FALSE;
  //啟動執行緒,初始為掛起狀態
  m_pThread = AfxBeginThread(ThreadProc, &m_ThreadParam,
  THREAD_PRIORITY_ABOVE_NORMAL, 0, CREATE_SUSPENDED);
  //執行緒結束時不自動刪除
  m_pThread->m_bAutoDelete = FALSE;
  //恢復執行緒運行
  m_pThread->ResumeThread();
  }
  void CDemoDlg::OnEndThread()
  {
  if (m_pThread == Null)
  {
  AfxMessageBox(_T("執行緒已經終止。"));
  return;
  }
  m_ThreadParam.bExit = TRUE;
  //等待中的執行緒結束
  ::WaitForSingleObject(m_pThread->m_hThread, INFINITE);
  delete m_pThread;
  m_pThread = Null;
  }
  (10)在CDemoDlg類中添加自訂消息處理函數,代碼如下:
  // DemoDlg.h
  afx_msg LRESULT OnMsgFunc();
  // DemoDlg.cpp
  BEGIN_MESSAGE_MAP(CDemoDlg, CDialog)
  ON_MESSAGE(WM_THREADMSG, OnMsgFunc)
  END_MESSAGE_MAP()
  LRESULT CDemoDlg::OnMsgFunc()
  {
  SetDlgItemInt(IDC_DATA, m_ThreadParam.nData);
  return 1;  
   }

源址: HTTP://www.examda.com/ncre2/cpp/zonghe/20090612/084854957.html
創作者介紹
創作者 shadow 的頭像
shadow

資訊園

shadow 發表在 痞客邦 留言(0) 人氣()