[英]Is an atomic object unsafe in any context where a plain object is safe?
我的问题很简单:是否有任何并行算法使用一个简单类型T
的对象是合法和安全的(定义明确,保证工作),而使用std::atomic<T>
对象会导致未指定或未定义的行为? 换句话说,非原子类型是否有可能提供比原子类型更强的保证?
当它们对常规对象有效时,所有内存可见性保证对原子对象有效吗?
[这意味着编译器可以将(宽松的)原子操作和非原子操作一视同仁,从而简化中间表示。]
如果是,那是否可以正式证明?
当然,类型T
使得std::atomic<T>
不是std::atomic
的有效特化不算数。
与atomic
等价物相比,没有非原子值具有更强保证的情况。
我能想到的唯一不好的模式是,当开发人员错误地假设如果数据结构的所有成员都是单独的线程安全的,那么整个数据结构就被假定为线程安全的。 这不是一个正确的假设。
考虑以下假设:
class Volume
{
atomic<int> _width;
atomic<int> _height;
atomic<int> _depth;
public:
int computeValue() {return (_width*_height*_depth);}
void SetInternals(int w, int h, int d) {_height=h;_width=w;_depth=d;}
};
线程 1 执行此操作的地方:
f->SetInternals(42, 100, 200);
线程 2 同时执行此操作。
int something_important = f->computeValue();
可以看到,如果两个线程同时执行, computeValue
返回的值可能会损坏。
您可以使用互斥锁和锁组合而不是原子来实现所需的线程安全行为:
class Volume
{
int _width;
int _height;
int _depth;
mutex _mutex;
public:
int computeValue() {
lock_guard<mutex> lck(_mutex);
int result = _width*_height*_depth;
return result;
}
void SetInternals(int w, int h, int d) {
lock_guard<mutex> lck(_mutex);
_height=h;_width=w;_depth=d;
}
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.