2013-04-16 64 views
11

許多C++ 11 CAS操作(例如,atomic_compare_exchange_weakatomic_compare_exchange_strong)取兩個指針和值,即,像這樣的:爲什麼C++ 11 CAS操作需要兩個指針參數?

bool atomic_compare_exchange(T* pointer, T* expected,  // pseudodeclaration! 
          T desired); 

相比之下,微軟,GCC和英特爾的CAS操作所有需要一個指針和兩個值:

long InterlockedCompareExchange(long* pointer, long desired,  // Microsoft 
           long expected); 

int __sync_bool_compare_and_swap (T* pointer, T expected,   // gcc and 
            T desired);      // Intel 

爲什麼在C++ 11個CAS功能需要兩個指針和一個值,而不是這似乎是一個更傳統的一個指針和兩個值?

+0

'__sync_bool _...'返回一個布爾* *。 –

+1

@KerrekSB:我展示的簽名是從英特爾手冊中複製而來的。我認爲gcc使用了相同的簽名。我現在看到它沒有。 – KnowItAllWannabe

回答

18

C++ 11的方式更加有用:如果交換失敗,那麼*expected更新爲爲新的當前值。這使得它易於使用的功能,在一個循環:

T value = x.load(); 
T newvalue = frob(value); 

while (!atomic_compare_exchange(&x, &value, newvalue)) 
{ 
    newvalue = frob(value); 
} 

隨着微軟簽名,檢驗操作是否成功是比較煩瑣,並同上,對GCC的__sync_type版本。對於GCC的__sync_bool,每次交換失敗時甚至需要執行另一次加載。

2

我不明白爲什麼你不會有這兩個。在我的用例中,C++版本不太有用。我想等到一個變量有一些值,然後我想將它設置爲一個新的值。

隨着GCC instrinsics:

while (!__sync_bool_compare_and_swap(&value, expected, desired)) { } 

用C++ 11:

auto tmp = expected; 
while (!value.compare_exchange_weak(tmp,desired)) 
{ 
    tmp = expected; 
} 
相關問題