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

C++ std::atomic_flag 實戰:無鎖線程同步範例詳解

     編輯:C++ 入門

atomic_flag 核心特性

  • 最輕量原子類型:保證無鎖 (is_lock_free() 恆為 true)
  • 兩態標誌:set (真) / clear (假)
  • 核心操作:test_and_set() (原子讀取並置真)、clear() (原子置假)
  • 初始化:ATOMIC_FLAG_INIT 或 {} (C++20 起可直接預設構造)

自旋鎖實作範例

#include 
#include 
#include 
#include 
#include 

using namespace std;

atomic_flag lock_stream = ATOMIC_FLAG_INIT;
stringstream stream;

void append_number(int x) {
    // 自旋等待鎖釋放
    while (lock_stream.test_and_set()) {
        // busy-wait,可加 this_thread::yield() 降低 CPU 佔用
    }
    // 臨界區
    stream << "thread #" << x << '\n';
    // 釋放鎖
    lock_stream.clear();
}

int main() {
    vector threads;
    for (int i = 1; i <= 10; ++i) {
        threads.emplace_back(append_number, i);
    }
    for (auto& t : threads) t.join();
    cout << stream.str();
    return 0;
}

執行結果對比

有鎖版本 (有序輸出)

thread #1
thread #2
thread #3
thread #4
thread #5
thread #6
thread #7
thread #8
thread #9
thread #10

無鎖版本 (交錯亂序)

thread #3
thread #1
thread #5
thread #2
...
(輸出順序不可預測,甚至單行字符可能交錯)

關鍵技術細節

test_and_set() 語義

  • 原子執行:bool old = flag; flag = true; return old;
  • 返回 舊值:true 表示「鎖已被佔用」,false 表示「成功獲取鎖」
  • 典型用法:while (flag.test_and_set()) { /* wait */ }

clear() 語義

  • 原子將旗標設為 false
  • 不返回舊值,單純釋放

記憶體序 (Memory Order)

class SpinLock {
    atomic_flag flag = ATOMIC_FLAG_INIT;
public:
    void lock() { while (flag.test_and_set(memory_order_acquire)) {} }
    void unlock() { flag.clear(memory_order_release); }
};

// RAII 包裝
class SpinLockGuard {
    SpinLock& mtx;
public:
    explicit SpinLockGuard(SpinLock& m) : mtx(m) { mtx.lock(); }
    ~SpinLockGuard() { mtx.unlock(); }
};

// 使用
SpinLock mtx;
void safeFunc() {
    SpinLockGuard g(mtx);
    // 臨界區...
}

總結

atomic_flag 是 C++ 原子操作的基石,以最小原語實現互斥。理解其 test_and_set/clear 語義、記憶體序配合、自旋特性,能在高效能、低延遲場景下構建高效同步機制。但切記:自旋鎖僅適合極短臨界區,濫用會嚴重浪費 CPU 週期。

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