[C++] Atomic

缘由

在需要进行并发编程的多线程应用中,std::atomic会被广泛使用。

用法

  • load():从原子对象中加载当前值。
#include <iostream>
#include <atomic>

int main() {
    std::atomic<int> value(10);
    int loadedValue = value.load();
    std::cout << "Loaded value: " << loadedValue << std::endl;
    return 0;
}
  • store(val):将给定的值存储到原子对象中。
#include <iostream>
#include <atomic>

int main() {
    std::atomic<int> value;
    value.store(20);
    std::cout << "Stored value: " << value << std::endl;
    return 0;
}
  • exchange(val):交换原子对象中的值,并返回之前的值
#include <iostream>
#include <atomic>

int main() {
    std::atomic<int> value(30);
    int oldValue = value.exchange(40);
    std::cout << "Exchanged value: " << oldValue << std::endl;
    std::cout << "New value: " << value << std::endl;
    return 0;
}
  • compare_exchange_weak(expected, desired) 和 compare_exchange_strong(expected, desired):比较原子对象的当前值和期望值,如果相等则用新值替换当前值。
#include <iostream>
#include <atomic>

int main() {
    std::atomic<int> value(50);
    int expected = 50;
    int desired = 60;
    bool success = value.compare_exchange_weak(expected, desired);
    if (success) {
        std::cout << "Compare_exchange successful. New value: " << value << std::endl;
    } else {
        std::cout << "Compare_exchange failed. Current value: " << value << std::endl;
    }
    return 0;
}
  1. fetch_add(val) 和 fetch_sub(val):分别对原子对象的值进行加法和减法操作,并返回操作之前的值。
#include <iostream>
#include <atomic>

int main() {
    std::atomic<int> value(70);
    int oldValue = value.fetch_add(5);
    std::cout << "Old value: " << oldValue << std::endl;
    std::cout << "New value: " << value << std::endl;
    return 0;
}
  1. fetch_and(val)fetch_or(val) 和 fetch_xor(val):分别对原子对象的值进行按位与、按位或和按位异或操作,并返回操作之前的值。
#include <iostream>
#include <atomic>

int main() {
    std::atomic<int> value(15);
    int oldValue = value.fetch_and(3);
    std::cout << "Old value: " << oldValue << std::endl;
    std::cout << "New value: " << value << std::endl;
    return 0;
}

作用

  1. 保证原子性操作std::atomic 可以确保基本的内存读取、写入和其他操作是原子的,这意味着在多线程环境下,对 std::atomic 类型的对象进行操作时不会发生数据竞争,从而避免了需要额外的锁来保护这些操作的情况。
  2. 提供内存顺序保证std::atomic 也提供了内存顺序保证,确保所有线程都能够看到相同的操作顺序,从而避免了由于指令重排等导致的意外行为。
  3. 用于并发数据结构std::atomic 在开发并发数据结构时非常有用,比如并发队列、栈、哈希表等,它可以确保在多线程环境下对这些数据结构的操作是线程安全的。最好还是用lock_guard搭配mutex来处理vector等STL容器。
  4. 提高性能:相比使用锁(如互斥锁)来进行同步,std::atomic 可能在某些情况下具有更好的性能,特别是对于一些简单的操作,因为它们不涉及线程的阻塞和唤醒。

已发布

分类

来自

标签:

评论

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注