对atomic<bool>的操作

#include <iostream>
#include<atomic>
#include<thread>
//std::atomic<bool>是一个比 std::atomic_flag 更具功能的布尔标志。
// 尽管仍然不能进行拷贝构造或拷贝赋值,但可以从一个非原子的 bool 类型构造它,或进行赋值

//与 std::atomic_flag 使用功能有限的 clear() 函数不同,写入操作(true 、false)是通过调用 store() 来完成的。
// 同样,test_and_set() 被更通用的 exchange() 成员函数取代,它允许用选择的新值替换存储的值,并原子地检索原始值
void do_something(std::atomic<bool>&lock) {
	while (lock.load(std::memory_order_acquire)) { //加载操作,返回当前的值
		std::cout << "等待其他线程完成,当前锁的状态为:" << (lock.load() ? "已上锁" : "未上锁")<< "\n"; 
		std::this_thread::sleep_for(std::chrono::milliseconds(250));
	}
	//exchange读修改操作
	bool status = lock.exchange(true, std::memory_order_acq_rel); //上锁,并返回之前的状态
	std::cout << "线程" << std::this_thread::get_id() << "准备就绪!当前锁的状态为:" << (status? "已上锁" : "未上锁") << "\n";

	std::cout << "线程" << std::this_thread::get_id() << "运行中!当前锁的状态为:"<<(lock.load()?"已上锁" :"未上锁")<<"\n";
	std::this_thread::sleep_for(std::chrono::milliseconds(300));
	
	//存储操作,把锁存储为false,表示未占用
	lock.store(false,std::memory_order_release); //释放锁,恢复为未占用的状态

}
void Test1() {
	std::atomic<bool>lock(false); //初始化
	std::thread threads[10];
	for (int i = 0; i < 10; ++i) {
		threads[i] = std::thread(do_something,std::ref(lock));
	}
	for (int i = 0; i < 10; ++i) {
		threads[i].join();
	}
}
//compare_exchange_weak和compare_exchange_strong成员函数
//于 compare_exchange_weak(),即使原始值等于期望值,存储操作也可能不成功
//这种情况最有可能发生在缺乏单一比较和交换指令的机器上,可能是因为执行操作的线程在必要的指令序列中间被切换出去,
// 而操作系统在其位置安排了另一个线程

