惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

量子位
Stack Overflow Blog
Stack Overflow Blog
人人都是产品经理
人人都是产品经理
The GitHub Blog
The GitHub Blog
Engineering at Meta
Engineering at Meta
Vercel News
Vercel News
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Y
Y Combinator Blog
The Cloudflare Blog
Last Week in AI
Last Week in AI
B
Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
Tailwind CSS Blog
V
Visual Studio Blog
博客园 - 三生石上(FineUI控件)
小众软件
小众软件
Google DeepMind News
Google DeepMind News
D
DataBreaches.Net
博客园 - 司徒正美
B
Blog RSS Feed
Microsoft Azure Blog
Microsoft Azure Blog
罗磊的独立博客
Hugging Face - Blog
Hugging Face - Blog
L
LangChain Blog

博客园 - 平凡人

linux学习-目录 C++设计模式--PIMPL c++的RAII C++技术之---标准容器的值语义 blender学习系列之--CLOG Blender中的DNA QT元对象系统(Meta-Object System) Blender文档翻译:ID Datablocks(ID数据块) Blender内存管理库(bf_intern_guardedalloc) IDA\Windbg调试 - 平凡人 - 博客园 IOCTL(CTL_CODE) 内核开发速查表 Blender中的事件处理器 Blender:SDNA QT信号和槽 利用QEventLoop实现同步等待信号槽返回结果 Blender文档翻译:Operators tutorial(操作教程) Blender文档翻译:Operators Blender文档翻译:RNA Blender文档翻译-Blender库数据的通用属性
std::atomic
平凡人 · 2026-04-18 · via 博客园 - 平凡人

std::atomic 完整使用指南

std::atomic 提供了线程安全的原子操作,无需使用互斥锁。下面是详细的使用方法。

基础操作

1. 声明和初始化

#include <atomic>

// 基本类型
std::atomic<int> count{0};
std::atomic<bool> is_ready{false};
std::atomic<ConnectionState> state{ConnectionState::Disconnected};

// 指针类型
std::atomic<int*> ptr{nullptr};

// 自定义类型需要满足 TriviallyCopyable
struct Status {
    int code;
    bool success;
};
std::atomic<Status> status{Status{0, false}};

2. 基本读写操作

// 存储(写)
state.store(ConnectionState::LoggedIn);           // 默认顺序
state.store(ConnectionState::LoggedIn, std::memory_order_release);  // 指定内存序

// 加载(读)
auto s = state.load();                             // 默认顺序
auto s = state.load(std::memory_order_acquire);    // 指定内存序

// 直接赋值和转换(运算符重载)
state = ConnectionState::LoggedIn;                 // 等同于 store
ConnectionState s = state;                         // 等同于 load

3. 修改操作

std::atomic<int> counter{0};

// 后置自增/自减
int old = counter++;        // 返回旧值,然后+1
int old = counter--;        // 返回旧值,然后-1

// 前置自增/自减
int new_val = ++counter;    // +1后返回新值
int new_val = --counter;    // -1后返回新值

// 原子加/减
int old = counter.fetch_add(5);     // 返回旧值,然后+5
int old = counter.fetch_sub(3);     // 返回旧值,然后-3

// 原子位运算
int old = counter.fetch_or(0xFF);    // 按位或
int old = counter.fetch_and(0x00);   // 按位与
int old = counter.fetch_xor(0xFF);   // 按位异或

CAS(Compare-And-Swap)操作

这是最强大的原子操作,用于无锁编程。

std::atomic<int> value{10};

// compare_exchange_strong(强版本)
int expected = 10;
// 如果 value == expected,则设置 value = 20,返回 true
// 否则 expected = value,返回 false
bool success = value.compare_exchange_strong(expected, 20);

if (success) {
    // 成功修改为20
} else {
    // 修改失败,expected现在等于value的实际值
    std::cout << "实际值是: " << expected << std::endl;
}

// compare_exchange_weak(弱版本,可能虚假失败)
// 适用于循环操作
expected = 20;
while (!value.compare_exchange_weak(expected, 30)) {
    // 虚假失败或值已改变,expected已更新
    // 可以在这里添加重试逻辑
}

实际应用示例

示例1:状态机转换(最常用)

enum class ConnectionState {
    Disconnected, Connecting, Connected, LoggingIn, LoggedIn
};

