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

Win32 同步機制精通:臨界區、互斥體、信號燈、事件四大核心物件實戰

     編輯:關於C語言

為何需要同步?

多執行緒並發存取共享資料(全域變數、堆積物件、檔案、硬體)會導致競爭條件。經典範例:iCounter++ 非原子操作(讀-改-寫),兩執行緒同時執行導致更新遺失。

四大同步物件對比

MFC 同步類別統一介面

  • 建構:CCriticalSection cs; CMutex mutex(FALSE, _T("MyNamedMutex")); CSemaphore sem(0, 5); CEvent event(FALSE, TRUE); (手動/自動重設事件)。
  • 鎖定:cs.Lock() / mutex.Lock() / sem.Lock() (遞減計數) / event.Lock() (等待觸發)。
  • 解鎖:cs.Unlock() / mutex.Unlock() / sem.Unlock() (遞增計數) / event.SetEvent() (觸發) / event.ResetEvent() (重設)。
  • RAII 鎖: CSingleLock/CMultiLock 建構時自動 Lock,解構自動 Unlock,防止忘記釋放。

實戰模式

1. 保護共享資料 (Critical Section)


CCriticalSection g_cs;
int g_counter = 0;

UINT ThreadFunc(LPVOID) {
    for (int i=0; i<10000; ++i) {
        CSingleLock lock(&g_cs); // 自動 Lock/Unlock
        g_counter++;
    }
    return 0;
}

2. 單一實例應用程式 (Named Mutex)


CMutex mutex(TRUE, _T("Global\\MyAppSingletonMutex"), &bCreated);
if (!bCreated || GetLastError() == ERROR_ALREADY_EXISTS) {
    // 已有實例執行中,啟動既有視窗並退出
    return FALSE;
}
// 正常啟動...

3. 生產者-消費者佇列 (Semaphore + Critical Section)


CQueue g_queue;
CCriticalSection g_qcs;
CSemaphore g_sem(0, MAX_QUEUE); // 可用項目數
CEvent g_exitEvent;

UINT Producer(LPVOID) {
    while (!g_exitEvent.Lock(0)) { // 輪詢退出事件
        Task t = ProduceTask();
        { CSingleLock lock(&g_qcs); g_queue.push(t); }
        g_sem.Unlock(); // 通知消費者
    }
    return 0;
}

UINT Consumer(LPVOID) {
    while (true) {
        if (g_sem.Lock(INFINITE)) { // 等待項目
            if (g_exitEvent.Lock(0)) break; // 收到退出且佇列空
            Task t;
            { CSingleLock lock(&g_qcs); t = g_queue.front(); g_queue.pop(); }
            ProcessTask(t);
        }
    }
    return 0;
}

4. 非同步操作完成通知 (Event)


CEvent opComplete(FALSE, FALSE); // 自動重設,非觸發狀態啟動

// 發起非同步操作,傳遞 event 控制代碼給回呼/完成埠
StartAsyncOperation(opComplete.m_hObject);

// 工作執行緒等待完成
if (opComplete.Lock(5000)) { // 5 秒超時
    // 操作成功完成
} else {
    // 超時處理
}

進階技巧

  • 避免死鎖: 固定鎖獲取順序、使用 CMultiLock 同時獲取多鎖 (內部排序)、設定鎖超時而非無限等待。
  • 自旋鎖優化: 極短關鍵區 (幾條指令) 可用 InterlockedCompareExchange 實作自旋,避免核心轉換開銷。
  • 無鎖資料結構: 高併發場景考慮 Lock-free Queue/Stack (需深厚記憶體模型知識)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
物件核心/用戶模式跨行程適用場景MFC 封裝
Critical Section (臨界區)用戶模式 (快)否同一行程內高頻率短暫鎖定CCriticalSection
Mutex (互斥體)核心模式是 (命名)跨行程互斥、單一實例應用程式檢查CMutex
Semaphore (信號燈)核心模式是 (命名)資源池計數控制 (連線池、執行緒池)CSemaphore
Event (事件)核心模式是 (命名)執行緒間通知/等待條件 (生產者-消費者)CEvent