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

MFC 線程同步進階:跨進程資源共享的互斥量實作

     編輯:關於VC++

當多線程同步需求跨越進程邊界時,臨界區便無法滿足需求。互斥量是 Windows 提供的核心同步物件,不僅支援單一進程內線程同步,更能實現跨進程的資源共享保護。本文深入解析 MFC CMutex 類的使用機制,並對比臨界區的異同,幫助開發者選擇適合的同步策略。

互斥量與臨界區的核心差異

特性臨界區互斥量
跨進程同步不支援支援(命名互斥量)
效能開銷極低(用戶模式)較高(核心模式轉換)
等待機制自旋鎖 + 核心事件核心調度器管理
擁有權檢查無支援(僅擁有者可釋放)
遺棄處理無WAIT_ABANDONED 通知

CMutex 與 CSingleLock 的協作模式

MFC 要求使用 CSingleLock 或 CMultiLock 來管理互斥量的鎖定/釋放,這是 RAII 模式的體現:

#include "afxmt.h"

class CDataArray
{
private:
    int iArray[10];
    CMutex Mutex;  // 互斥量物件

public:
    CDataArray() {}
    ~CDataArray() {}
    void SetData(int iValue);
    void GetDataArray(int aArray[10]);
};

// 使用 CSingleLock 實現自動鎖定/釋放
void CDataArray::SetData(int iValue)
{
    CSingleLock SingleLock(&Mutex);  // 建構時自動嘗試鎖定
    SingleLock.Lock();               // 明確鎖定(建構函數預設不鎖定)
    
    for (int i = 0; i < 10; i++)
        iArray[i] = iValue;
    
    // 解構時自動呼叫 Unlock(),確保異常安全
}

void CDataArray::GetDataArray(int aArray[10])
{
    CSingleLock SingleLock(&Mutex);
    SingleLock.Lock();
    
    for (int i = 0; i < 10; i++)
        aArray[i] = iArray[i];
}

跨進程同步的關鍵:命名互斥量

實現跨進程同步需在建構互斥量時指定名稱:

// 建立命名互斥量,第二個參數為初始擁有權,第三個為名稱
CMutex Mutex(FALSE, "Global\\MySharedMutex");  

// 其他進程使用相同名稱開啟既有互斥量
CMutex Mutex(FALSE, "Global\\MySharedMutex");

注意:命名互斥量名稱建議加上 "Global\\" 前綴以確保跨會話可見性,且需處理 ERROR_ALREADY_EXISTS 以區分建立者與開啟者。

互斥量的特殊優勢:遺棄偵測

若擁有互斥量的線程意外終止未釋放,下一個等待線程將獲得 WAIT_ABANDONED 狀態碼,可藉此偵測並修復可能受損的共享資料:

CSingleLock lock(&Mutex);
DWORD result = lock.Lock(INFINITE);

if (result == WAIT_ABANDONED)
{
    // 前一擁有者異常終止,共享資料可能處於不一致狀態
    // 執行資料驗證與修復邏輯
    RepairSharedData();
}

效能考量與最佳實踐

  1. 單進程內優先使用臨界區:除非需要跨進程同步,否則臨界區效能優勢明顯
  2. 善用超時機制:避免無限期阻塞,使用 Lock(timeout) 並處理逾時情況
  3. 避免長時間持有:縮小鎖定範圍,減少其他線程/進程等待時間
  4. 正確處理遺棄狀態:跨進程場景下務必檢查 WAIT_ABANDONED

總結

互斥量是解決跨進程同步問題的標準方案。MFC 的 CMutex 搭配 CSingleLock 提供了型別安全、異常安全的介面。開發者應根據同步範圍(進程內 vs 跨進程)、效能需求、容錯要求,在臨界區與互斥量之間做出明智選擇。

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