class StateMachine {
private:
    std::atomic<ConnectionState> state_{ConnectionState::Disconnected};
    
public:
    // 尝试转换状态(原子操作)
    bool transition_to(ConnectionState new_state) {
        ConnectionState expected = get_state();
        
        // 检查状态转换是否合法
        switch (expected) {
            case ConnectionState::Disconnected:
                if (new_state != ConnectionState::Connecting) return false;
                break;
            case ConnectionState::Connecting:
                if (new_state != ConnectionState::Connected && 
                    new_state != ConnectionState::Disconnected) return false;
                break;
            // ... 其他状态检查
        }
        
        // 原子地执行转换
        return state_.compare_exchange_strong(expected, new_state);
    }
    
    // 更安全的方式:只在特定状态转换
    bool transition_if(ConnectionState expected, ConnectionState desired) {
        return state_.compare_exchange_strong(expected, desired);
    }
    
    ConnectionState get_state() const {
        return state_.load(std::memory_order_acquire);
    }
    
    void set_state(ConnectionState new_state) {
        state_.store(new_state, std::memory_order_release);
    }
};

示例2:线程安全的计数器

class RequestCounter {
private:
    std::atomic<uint64_t> counter_{0};
    std::atomic<uint64_t> max_concurrent_{0};
    std::atomic<uint64_t> current_{0};
    
public:
    uint64_t increment() {
        uint64_t old = current_.fetch_add(1, std::memory_order_acq_rel);
        uint64_t new_val = old + 1;
        
        // 更新最大值
        uint64_t cur_max = max_concurrent_.load(std::memory_order_relaxed);
        while (new_val > cur_max) {
            if (max_concurrent_.compare_exchange_weak(cur_max, new_val)) {
                break;
            }
        }
        
        return new_val;
    }
    
    uint64_t decrement() {
        return current_.fetch_sub(1, std::memory_order_acq_rel) - 1;
    }
    
    uint64_t get_current() const {
        return current_.load(std::memory_order_acquire);
    }
    
    uint64_t get_max() const {
        return max_concurrent_.load(std::memory_order_relaxed);
    }
};

示例3:单例模式(双重检查锁定)

class Singleton {
private:
    static std::atomic<Singleton*> instance_;
    static std::mutex mutex_;
    
    Singleton() = default;
    
public:
    static Singleton* get_instance() {
        Singleton* ptr = instance_.load(std::memory_order_acquire);
        if (!ptr) {
            std::lock_guard<std::mutex> lock(mutex_);
            ptr = instance_.load(std::memory_order_relaxed);
            if (!ptr) {
                ptr = new Singleton();
                instance_.store(ptr, std::memory_order_release);
            }
        }
        return ptr;
    }
};

std::atomic<Singleton*> Singleton::instance_{nullptr};

示例4:无锁队列的简化实现

template<typename T>
class LockFreeQueue {
private:
    struct Node {
        T data;
        std::atomic<Node*> next;
        Node(const T& d) : data(d), next(nullptr) {}
    };
    
    std::atomic<Node*> head_;
    std::atomic<Node*> tail_;
    
public:
    LockFreeQueue() {
        Node* dummy = new Node(T());
        head_.store(dummy, std::memory_order_relaxed);
        tail_.store(dummy, std::memory_order_relaxed);
    }
    
    void push(const T& value) {
        Node* new_node = new Node(value);
        
        while (true) {
            Node* tail = tail_.load(std::memory_order_acquire);
            Node* next = tail->next.load(std::memory_order_acquire);
            
            if (tail != tail_.load(std::memory_order_relaxed)) {
                continue;  // tail被修改
            }
            
            if (next != nullptr) {
                // 帮助推进tail
                tail_.compare_exchange_weak(tail, next);
                continue;
            }
            
            // 尝试链接新节点
            if (tail->next.compare_exchange_weak(next, new_node)) {
                // 成功,推进tail
                tail_.compare_exchange_weak(tail, new_node);
                break;
            }
        }
    }
    
    bool pop(T& result) {
        while (true) {
            Node* head = head_.load(std::memory_order_acquire);
            Node* tail = tail_.load(std::memory_order_acquire);
            Node* next = head->next.load(std::memory_order_acquire);
            
            if (head != head_.load(std::memory_order_relaxed)) {
                continue;
            }
            
            if (head == tail) {
                if (next == nullptr) {
                    return false;  // 队列为空
                }
                // 推进tail
                tail_.compare_exchange_weak(tail, next);
                continue;
            }
            
            // 读取数据
            result = next->data;
            
            // 移动head
            if (head_.compare_exchange_weak(head, next)) {
                delete head;
                return true;
            }
        }
    }
};

