我必须显式调用原子加载/存储吗?

问题描述 投票:0回答:2

C++11 引入了

std::atomic<>
模板库。该标准指定了
store()
load()
操作来原子地设置/获取由多个线程共享的变量。

我的问题是:赋值和访问操作也是原子的吗?

即,是:

std::atomic<bool> stop(false);
...
void thread_1_run_until_stopped()
{
    if(!stop.load())
        /* do stuff */
}

void thread_2_set_stop()
{        
    stop.store(true);
}

相当于:

void thread_1_run_until_stopped()
{
    if(!stop)
        /* do stuff */
}

void thread_2_set_stop()
{        
    stop = true;
}
c++ c++11 atomic stdatomic
2个回答
67
投票

非引用类型的赋值和访问操作也是原子的吗?

是的,他们是。

atomic<T>::operator T
atomic<T>::operator=
分别相当于
atomic<T>::load
atomic<T>::store
。所有运算符都在原子类中实现,以便它们将按照您的预期使用原子操作。

我不确定你所说的“非引用”类型是什么意思?不确定引用类型在这里有何相关性。


41
投票

您可以两者都做,但

load()
/
store()
的优点是它们允许指定内存顺序。有时这对于性能很重要,您可以指定
std::memory_order_relaxed
,而
atomic<T>::operator T
atomic<T>::operator=
将使用最安全且最慢的
std::memory_order_seq_cst
。有时,这对于代码的正确性和可读性很重要:尽管默认的
std::memory_order_seq_cst
最安全,因此最有可能是正确的,但读者并不能立即清楚您正在执行哪种操作(获取/释放/消耗) ,或者你是否正在做这样的操作(回答:这里宽松的秩序还不够吗?)。

© www.soinside.com 2019 - 2024. All rights reserved.