2017-07-27 71 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; 
}