首页 > 解决方案 > std::atomic 加载和存储都需要吗?

问题描述

根据这篇文章

任何时候两个线程同时对共享变量进行操作,并且其中一个操作执行写入,两个线程都必须使用原子操作。

但是,如果较低优先级的线程是写入者,而较高优先级的线程是读取者,那么较低优先级的线程是否需要强制执行原子存储?在我看来,只有更高优先级的线程需要强制执行原子负载:

#include <atomic>

std::atomic<T*> ptr; // assume initialized to some non-null value

void highPriThreadFcn(void)
{
    T* local_ptr = ptr.load(); // need atomic load here in case lowPriThread write/store was interrupted
}

void lowPriThreadFcn(T* some_ptr)
{
    ptr = some_ptr; // do I need an atomic store here? I'd think not, as ptr is not written to by highPriThread
}

类似的问题将适用于“反向”情况(在高优先级线程中写入,从低优先级线程中读取):

void highPriThreadFcn(T* some_ptr)
{
    ptr = some_ptr; // do I need an atomic store here? I'd think not, as write to ptr cannot be interrupted
}

void lowPriThreadFcn(void)
{
    T* local_ptr = ptr.load(); // need atomic load here in case read/load was interrupted
}

标签: c++multithreadingc++11interruptatomic

解决方案


您不能对原子变量执行非原子存储或加载。API 确保没有办法尝试它。你所谓的“非原子商店”,

ptr = some_ptr;

实际上是一个顺序一致的原子存储。请参阅cppreference 上的 atomic::operator=

顺便说一句,如果您正在考虑将原子变量更改为仅以原子方式执行某些操作的非原子变量:请不要这样做。每当对同一内存位置的加载和存储“潜在并发”时,标准要求它们都是原子的。否则,行为未定义。这意味着允许编译器以破坏代码的方式“优化”。一个线程是否比另一个线程“更高”的优先级不会影响这一点。


推荐阅读