内存序(Memory Order)详解

// 1. relaxed - 最宽松,只保证原子性,不保证顺序
std::atomic<int> x{0}, y{0};
x.store(1, std::memory_order_relaxed);
y.store(2, std::memory_order_relaxed);
// 其他线程可能看到 y=2 而 x=0

// 2. release/acquire - 同步操作
// 线程A
data = 100;
ready.store(true, std::memory_order_release);  // 之前的写入都完成
// 线程B
while (!ready.load(std::memory_order_acquire)); // 确保看到release前的所有写入
assert(data == 100);  // 保证成功

// 3. seq_cst - 最严格,全局顺序一致(默认)
std::atomic<bool> x{false}, y{false};
// 线程1
x.store(true, std::memory_order_seq_cst);
// 线程2
y.store(true, std::memory_order_seq_cst);
// 线程3
while (!x.load(std::memory_order_seq_cst));
if (y.load(std::memory_order_seq_cst)) {
    // 保证看到一致顺序
}

在 Asio 网络程序中的实用模式

class NetworkClient {
private:
    std::atomic<ConnectionState> state_{ConnectionState::Disconnected};
    std::atomic<uint64_t> request_id_{0};
    std::atomic<bool> should_stop_{false};
    
public:
    // 快速状态检查(高频调用)
    bool is_ready() const {
        // 对于简单的bool检查,relaxed足够
        auto s = state_.load(std::memory_order_relaxed);
        return s == ConnectionState::LoggedIn;
    }
    
    // 安全的操作前检查
    asio::awaitable<void> send_request(const Request& req) {
        // 获取当前状态
        auto s = state_.load(std::memory_order_acquire);
        
        if (s != ConnectionState::LoggedIn) {
            // 缓存请求
            cache_request(req);
            co_return;
        }
        
        // 生成请求ID
        uint64_t id = request_id_.fetch_add(1, std::memory_order_relaxed);
        
        // 发送数据...
        co_await do_send(req);
    }
    
    // 状态转换(带重试)
    bool try_set_state(ConnectionState expected, ConnectionState desired) {
        return state_.compare_exchange_strong(expected, desired,
            std::memory_order_acq_rel);
    }
    
    // 优雅关闭
    void shutdown() {
        should_stop_.store(true, std::memory_order_release);
    }
    
    bool should_stop() const {
        return should_stop_.load(std::memory_order_acquire);
    }
};

性能提示

  1. 默认使用 seq_cst 是最安全的,但性能开销最大
  2. 计数器使用 relaxedcounter.fetch_add(1, std::memory_order_relaxed)
  3. 标志位使用 release/acquire:生产者-消费者模式
  4. 避免在循环中使用 seq_cst,除非真的需要全局顺序
  5. 优先使用 compare_exchange_weak 在循环中(可能虚假失败但性能更好)

这样你就可以在多线程环境中安全地管理连接状态了!

std::atomicC++11 标准 正式引入的。这意味着,如果你的编译器支持 C++11(如 GCC 4.8+、Clang 3.6+、MSVC 2015+),就可以直接使用它。

各标准版本的支持演进

标准版本 主要更新内容
C++11 首次引入 std::atomic 模板,支持布尔、整型和指针类型
C++20 增加对 floatdouble 等浮点类型的特化支持;增加对 std::shared_ptr<T>std::weak_ptr<T> 的特化支持;默认构造函数变为 constexpr
C++23 提供 _Atomic(T) 宏以兼容 C 的 stdatomic.h 头文件

兼容性说明

  • C++11 及以上:可直接使用 #include <atomic>std::atomic<T>,这是推荐的方式
  • C++98/03:标准库中没有 std::atomic,如需使用原子操作,只能借助编译器内置函数(如 GCC 的 __sync_*__atomic_* 系列)或平台相关 API(如 Windows 的 InterlockedExchange),或使用第三方库如 Boost.Atomic 作为过渡方案

类型限制提醒

std::atomic<T> 要求 T 满足 可平凡复制(TriviallyCopyable)的条件。像 std::stringstd::vector 这类类型不能直接使用,这在选择状态枚举类型时没有问题,但如果想原子化更大的结构体,需要先确认其满足该条件。

简单来说,只要项目配置在 C++11 或更高标准,就可以放心使用 std::atomic 来管理线程间的状态同步。