C++ 并发专题 - 不变式与多线程

一:概述

        在C++中,“不变式”通常是指程序中某些必须始终成立的条件或者规则,破坏不变式(breaking Invariant Solved)的问题通常出现在并发编程中,当多个线程同时操作共享数据时,如果没有正确同步,可能导致数据不一致,进而违反了不变式。 

        在多线程程序中,不变式是指那些在整个程序运行过程中始终需要保持为真的条件或属性。比如:

        1. 某个变量的值不能超过特定范围。

        2. 一个计数器的值应该是非负数。

        3. 某个状态应该在任何时候都保持一致。 

二:例子(账户总余额不变)

#include <atomic>
#include <functional>
#include <iostream>
#include <mutex>
#include <thread>struct Account
{int balance{ 100 };
};std::mutex mutAccount;void transferMoney(int amount, Account& from, Account& to)
{using namespace std::chrono_literals;{std::lock_guard<std::mutex> lock(mutAccount);if (from.balance >= amount){from.balance -= amount;std::this_thread::sleep_for(10ns);to.balance += amount;}}
}void printSum(Account& a1, Account& a2)
{std::lock_guard<std::mutex> lock(mutAccount);std::cout << (a1.balance + a2.balance) << '\n';
}int main()
{std::cout << '\n';Account acc1; Account acc2;std::cout << "initial sum: "; printSum(acc1, acc2);std::thread thr1(transferMoney, 5, std::ref(acc1), std::ref(acc2));std::thread thr2(transferMoney, 13, std::ref(acc2), std::ref(acc1));std::cout << "Intermediate sum: ";std::thread thr3(printSum, std::ref(acc1), std::ref(acc2));thr1.join();thr2.join();thr3.join();std::cout << "  acc1.balance: " << acc1.balance << '\n';std::cout << "  acc2.balance: " << acc2.balance << '\n';std::cout << "Final sum: "; printSum(acc1, acc2);std::cout << '\n';}

三: 破坏不变式的情况和示例

        破坏不变式通常发生在多线程程序中,尤其是当多个线程访问共享数据时,如果没有正确同步,可能会导致以下问题:

        1. 竞态条件:多个线程同时读写共享数据而没有适当的同步机制,导致数据不一致。

        2. 死锁:多个线程在等待对方释放资源时,导致程序无法继续运行。

        3. 不一致的状态:即使没有竞态条件,线程在更新数据时的时序问题可能导致不变式被破坏。

        下面介绍一个例子,多线程程序中,如果没有同步机制,共享变量会导致不一致的情况:

#include <iostream>
#include <thread>
#include <mutex>std::mutex mtx;
int shared_value = 0;void increment() {for (int i = 0; i < 100000; ++i) {shared_value++;}
}void decrement() {for (int i = 0; i < 100000; ++i) {shared_value--;}
}int main() {std::thread t1(increment);std::thread t2(decrement);t1.join();t2.join();// 期望 shared_value 为 0,但由于缺少同步,可能不为 0std::cout << "Shared value: " << shared_value << std::endl;return 0;
}

四:解决不变式破坏问题的方法: 

        解决不变式被破坏问题的方法通常涉及到正确的线程同步,可以使用 std::mutex 来确保同一时刻只有一个个线程访问共享资源,从而避免竞态条件。以下是解决上述问题的示例代码:

#include <iostream>
#include <thread>
#include <mutex>std::mutex mtx;
int shared_value = 0;void increment() {for (int i = 0; i < 100000; ++i) {std::lock_guard<std::mutex> lock(mtx);  // 使用锁来保护共享资源shared_value++;}
}void decrement() {for (int i = 0; i < 100000; ++i) {std::lock_guard<std::mutex> lock(mtx);  // 使用锁来保护共享资源shared_value--;}
}int main() {std::thread t1(increment);std::thread t2(decrement);t1.join();t2.join();// 现在,shared_value 应该是 0std::cout << "Shared value: " << shared_value << std::endl;return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【359】基于springboot的智慧草莓基地管理系统

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本智慧草莓基地管理系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据…

MongoDB笔记03-MongoDB索引

文章目录 一、前言1.1 概述1.2 MongoDB索引使用B-Tree还是BTree&#xff1f;1.3 B 树和 B 树的对比1.4 总结 二、索引的类型2.1 单字段索引2.2 复合索引2.3 其他索引 三、索引的管理操作3.1 索引的查看3.2 索引的创建3.2.1 单字段索引3.2.2 复合索引 3.3 索引的移除3.3.1 指定索…

string模拟实现流插入(输出)+流提取(输入)

个人主页&#xff1a;Jason_from_China-CSDN博客 所属栏目&#xff1a;C系统性学习_Jason_from_China的博客-CSDN博客 所属栏目&#xff1a;C知识点的补充_Jason_from_China的博客-CSDN博客 string模拟实现clear 模拟实现clear的目的是在流提取的时候我们清空之前的数据&#x…

C++入门基础知识134—【关于C 库函数 - gmtime()】

成长路上不孤单&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【14后&#x1f60a;///C爱好者&#x1f60a;///持续分享所学&#x1f60a;///如有需要欢迎收藏转发///&#x1f60a;】 今日分享关于C 库函数 - gmtime()的相关内容&#xf…

ERP学习笔记-预处理eeglab

第一步&#xff1a;数据格式转化 import data&#xff1a;读取收集到的原始数据文件.vhdr格式 读取后的样子&#xff1a; 将数据保存为.set文件 第二步&#xff1a;通道定位 读取.set文件 Channel locations部分为unknown&#xff0c;表明通道的坐标未知 增加默认的设置 Chan…

查缺补漏----用户上网过程(HTTP,DNS与ARP)

&#xff08;1&#xff09;HTTP 来自湖科大计算机网络微课堂&#xff1a; ① HTTP/1.0采用非持续连接方式。在该方式下&#xff0c;每次浏览器要请求一个文件都要与服务器建立TCP连接当收到响应后就立即关闭连接。 每请求一个文档就要有两倍的RTT的开销。若一个网页上有很多引…

谷歌推出全新AI生成游戏玩法 —— 无限生成角色生活模拟游戏“Unbounded”

随着人工智能技术的飞速发展,游戏行业正迎来前所未有的创新。近日,谷歌宣布了一款名为“Unbounded”的新型游戏,这是一款基于生成式AI技术的角色生命模拟游戏,它将为玩家带来前所未有的开放性和互动性体验。 项目概览 项目名称:Unbounded类型:生成式无限游戏(Generati…

论文阅读:DynamicDet: A Unified Dynamic Architecture for Object Detection

论文地址&#xff1a;[2304.05552] DynamicDet: A Unified Dynamic Architecture for Object Detection 代码地址&#xff1a;GitHub - VDIGPKU/DynamicDet: [CVPR 2023] DynamicDet: A Unified Dynamic Architecture for Object Detection 概要 本文提出了一种名为 DynamicD…

关于在GitLab的CI/CD中用docker buildx本地化多架构打包dotnet应用的问题

关于在GitLab的CI/CD中用docker buildx本地化多架构打包dotnet应用的问题 这是一个DevOps综合性问题docker buildx多架构打包.NET应用的问题用QEMU模拟多架构环境打包 这是一个DevOps综合性问题 网络上的方案都是细分的领域&#xff0c;未见一个集成了GitLabdockerdotnet的多架…

翻译工具开发技术笔记:《老挝语翻译通》app支持语音识别翻译功能,怎么提高语音识别的准确度呢?

《老挝语翻译通》app是一款专为老挝语翻译设计的免费工具&#xff0c;支持文本翻译、老挝文OCR文字识别提取、文字转语音。这款工具以其技术优势和用户友好的界面&#xff0c;为用户提供了便捷的老挝语翻译体验。 技术特点 文本翻译&#xff1a;支持双语输入&#xff0c;提供精…

qt QListView详解

1、概述 QListView 是 Qt 框架中的一个视图类&#xff0c;用于展示模型中的数据。它基于 QAbstractItemView&#xff0c;支持多种视图模式&#xff0c;如列表视图&#xff08;List View&#xff09;、图标视图&#xff08;Icon View&#xff09;等。QListView 是模型/视图框架…

初识C++(上) -- C++的关键字、命名空间、缺省参数以及函数的重载

目录 一、C的关键字&#xff08;C98&#xff09; 二、命名空间 1、命名冲突 2、命名空间 2.1 命名空间的定义 (1). 命名空间定义的例子以及命名空间的嵌套&#xff1a; (2). 同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中&#xff1a; 2…

MySQL_客户端工具建库.

前言&#xff1a; 通过前面的学习我们已经了解到什么是数据库&#xff0c;以及数据库是如何安装的&#xff0c;相信大家都已将数据库安装好了&#xff0c;让我们接下来开始新的学习吧&#xff01;&#xff01;&#xff01; 1.MySQL客户端工具 1. MySQL Workbench MySQL :: D…

突破1200°C高温性能极限!北京科技大学用机器学习合成24种耐火高熵合金,室温延展性极佳

在工程应用中&#xff0c;如燃气轮机、核反应堆和航空推进系统&#xff0c;对具备优异高温机械性能的金属合金需求十分旺盛。由于材料熔点的固有限制&#xff0c;传统镍基 (Ni) 高温合金的耐温能力已接近极限。为满足开发高温结构材料的需求&#xff0c;耐火高熵合金 (RHEAs) 于…

leetcode21:合并两个有序列表

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1&#xff1a; 输入&#xff1a;l1 [1,2,4], l2 [1,3,4] 输出&#xff1a;[1,1,2,3,4,4]示例 2&#xff1a; 输入&#xff1a;l1 [], l2 [] 输出&#xff1a;[]示…

开源模型应用落地-glm模型小试-glm-4-9b-chat-vLLM集成(四)

一、前言 GLM-4是智谱AI团队于2024年1月16日发布的基座大模型&#xff0c;旨在自动理解和规划用户的复杂指令&#xff0c;并能调用网页浏览器。其功能包括数据分析、图表创建、PPT生成等&#xff0c;支持128K的上下文窗口&#xff0c;使其在长文本处理和精度召回方面表现优异&a…

K8S篇(基本介绍)

目录 一、什么是Kubernetes&#xff1f; 二、Kubernetes管理员认证&#xff08;CKA&#xff09; 1. 简介 2. 考试难易程度 3. 考试时长 4. 多少分及格 5. 考试费用 三、Kubernetes整体架构 Master Nodes 四、Kubernetes架构及和核心组件 五、Kubernetes各个组件及功…

关于路由笔记

路由 定义&#xff1a; 在计算机网络中&#xff0c;路由是将数据包从源节点传输到目标节点的过程。这个过程涉及到网络中的多个设备&#xff0c;如路由器、交换机等&#xff0c;其中路由器起着关键的决策作用。 工作原理示例&#xff1a; 假设你在一个公司的局域网内&#…

人工智能之人脸识别(人脸采集人脸识别)

文章目录 前言PySimpleGUI 库1-布局和窗口 前言 例如&#xff1a;随着人工智能的不断发展&#xff0c;本文主要介绍关于人工智能中GUI和PyMysql相应用。 本文采用代码&#xff0b;逻辑思路分析的方式有助于理解代码。 PySimpleGUI 库 PySimpleGUI 是一个用于简化 GUI 编程的…

如何找到养生生活视频素材?推荐几个优秀网站

今天&#xff0c;我们来聊一个实用的话题&#xff0c;那就是如何找到优质的养生视频素材。作为自媒体创作者&#xff0c;高质量的视频素材对内容制作至关重要。不论你是刚入行的新手&#xff0c;还是已经积累了一定粉丝的大V&#xff0c;找到合适的养生视频素材都能帮助你更好地…