C++11:atomic::compare_exchange_weak 支持非原始类型吗?

Posted

技术标签:

【中文标题】C++11:atomic::compare_exchange_weak 支持非原始类型吗?【英文标题】:C++11: does atomic::compare_exchange_weak support none-primitive types? 【发布时间】:2017-07-27 09:02:43 【问题描述】:

我有以下代码:

#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,

所以我的问题:

    std::atomic::compare_exchange_weak 是否适用于复杂结构?

    如果 intel cpu 硬件 CMPEXG 只能在 64 位长度的缓存行中工作,那么大于 8 字节的结构是否可以与 CMPEXG 一起工作?还是原子操作吗?

    如何修复我的程序?

谢谢。

【问题讨论】:

【参考方案1】:

std::atomic::compare_exchange_weak 是否适用于复杂结构?

是的,但有conditions 包括trivially copyable 和trivially 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;

【讨论】:

以上是关于C++11:atomic::compare_exchange_weak 支持非原始类型吗?的主要内容,如果未能解决你的问题,请参考以下文章

C++11 - 如何在 C++11 中制作这个 Qt 语句?

是否可以通过#define 将 g++ 设置为遵循 C++11 ISO (-std=c++11)?

C++0x 和 C++11 有啥区别?

Qt 5:CONFIG+=c++11 与 QMAKE_CXXFLAGS+=-std=c++11 (更好的)

默认情况下,clang 中是不是有一组已知的 `c++11` 功能不需要`-std=c++11`?

C++11新特性:19—— C++11右值引用