首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

多執行緒程式設計(三):執行緒間通訊機制

     編輯:關於VC++

通訊必要性

主執行緒(UI)與工作者執行緒(背景運算)頻繁交換資料:主執行緒下發任務參數、工作者執行緒回報進度/結果。MFC 提供兩種主要通訊方式。

方式一:全域變數(簡單但需謹慎)

  • 同進程執行緒共享位址空間,全域變數天然可見
  • 建議加 volatile 關鍵字,防止編譯器優化導致讀取舊值
  • 複雜資料可定義結構體,傳遞指標
  • 缺點:需自行處理同步(Critical Section 等),否則有競爭風險

方式二:自訂訊息(推薦,鬆耦合)

利用 Windows 訊息機制:發送端 PostThreadMessage,接收端需有訊息迴路。工作者執行緒若衍生自 CWinThread 並覆寫 InitInstance() 返回 TRUE,即擁有訊息迴路。

完整範例:主執行緒與計算執行緒雙向通訊

場景:主執行緒選擇加數上限 (10/50/100) → 發送 WM_CALCULATE → 計算執行緒累加 → 發送 WM_DISPLAY 回主執行緒顯示結果。

1. 定義自訂訊息

#define WM_CALCULATE (WM_USER + 1)
#define WM_DISPLAY   (WM_USER + 2)

2. 主對話框類別 (CMultiThread7Dlg)

class CMultiThread7Dlg : public CDialog {
    // ...
protected:
    int m_nAddend; // 加數上限
    CCalculateThread* m_pCalcThread;
    afx_msg LRESULT OnDisplay(WPARAM wParam, LPARAM lParam);
    DECLARE_MESSAGE_MAP()
};

// 訊息映射
BEGIN_MESSAGE_MAP(CMultiThread7Dlg, CDialog)
    ON_MESSAGE(WM_DISPLAY, OnDisplay)
END_MESSAGE_MAP()

// 處理計算結果顯示
LRESULT CMultiThread7Dlg::OnDisplay(WPARAM wParam, LPARAM) {
    SetDlgItemInt(IDC_STATUS, (int)wParam, FALSE);
    return 0;
}

// 「求和」按鈕:啟動執行緒並發送參數
void CMultiThread7Dlg::OnSum() {
    m_pCalcThread = (CCalculateThread*)AfxBeginThread(RUNTIME_CLASS(CCalculateThread));
    Sleep(500); // 確保執行緒啟動完成
    m_pCalcThread->PostThreadMessage(WM_CALCULATE, m_nAddend, 0);
}

3. 計算執行緒類別 (CCalculateThread)

class CCalculateThread : public CWinThread {
    DECLARE_DYNCREATE(CCalculateThread)
protected:
    afx_msg LONG OnCalculate(UINT wParam, LONG lParam);
    DECLARE_MESSAGE_MAP()
};

BEGIN_MESSAGE_MAP(CCalculateThread, CWinThread)
    ON_THREAD_MESSAGE(WM_CALCULATE, OnCalculate) // 注意:ON_THREAD_MESSAGE
END_MESSAGE_MAP()

LONG CCalculateThread::OnCalculate(UINT wParam, LONG) {
    int sum = 0;
    for (int i = 0; i <= (int)wParam; i++) sum += i;
    Sleep(500); // 模擬耗時運算
    // 向主視窗發送結果 (需包含主對話框標頭檔)
    ::PostMessage(AfxGetMainWnd()->GetSafeHwnd(), WM_DISPLAY, sum, 0);
    return 0;
}

關鍵差異對照

特性主執行緒 (CDialog)工作者執行緒 (CWinThread)
訊息映射巨集ON_MESSAGEON_THREAD_MESSAGE
發送訊息 APIPostMessagePostThreadMessage
接收端需有訊息迴路是 (預設)是 (覆寫 InitInstance 回傳 TRUE)

進階技巧:傳遞複雜資料

  • WPARAM/LPARAM 僅能傳 32/64 位元整數
  • 需傳結構體/物件時:動態配置記憶體,指標放入 LPARAM,接收端處理完負責釋放
  • 或使用共享記憶體 + 同步物件

結語

自訂訊息機制實現執行緒間非阻塞、鬆耦合通訊,是 MFC 多執行緒開發的核心模式。搭配 CWinThread 訊息迴路,可構建清晰的生產者-消費者、主從協作架構。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved