[英]Is an atomic object unsafe in any context where a plain object is safe?
My question is simple: is there any parallel algorithm where using an object of a trivial type T
is legal and safe (well defined, guaranteed to work) and using instead an std::atomic<T>
object leads to unspecified or undefined behavior?我的问题很简单:是否有任何并行算法使用一个简单类型
T
的对象是合法和安全的(定义明确,保证工作),而使用std::atomic<T>
对象会导致未指定或未定义的行为? In other words, it is possible for a non atomic type to provide stronger guarantees than an atomic type?换句话说,非原子类型是否有可能提供比原子类型更强的保证?
Are all the guarantees of memory visibility valid for atomic object when they are valid for regular objects?当它们对常规对象有效时,所有内存可见性保证对原子对象有效吗?
[That would mean that a compiler could treat (relaxed) atomic and non atomic operations the same, simplifying intermediate representation.] [这意味着编译器可以将(宽松的)原子操作和非原子操作一视同仁,从而简化中间表示。]
If yes, is that formally provable?如果是,那是否可以正式证明?
Of course types T
such that std::atomic<T>
isn't a valid specialization of std::atomic
don't count.当然,类型
T
使得std::atomic<T>
不是std::atomic
的有效特化不算数。
No scenario in which a non-atomic value has a stronger guarantee when compared to it's atomic
equivalent.与
atomic
等价物相比,没有非原子值具有更强保证的情况。
The only bad pattern I can think of, is when a developer makes a mistake of assuming that if all members of a data structure are individually thread safe, then the entire data structure is assumed to be thread safe.我能想到的唯一不好的模式是,当开发人员错误地假设如果数据结构的所有成员都是单独的线程安全的,那么整个数据结构就被假定为线程安全的。 This would not be a correct assumption.
这不是一个正确的假设。
Consider the following hypothetical:考虑以下假设:
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;}
};
Where thread 1 does this:线程 1 执行此操作的地方:
f->SetInternals(42, 100, 200);
And thread 2 does this at the same time.线程 2 同时执行此操作。
int something_important = f->computeValue();
You can see that the value returned by computeValue
may be corrupted if both threads execute at the same time.可以看到,如果两个线程同时执行,
computeValue
返回的值可能会损坏。
You can achieve the desired thread safe behavior with a mutex and lock combo instead of atomics:您可以使用互斥锁和锁组合而不是原子来实现所需的线程安全行为:
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.