我必须明确调用原子加载/存储吗?
Posted
技术标签:
【中文标题】我必须明确调用原子加载/存储吗?【英文标题】:Must I call atomic load/store explicitly? 【发布时间】:2013-09-21 22:40:43 【问题描述】: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;
【问题讨论】:
正如 Serge 所说,stop.load(std::memory_order_relaxed)
和 stop.store(true, std::memory_order_relaxed);
在这里应该没问题。您只需要立即看到商店,relaxed
仍然保证这一点。只有在需要同步其他数据时,才需要更强的排序。
【参考方案1】:
非引用类型的赋值和访问操作也是原子的吗?
是的,他们是。 atomic<T>::operator T
和 atomic<T>::operator=
分别相当于 atomic<T>::load
和 atomic<T>::store
。所有操作符都在原子类中实现,因此它们将使用您所期望的原子操作。
我不确定您所说的“非引用”类型是什么意思?不确定引用类型在此处的相关性。
【讨论】:
相当于不带一致性控制参数的load和store版本,即 @user1131467 - 谢谢。删除了“参考”,好吧,参考;-) @BenVoigt 这意味着使用最严格的内存顺序:std::memory_order_seq_cst
。这可以防止一个人在脚上开枪,但可能是过早的悲观。【参考方案2】:
两者都可以,但load()
/store()
的优点是它们允许指定内存顺序。有时对性能很重要,您可以指定std::memory_order_relaxed
,而atomic<T>::operator T
和atomic<T>::operator=
将使用最安全和最慢的std::memory_order_seq_cst
。有时它对代码的正确性和可读性很重要:尽管默认 std::memory_order_seq_cst
最安全,因此最有可能是正确的,但读者并不能立即清楚您正在执行哪种操作(获取/释放/使用) ,或者你是否正在做这样的操作(回答:这里的放松顺序还不够吗?)。
【讨论】:
以上是关于我必须明确调用原子加载/存储吗?的主要内容,如果未能解决你的问题,请参考以下文章
Azure 数据工厂中的 Azure Synapse 存储过程:是同步调用吗?