| 類型 | UI 執行緒 | 工作執行緒 |
| 訊息泵 | 有 (建立視窗需訊息循環) | 無 (較輕量) |
| 典型用途 | 獨立視窗、模態對話框、ActiveX 控制項容器 | 計算、檔案 I/O、網路通訊、資料庫操作 |
| 建立方式 | 衍生 CWinThread,覆寫 InitInstance | AfxBeginThread 全域函式或靜態成員函式 |
| 生命週期 | 視窗銷毀時結束 (ExitInstance) | 函式返回即結束 |
UI 執行緒實作範本
class CGUIThread : public CWinThread {
DECLARE_DYNCREATE(CGUIThread)
protected:
CGUIThread() { m_bAutoDelete = TRUE; } // 自動刪除
virtual BOOL InitInstance() {
CMyWnd* pWnd = new CMyWnd;
if (!pWnd->CreateEx(0, AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW),
_T("UI Thread Window"), WS_OVERLAPPEDWINDOW|WS_VISIBLE,
0,0,400,300, NULL, NULL)) return FALSE;
m_pMainWnd = pWnd;
return TRUE;
}
virtual int ExitInstance() {
// 清理資源
return CWinThread::ExitInstance();
}
};
IMPLEMENT_DYNCREATE(CGUIThread, CWinThread)
// 啟動
CGUIThread* pThread = (CGUIThread*)AfxBeginThread(RUNTIME_CLASS(CGUIThread), THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);
pThread->ResumeThread();
工作執行緒實作範本
UINT __cdecl WorkerThreadFunc(LPVOID pParam) {
CMyData* pData = (CMyData*)pParam;
for (int i=0; i<100; ++i) {
if (pData->bCancel) break;
// 執行工作...
pData->progress = i;
::PostMessage(pData->hWnd, WM_USER_PROGRESS, i, 0); // 通知 UI
Sleep(50);
}
return 0;
}
// 啟動
CMyData data; data.hWnd = m_hWnd;
AfxBeginThread(WorkerThreadFunc, &data, THREAD_PRIORITY_NORMAL, 0, 0, NULL);
關鍵同步與通訊機制
- 訊息傳遞 (推薦):
PostMessage/SendMessage 到主視窗,避免直接存取 UI 控制項(非執行緒安全)。
- 共享資料保護:
CCriticalSection (輕量、行程內)、CMutex (跨行程)、CSemaphore (資源計數)、CEvent (信號通知)。
- MFC 同步類別為 Win32 API 薄封裝,建構/解構自動處理核心物件生命週期。
常見錯誤與最佳實踐
- UI 執行緒未建立訊息泵: 必須在
InitInstance 建立視窗並指派 m_pMainWnd,MFC 執行緒訊息泵才會啟動。
- 工作執行緒直接操作 UI: 導致競爭、死鎖、存取違規。**嚴禁**。
- 執行緒函式拋出未捕獲例外: 導致整行程崩潰。工作函式頂層用
try/catch(...) 捕獲並記錄。
- 傳遞堆疊區域指標給執行緒: 呼叫者函式返回前執行緒仍在用 → 未定義行為。**改用堆積配置或共享結構體加參考計數/智慧指標。**
- 關閉應用程式時強制結束執行緒:
TerminateThread 極危險(鎖未釋放、資源洩漏)。**改用旗標/事件通知執行緒自行退出**,主執行緒 WaitForSingleObject 等待。
- 上一篇文章: Win32 行程控制實戰:CreateProcess 參數詳解與常見應用模式
- 下一篇文章: Win32 同步機制精通:臨界區、互斥體、信號燈、事件四大核心物件實戰
Copyright ©
程式碼之家 All Rights Reserved