2017-07-27 82 views
2

我有下面的代碼:C++ 11:原子:: compare_exchange_weak支持非原始類型嗎?

#include<atomic> 
#include<iostream> 
using namespace std; 

struct Big{ 
    int i; 
    int j; 
    int k[100]; 
}; 
int main(){ 
    atomic<int> i; 
    cout<<i.load()<<endl; 
    i.store(20); 
    cout<<i.load()<<endl; 
    i.exchange(30); 
    cout<<i.load()<<endl; 

    atomic<Big> ab,expect,value; 
    ab.compare_exchange_weak(expect,value,memory_order_release,memory_order_relaxed);//error 
    return 0; 
} 

好,原子的作品很好,但我想看看是否compare_exchange_weak的無鎖功能可以爲複雜的數據結構的工作。與--std編譯= C++ 11它給了我:

error: no matching member function for call to 'compare_exchange_weak' 
    ab.compare_exchange_weak(expect,value,memory_order_release,memory_order_relaxed); 
    ~~~^~~~~~~~~~~~~~~~~~~~~ 
candidate function not viable: no known conversion from 'atomic<Big>' to 'Big &' for 1st argument 
    bool compare_exchange_weak(_Tp& __e, _Tp __d, 

所以我的問題:

  1. 是否標準::結構複雜的原子:: compare_exchange_weak工作?

  2. 如果intel cpu硬件CMPEXG只能在64位長的高速緩存行中工作,那麼大於8個字節的結構是否適用於CMPEXG?它仍然是原子操作嗎?

  3. 如何解決我的程序?

謝謝。

回答

3

是否std :: atomic :: compare_exchange_weak使用複雜結構?

是的,但有​​,其中包括trivially copyabletrivially constructible

如果intel cpu硬件CMPEXG只能在64位長度的高速緩存行中工作,那麼大於8個字節的結構是否適用於CMPEXG?

不,它不會那樣工作。如果你創建了一個瘋狂的大型結構,那麼你的代碼將不會「無鎖」。你的編譯器會發布總線鎖來確保線程安全,這就是爲什麼你永遠不應該做你在那裏用大數據結構做的事情。如果不是更多,你會減慢你的程序數百次。考慮原子交換指針。

它還在原子操作嗎?

不,它使用鎖。你可以用這個測試std::atomic::is_lock_free()

如何解決我的程序?

你去那裏:

#include <atomic> 
#include <iostream> 

using namespace std; 

struct Big { 
    int i; 
    int j; 
    int k[100]; 
}; 

int main() { 
    Big value, expect; 
    atomic<Big> ab; 
    ab.compare_exchange_weak(expect, value); 
    return 0; 
}