void Test2() {
	std::atomic_bool atomic_lock(false); //atomic_bool和atomic<bool>一样
	bool expected_status = true; //期望的bool状态
	bool desired_status = false; //比较后修改的状态

	//当前状态的期望状态不一样,返回false,并且不会改变当前的状态,但会修改expected_status的状态为当前原子的状态
	bool compare_status = atomic_lock.compare_exchange_weak(expected_status, desired_status);
	std::cout << "比较后得到的状态是" << (compare_status ? "true" : "false") << "\n";
	std::cout << "atomic_bool的状态是" << (atomic_lock.load(std::memory_order_acquire) ? "true" : "false") << "\n";
	std::cout<<"expected_statu的状态是"<< (expected_status ? "true" : "false") << "\n";
	std::cout << "desired_statu的状态是" << (desired_status ? "true" : "false") << "\n";

	//当前状态的期望状态一样,返回true,并且改变当前的状态为desire_status,不会修改expected_status的状态
	atomic_lock.store(true, std::memory_order_release); // 改变当前状态为true
	expected_status = true; // 更新期望的状态为true
	compare_status = atomic_lock.compare_exchange_weak(expected_status, desired_status);

	std::cout << "比较后得到的状态是" << (compare_status ? "true" : "false") << "\n";
	std::cout << "atomic_bool的状态是" << (atomic_lock.load(std::memory_order_acquire) ? "true" : "false") << "\n";
	std::cout << "expected_statu的状态是" << (expected_status ? "true" : "false") << "\n";
	std::cout << "desired_statu的状态是" << (desired_status ? "true" : "false") << "\n";

	//但compare_exchange_weak一次比较可能会发生“伪失败”,需要使用一个循环
	bool expected = false;
	std::atomic<bool> b(false); 
	//多次比较
	while (!b.compare_exchange_weak(expected, true)&&!expected) { //通常情况这两个条件不会同时满足,除非发生错误
		expected = false; //比较失败需要重置,多次比较
		std::cout << "修改失败!\n";
	}
	std::cout << "修改成功!\n";

	//ompare_exchange_strong() 保证只有在值不相等的情况下才返回 false。这可以消除像上面展示的循环的需要
	atomic_lock.store(true,std::memory_order_release); // 改变当前状态为true
	expected_status = true; // 更新期望的状态为true
	compare_status = atomic_lock.compare_exchange_strong(expected_status, desired_status);

	std::cout << "比较后得到的状态是" << (compare_status ? "true" : "false") << "\n";
	std::cout << "atomic_bool的状态是" << (atomic_lock.load(std::memory_order_acquire) ? "true" : "false") << "\n";
	std::cout << "expected_statu的状态是" << (expected_status ? "true" : "false") << "\n";
	std::cout << "desired_statu的状态是" << (desired_status ? "true" : "false") << "\n";

	//可以为比较成功和失败指定相应的排序
	//成功:可能希望具有 memory_order_acq_rel 语义
	//失败:则具有 memory_order_relaxed 语义
	//失败的比较交换不会执行存储操作,因此它不能具有 memory_order_release 或 memory_order_acq_rel 语义
	//也不能为失败提供比成功更严格的内存排序
	//如果没有为失败指定排序,它被假设与成功时相同,只是释放部分被剥离:
	//memory_order_release 变为 memory_order_relaxed,memory_order_acq_rel 变为 memory_order_acquire。
	//如果两者都没有指定,默认为 memory_order_seq_cst

	atomic_lock.store(false, std::memory_order_release); // 改变当前状态为true
	expected_status = true; // 更新期望的状态为true
	//比较成功调用的排序为memory_order_acq_rel,失败后调用的是memory_order_relaxed
	compare_status = atomic_lock.compare_exchange_strong(
		expected_status, desired_status,std::memory_order_acq_rel,std::memory_order_relaxed);
	

	std::cout << "比较后得到的状态是" << (compare_status ? "true" : "false") << "\n";
	std::cout << "atomic_bool的状态是" << (atomic_lock.load(std::memory_order_acquire) ? "true" : "false") << "\n";
	std::cout << "expected_statu的状态是" << (expected_status ? "true" : "false") << "\n";
	std::cout << "desired_statu的状态是" << (desired_status ? "true" : "false") << "\n";

}
int main(){
	//Test1();
	Test2();

	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/783589.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

家里老人能操作的电视直播软件,目前能用的免费看直播的电视软件app,适合电视和手机使用!

2024年许多能看电视直播的软件都不能用了&#xff0c;家里的老人也不会手机投屏&#xff0c;平时什么娱乐都没有了&#xff0c;这真的太不方便了。 很多老人并不喜欢去买一个广电的机顶盒&#xff0c;或者花钱拉有线电视。 现在的电视大多数都是智能电视&#xff0c;所以许多电…

记录在Windows上安装Docker

在Windows上安装Docker时&#xff0c;可以选择使用不同的后端。 其中两个常见的选择是&#xff1a;WSL 2&#xff08;Windows Subsystem for Linux 2&#xff09;和 Hyper-V 后端。此外&#xff0c;还可以选择使用Windows容器。 三者的区别了解即可&#xff0c;推荐用WSL 2&…

驾校管理系统-计算机毕业设计源码49777

驾校管理系统 摘 要 驾校管理系统是一个基于Spring Boot框架开发的系统&#xff0c;旨在帮助驾校提高管理效率和服务水平。该系统主要实现了用户管理、年月类型管理、区域信息管理、驾校信息管理、车辆信息管理、报名信息管理、缴费信息管理、财务信息管理、教练分配管理、更换…

数字签密:信息安全的新防线

随着互联网的普及和数字技术的飞速发展&#xff0c;信息安全问题日益凸显。在这个背景下&#xff0c;数字签密技术应运而生&#xff0c;为保护信息安全提供了新的解决方案。本文将介绍数字签密的概念、原理及应用&#xff0c;探讨其在信息安全领域的重要性。 数字签密的概念 …

智慧矿山:EasyCVR助力矿井视频多业务融合及视频转发服务建设

一、方案背景 随着矿井安全生产要求的不断提高&#xff0c;视频监控、数据传输、通讯联络等业务的需求日益增长。为满足矿井生产管理的多元化需求&#xff0c;提高矿井作业的安全性和效率&#xff0c;TSINGSEE青犀EasyCVR视频汇聚/安防监控综合管理平台&#xff0c;旨在构建一…

Spring学习05-[AOP学习-AOP原理和事务]

AOP原理和事务 AOPAOP底层原理比如下面的代码案例手动模拟AOP 动态代理详解JDK动态代理具体实现 Cglib动态代理具体实现 jdk动态代理和cglib动态代理的区别 事务 AOP AOP底层原理 当实现了AOP,Spring会根据当前的bean创建动态代理(运行时生成一个代理类) 面试题&#xff1a;为…

JAVA之(static关键字、final关键字)

JAVA之&#xff08;static关键字、final关键字&#xff09; 一、 static关键字1、静态变量2、静态方法3、 静态代码块4、例子 二、final关键字1、final修饰类2、 final修饰方法3、修饰变量 一、 static关键字 1、静态变量 private static String str1“staticProperty”2、静…

适合中小企业的MES管理系统有哪些特点

在当今竞争激烈的商业环境中&#xff0c;中小企业对于高效、灵活的生产管理系统的需求日益凸显。面对这些企业的MES管理系统不仅成为监控生产过程的得力助手&#xff0c;还通过提供关键数据&#xff0c;构建起客户期望与制造车间实时订单状态之间的紧密桥梁&#xff0c;以下是对…

Vue3使用markdown编辑器之Bytemd

官网地址&#xff1a;https://bytemd.js.org/playground GitHub地址&#xff1a;https://github.com/bytedance/bytemd ByteMD 是字节跳动出品的富文本编辑器&#xff0c;功能强大&#xff0c;可以免费使用&#xff0c;而且支持很多掘金内置的主题&#xff0c;写作体验很棒。 …

【Unity2D 2022:Particle System】添加拾取粒子特效

一、创建粒子特效游戏物体 二、修改粒子系统属性 1. 基础属性 &#xff08;1&#xff09;修改发射粒子持续时间&#xff08;Duration&#xff09;为3s &#xff08;2&#xff09;取消勾选循环&#xff08;Looping&#xff09; &#xff08;2&#xff09;修改粒子存在时间&…

星网安全产品线成立 引领卫星互联网解决方案创新

2024年6月12日&#xff0c;盛邦安全&#xff08;688651&#xff09;成立星网安全产品线&#xff0c;这是公司宣布全面进入以场景化安全、网络空间地图和卫星互联网安全三大核心能力驱动的战略2.0时代业务落地的重要举措。 卫星互联网技术的快速发展&#xff0c;正将其塑造为全球…

leetcode:编程基础0到1

文章目录 交替合并字符串str.length();StringBuilder类型 ,toString()append() &#xff0c;chatAt()题目描述 交替合并字符串 str.length(); 输出字符串str的长度 StringBuilder类型 ,toString() append() &#xff0c;chatAt() 题目描述 class Solution {public String …

(译文)IRIG-B对时编码快速入门

原文 PDF&#xff1a;https://ww1.microchip.com/downloads/aemDocuments/documents/FTD/tekron/tekronwhitepapers/221223-A-guide-to-IRIG-B.pdf IRIG-B3 概论 Inter-Range Instrument Group 时间码&#xff08;简称IRIG&#xff09;是一系列标准时间码格式。用于将时间信…

俄罗斯VK Ads开户充值全流程!VK如何开户?VK如何注册?VK广告

在俄罗斯&#xff0c;VK&#xff08;VKontakte&#xff09;是一个广受欢迎的社交媒体平台&#xff0c;对于寻求进入该市场的企业来说&#xff0c;进行VK广告推广是一条有效途径。 首先&#xff0c;你需要明确自己要推广的产品或服务&#xff0c;并且确定目标市场和受众。 由于…

1.8.0-矩阵乘法的反向传播-简单推导

1相关资料 之前分享过一个博客里面写的&#xff0c;我们大致了解并记住结论的博客&#xff1a;【深度学习】7-矩阵乘法运算的反向传播求梯度_矩阵梯度公式-CSDN博客&#xff1b;这里再分享一下自然语言处理书上关于这部分的推导过程&#xff1a;3-矩阵相乘-梯度反向传播的计算…

如何下载jmeter旧版本

如何下载jmeter旧版本 推荐先用旧版本做好测试基本操作&#xff0c;因为高版本不适合做压力测试&#xff0c;需要证书&#xff0c;有点麻烦。 1.百度或直接打开jmeter官网&#xff1a;https://jmeter.apache.org/ 2.向下拖到Archives一栏&#xff0c;点击Apache Jmeter archi…

ICC2:ignore pin的设置

我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧? 拾陆楼知识星球入口 相关文章链接:

OS Copilot测评

1.按照第一步管理重置密码时报错了,搞不懂为啥?本来应该跳转到给的那个实例的,我的没跳过去 2.下一步重置密码的很丝滑没问题 3安全组新增入库22没问题 很方便清晰 4.AccessKey 还能进行预警提示 5.远程连接,网速还是很快,一点没卡,下载很棒 6.替换的时候我没有替换<>括…

六、快速启动框架:SpringBoot3实战-个人版

六、快速启动框架&#xff1a;SpringBoot3实战 文章目录 六、快速启动框架&#xff1a;SpringBoot3实战一、SpringBoot3介绍1.1 SpringBoot3简介1.2 系统要求1.3 快速入门1.4 入门总结回顾复习 二、SpringBoot3配置文件2.1 统一配置管理概述2.2 属性配置文件使用2.3 YAML配置文…

调制信号识别系列 (一):基准模型

调制信号识别系列 (一)&#xff1a;基准模型 说明&#xff1a;本文包含对CNN和CNNLSTM基准模型的复现&#xff0c;模型架构参考下述两篇文章 文章目录 调制信号识别系列 (一)&#xff1a;基准模型一、论文1、DL-PR: Generalized automatic modulation classification method b…