通過使用atomic操作避免使用互斥鎖,當一個線程執行一個atomic操作,其他線程掛起,atomic操作的優點是它們相對locks更快,不會有deadlock和convoying的現象,缺點是它們只能做有限的操作,常常沒有足夠同步更復雜的操作,但是你不應該放棄使用atomic操作的機會而去使用互斥鎖,類atomic實現c++風格的的操作。
atomic操作的典型應用是線程安全的引用計數。假設x是一個類型爲int的引用計數,當引用計數變成0時,需要程序做一些行爲。在單一線程中,你能使用int型的x並且–x;if(x==0) action()。但是這種方法對多線程可能是失敗的,因爲2個線程可能交叉下面的操作:
x是在2個線程中分開操作,如果x=2,在線程評估if條件之前2個線程對x做減少操作,2個線程調用action(),爲了更正這個問題,你需要同一時間只有個線程減少,確保通過if檢測的值是減少的結果。你能使用互斥鎖,但是使用atomic::operator–是更快更簡單的方法。
atomic支持類型T的atomic操作,一定是整型、枚舉或者是指針類型,有5個基本操作,附帶運算符重載的接口。例如,對atomic的++,–,-=以及+=操作,下面是5個對atomic類型變量x的基本操作:
因爲這些操作以原子形式發生的,他們可以在沒有互斥鎖的情況下安全的使用:
atomic<unsigned> counter;
unsigned GetUniqueInteger() {
return counter.fetch_and_add(1);
}
下面這種情況,atomic類型的對象X被初始化成0:
atomic<int> x; // zero-initialized because it is at file scope
class Foo {
atomic<int> y;
atomic<int> notzeroed;
static atomic<int> z;
public:
Foo() :
y() // zero-initializes y.
{
// notzeroed has unspecified value here.
}
};
atomic<int> Foo::z; // zero-initialized because it is a static member