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

C++ 實現類 C# lock / Java synchronized 的同步鎖封裝

     編輯:關於C++

習慣 C# lock() {} 或 Java synchronized() {} 的開發者,初用 Windows 臨界區、互斥體、事件、信號量常感不順手。本文示範如何用 RAII 模式封裝臨界區,實現語法簡潔、異常安全、自動釋放的 synchronized(mutex) { ... } 風格同步鎖。

核心設計:RAII 鎖包裝器

1. Mutex 類別:薄封裝 CRITICAL_SECTION

// Mutex.h
class Mutex {
public:
    Mutex();
    ~Mutex();
    void Lock();
    void Unlock();
private:
    CRITICAL_SECTION m_criticalSection;
};

// Mutex.cpp
#include "Mutex.h"
Mutex::Mutex() { InitializeCriticalSection(&m_criticalSection); }
Mutex::~Mutex() { DeleteCriticalSection(&m_criticalSection); }
void Mutex::Lock() { EnterCriticalSection(&m_criticalSection); }
void Mutex::Unlock() { LeaveCriticalSection(&m_criticalSection); }

2. Lock 類別:建構上鎖、解構解鎖

// Lock 定義於 Mutex.h
class Lock {
public:
    explicit Lock(Mutex& mutex);
    ~Lock();
    void SetUnlock();           // 提前解鎖標記
    operator bool() const;      // 用於 for 迴圈條件判斷
private:
    Mutex& m_mutex;
    bool   m_locked;
};

// Lock.cpp
#include "Mutex.h"
Lock::Lock(Mutex& mutex) : m_mutex(mutex), m_locked(true) {
    m_mutex.Lock();
}
Lock::~Lock() {
    if (m_locked) m_mutex.Unlock(); // 離開作用域自動解鎖
}
void Lock::SetUnlock() { m_locked = false; }
Lock::operator bool() const { return m_locked; }

3. 關鍵宏:實現 synchronized 關鍵字語法

#define synchronized(M) \
    for (Lock M##_lock = M; M##_lock; M##_lock.SetUnlock())

原理:for 迴圈初始化建立 Lock 物件 (上鎖),條件判斷 operator bool() 為真執行迴圈體,迴圈結束呼叫 SetUnlock() 將標記設為 false,下次條件判斷失效跳出,解構函數執行解鎖。無論迴圈體是否拋出異常,Lock 解構函數都會執行,保證釋放鎖。

使用範例

基本用法

Mutex _mutex;
{
    Lock lock(_mutex); // 手動 RAII
    // ... 同步區段 ...
}

synchronized 風格 (推薦)

Mutex mutex1;
int thread_count = 0;

DWORD CALLBACK thread_proc(LPVOID) {
    for (int i = 0; i < 10; ++i) {
        synchronized(mutex1) { // 整齊劃一的同步區塊
            for (char c = 'A'; c <= 'Z'; ++c) {
                printf("%c", c);
                Sleep(2);
            }
            printf("\n");
        }
    }
    thread_count--;
    return 0;
}

int main() {
    thread_count = 4;
    CreateThread(0, 0, thread_proc, 0, 0, 0);
    CreateThread(0, 0, thread_proc, 0, 0, 0);
    CreateThread(0, 0, thread_proc, 0, 0, 0);
    CreateThread(0, 0, thread_proc, 0, 0, 0);
    while (thread_count) Sleep(0);
    getchar();
    return 0;
}

執行結果

ABCDEFGHIJKLMNOPQRSTUVWXYZ
ABCDEFGHIJKLMNOPQRSTUVWXYZ
ABCDEFGHIJKLMNOPQRSTUVWXYZ
ABCDEFGHIJKLMNOPQRSTUVWXYZ
... (四條執行緒依序輸出,無交錯)

完美同步!每個執行緒完整輸出 A-Z 後釋放鎖,下一執行緒才進入。

優勢總結

  • 語法直觀:synchronized(mutex) { ... } 一目瞭然
  • 異常安全:RAII 保證鎖必釋放
  • 效能佳:臨界區為用戶態物件,無核心切換開銷
  • 可攜性:易替換為 std::mutex (C++11) 或跨平台實作

注意事項

  • 臨界區不支援跨進程同步,需跨進程請改用 Mutex (核心物件)
  • 避免在同步區塊執行耗時操作 (I/O、Sleep 等)
  • C++11 專案建議直接使用 std::lock_guard<std::mutex>
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved