[英]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.