C++11标准原子库内存顺序memory_order_consume与memory_order_acquire的差异示例

news/2025/1/13 8:06:46/

C++11标准原子库内存顺序memory_order_consumememory_order_acquire的差异示例

贺志国

在C++11标准原子库中,大多数函数接收一个memory_order参数:

enum memory_order {memory_order_relaxed,memory_order_consume,memory_order_acquire,memory_order_release,memory_order_acq_rel,memory_order_seq_cst
};

上述枚举变量虽然有六个选项,但仅代表三种内存模型:
(1)顺序一致性(sequentially consistent,即memory_order_seq_cst)
(2)获取-释放序(memory_order_consume, memory_order_acquire, memory_order_releasememory_order_acq_rel)
(3)自由序(或者叫松弛充,memory_order_relaxed)。

除非为特定的操作指定一个内在顺序选项,内存顺序默认都是memory_order_seq_cst

memory_order_consumememory_order_acquire都为了同一个目的:帮助非原子信息在线程间安全的传递。就像获取操作(memory_order_acquire)一样,消费操作(memory_order_consume)必须与另一个线程的释放操作(memory_order_acquire)一起使用。它们的差异在于:memory_order_acquire保证配对使用的 memory_order_release操作之前的所有原子和非原子的写入操作有效,但memory_order_consume仅保证配对使用的 memory_order_release操作之前的所有原子的写入操作有效。

下面使用一个示例来说明:

示例代码如下:

#include <atomic>
#include <cassert>
#include <iostream>
#include <thread>int a;
std::atomic<bool> flag;void Write() {a = 1;flag.store(true, std::memory_order_release);
}void Read() {// std::memory_order_acquire保证// flag.store(true, std::memory_order_release);// 之前的a = 1; 一定会先执行,但// std::memory_order_consume,std::memory_order_relaxed// 无法保证这点// 注意:// X86平台上无内存顺序的差别,任何内存顺序断言都会成功// 但在ARM平台上,如果使用// std::memory_order_consume,std::memory_order_relaxed,// 断言可能失败。while (!flag.load(std::memory_order_acquire)) {std::this_thread::yield();}std::cout << "a must be 1.\n";assert(1 == a);
}int main() {a = 0;flag = false;std::thread write_thread(Write);std::thread read_thread(Read);write_thread.join();read_thread.join();return 0;
}

CMake构建文件如下:

cmake_minimum_required(VERSION 3.0.0)
project(memory_order VERSION 0.1.0)
set(CMAKE_CXX_STANDARD 14)add_executable(${PROJECT_NAME} ${PROJECT_NAME}.cpp)find_package(Threads REQUIRED)
target_link_libraries(${PROJECT_NAME} ${CMAKE_THREAD_LIBS_INIT})include(CTest)
enable_testing()
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)

运行结果如下:

./memory_order 
a must be 1.

注意memory_order_consume这个内存序非常特殊,主流编译器直接将它当成memory_order_acquire处理。“C++ Concurrency In Action”(第二版,2019)一书作者认为memory_order_consume不应该出现在实际的代码中,即使在C++17中也不推荐使用


http://www.ppmy.cn/news/417740.html

相关文章

【深度学习】2-2 神经网络 - 前向传播实现3层神经网络

神经网络分层 神经网络的一个重要性质是它可以自动地从数据中学习到合适的权重参数。 用图来表示神经网络的话&#xff0c;把最左边的一列称为输入层&#xff0c;最右边的一列称为输出层&#xff0c;中间的一列称为中间层。中间层有时也叫隐藏层&#xff08;或隐含层&#xf…

国货之光!百度飞桨与华为麒麟重磅合作

7月3日-7月4日&#xff0c;“Baidu Create 2019”百度AI开发者大会&#xff0c;在中国北京国家会议中心举行。 今天上午&#xff0c;在百度AI开发者大会现场&#xff0c;百度首席技术官王海峰与华为消费者BG软件总裁王成录博士联合宣布&#xff0c;百度飞桨与华为麒麟达成深度…

华为鸿蒙麒麟巴龙鲲鹏,华为四大芯片 麒麟、巴龙、昇腾和鲲鹏“四大天王”...

华为作为我国通信科技行业企业&#xff0c;在2004年成立海思半导体开始研制芯片&#xff0c;如今在5G技术已经达到世界领先地位&#xff0c;不被国外芯片所限制&#xff0c;华为旗下拥有四大芯片&#xff1a;麒麟系列、巴龙系列、昇腾系列和鲲鹏系列&#xff0c;下面跟随小编来…

消息称华为麒麟 A2 处理器已有量产能力,海思将率先在可穿戴设备领域回归

华为海思将于 2023 年第 3 季度或第 4 季度推出麒麟 A2 处理器&#xff0c;海思将在可穿戴设备处理器领域率先回归。 报道指出&#xff0c;华为已经测试麒麟 A2 很长一段时间&#xff0c;已准备试产&#xff0c;且具备量产能力。不过&#xff0c;在最终交付量产之前&#xff0c…

麒麟659鸿蒙系统,华为官宣自研系统,麒麟659以上的华为手机可以直接切换新系统...

原标题&#xff1a;华为官宣自研系统&#xff0c;麒麟659以上的华为手机可以直接切换新系统 华为推出搭载自己研发的系统的手机&#xff0c;对中国来说意义重大&#xff0c;若干年后&#xff0c;会成为收藏品吗&#xff1f;华为操作系统的推出&#xff0c;必然会吸引相当多的国…

银河麒麟软件源更新

银河麒麟有用软件源&#xff1a; 1.银河麒麟系统无法更新下载软件&#xff0c;原因是软件源失效&#xff1b; 2.需要更换有效的软件源&#xff1b; 3.修改软件源地址&#xff1a; 在etc/apt 的sources.list文件里添加镜像源&#xff1a; deb http://archive.ubuntu.com/ubuntu/…

升级电子狗显示无法连接到服务器,什么是云电子狗?电子狗云升级是什么

云电子狗是科技发展时代进步的必然产物&#xff0c;它是由普通电子狗进化而来&#xff0c;继承了普通电子狗一切优点&#xff0c;同时又运用最新科技不断突破&#xff0c;它是一种通过无线网络实时与中心服务器进行数据交互的GPS雷达预警仪器&#xff0c;包括中心服务器端和客服…

麒麟处理器是基于arm的吗_麒麟处理器是华为自己研发制造的吗?

目前市场上流行的&#xff0c;自主研发智能手机处理器的就只有这么几家&#xff0c;如高通、苹果、三星、华为、联发科&#xff0c;而凑巧不凑巧的&#xff0c;这几家都是采用的ARM架构。这在行业里差不多已经形成了一个不成文的共识&#xff0c;智能手机处理器的架构都采用ARM…