c++ - 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
}
解决方案
您不能对原子变量执行非原子存储或加载。API 确保没有办法尝试它。你所谓的“非原子商店”,
ptr = some_ptr;
实际上是一个顺序一致的原子存储。请参阅cppreference 上的 atomic::operator=。
顺便说一句,如果您正在考虑将原子变量更改为仅以原子方式执行某些操作的非原子变量:请不要这样做。每当对同一内存位置的加载和存储“潜在并发”时,标准要求它们都是原子的。否则,行为未定义。这意味着允许编译器以破坏代码的方式“优化”。一个线程是否比另一个线程“更高”的优先级不会影响这一点。
推荐阅读
- jquery - 根据按下的链接显示特定类别 | Ruby on Rails
- jquery - 元素父级的未定义 nextElementSibling
- angular - 角度 6 中的异步 authguard
- r - 在R中,如果矩阵按行选择第一个元素,如果向量选择第一个元素
- r - 如何在 R 中计算纵向患者研究中的受试者?
- c++ - Bison,在 C++ 中与 flex 交互
- python-3.x - 需要帮助使用 OpenCV 从手头皮肤上遮盖面部皮肤
- android - Firestore (Android) 中的范围查询时间戳
- javascript - Mapbox queryRenderedFeatures on load
- php - 如何为动态 sql 语句制作准备好的 mysqli 语句