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

Windows 核心編程:用戶模式線程同步機制全解析

     編輯:關於C語言

為什麼需要同步?

  • 多線程並發訪問共享資源 → 數據競爭、不一致。
  • 線程間協作:任務完成通知、生產者-消費者模型。

用戶模式同步四大支柱

1. 原子操作

適用於單個整數/指針的無鎖同步,指令級原子性,無內核切換開銷。

核心 API 族

// 原子加/減並返回舊值
LONG InterlockedExchangeAdd(LONG volatile* Addend, LONG Increment);
LONGLONG InterlockedExchangeAdd64(LONGLONG volatile* Addend, LONGLONG Increment);

// 原子交換並返回舊值
LONG InterlockedExchange(LONG volatile* Target, LONG Value);
PVOID InterlockedExchangePointer(PVOID volatile* Target, PVOID Value);

// 原子比較交換 (CAS)
LONG InterlockedCompareExchange(LONG volatile* Destination, LONG Exchange, LONG Comparand);

自旋鎖實現範例

volatile LONG lock = 0;
void EnterSpinLock() {
    while (InterlockedExchange(&lock, 1) == 1) {
        Sleep(0); // 釋放時間片,避免忙等佔用 CPU
    }
}
void LeaveSpinLock() {
    InterlockedExchange(&lock, 0);
}

適用場景:極短臨界區、多核系統、無阻塞需求。禁用於單核、長耗時操作。

2. 臨界區

進程內互斥鎖,用戶模式快速路徑,爭用時自動轉入內核等待。

API

CRITICAL_SECTION cs;
InitializeCriticalSection(&cs); // 或 InitializeCriticalSectionAndSpinCount(&cs, 4000)
EnterCriticalSection(&cs);
// 訪問共享資源
LeaveCriticalSection(&cs);
DeleteCriticalSection(&cs); // 進程結束前調用

進階:嘗試進入

if (TryEnterCriticalSection(&cs)) {
    // 獲得鎖
    LeaveCriticalSection(&cs);
} else {
    // 做其他事,稍後重試
}

優點:無爭用時極快(僅原子操作)、支援遞歸進入。缺點:無超時參數、不可跨進程。

3. 讀寫鎖

區分共享讀與獨占寫,提升讀多寫少場景並發度。

API (Vista+)

SRWLOCK srw = SRWLOCK_INIT;
AcquireSRWLockShared(&srw);   // 讀鎖
ReleaseSRWLockShared(&srw);
AcquireSRWLockExclusive(&srw); // 寫鎖
ReleaseSRWLockExclusive(&srw);

條件變量配合

CONDITION_VARIABLE cv = CONDITION_VARIABLE_INIT;
// 等待條件(自動釋放鎖並阻塞)
SleepConditionVariableSRW(&cv, &srw, INFINITE, CONDITION_VARIABLE_LOCKMODE_SHARED);
// 唤醒單個/所有等待者
WakeConditionVariable(&cv);
WakeAllConditionVariable(&cv);

經典模式:生產者持有獨占鎖修改隊列 → WakeAllConditionVariable;消費者持有共享鎖 SleepConditionVariableSRW 等待數據。

4. 線程池與併發運行時 (現代替代)

Windows Vista+ 推薦使用 Threadpool API、Concurrency Runtime (PPL)、C++17 std::mutex/std::shared_mutex,封裝了上述底層機制,更安全、可移植。

選型決策樹

共享資料類型
├─ 單個整數/指針 → Interlocked 族
└─ 復雜結構/多變量
    ├─ 僅進程內、高性能、短臨界區 → Critical Section
    ├─ 讀多寫少、需共享讀 → SRWLock + Condition Variable
    ├─ 跨進程同步 → Mutex / Semaphore / Event (內核對象)
    └─ 現代 C++ 專案 → std::mutex / shared_mutex + condition_variable

最佳實踐清單

  • ✅ 鎖的粒度盡可能細,但避免過度細碎導致死鎖/性能損耗。
  • ✅ 始終用 RAII 封裝 (std::lock_guard/unique_lock),防止異常導致未解鎖。
  • ✅ 固定鎖獲取順序,預防死鎖。
  • ✅ 避免在持有鎖時調用外部代碼/發送消息/阻塞 I/O。
  • ✅ 使用 InitializeCriticalSectionAndSpinCount 設置旋轉計數(多核建議 4000)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved