【C++学习(27)】一个c++类的实例“多线程“运行的例子

一个类本身并不直接“用于多线程运行”。但是,类的实例(即对象)可以在多线程环境中被使用,并且类的设计可以影响它在多线程环境中的表现和易用性。

在多线程编程中,重要的是要理解线程安全和并发控制的概念。线程安全意味着类的实例可以在多个线程中同时访问而不会导致数据不一致或其他问题。要设计一个线程安全的类,通常需要考虑如何同步对共享资源的访问,以避免竞态条件(race conditions)和其他并发问题。

在C++中,要使一个类能够在多线程环境中安全使用,可能需要采取以下措施:

避免共享状态:如果可能的话,尽量设计无状态的类,或者每个线程使用自己的类实例,以避免共享数据。使用互斥锁:如果类确实需要共享状态,可以使用互斥锁(如std::mutex)来保护对共享数据的访问。这通常通过在类的成员函数中锁定和解锁互斥锁来实现。原子操作:对于简单的数据类型,可以使用原子操作(如std::atomic)来避免互斥锁的开销。条件变量:如果需要线程间通信或等待特定条件成立,可以使用条件变量(如std::condition_variable)。避免死锁:在使用互斥锁时,要注意避免死锁。确保锁总是以一致的顺序获取,并且总是被释放。

此外,一些设计模式(如单例模式、观察者模式等)在多线程环境中使用时需要特别注意线程安全性。

下面是一个简单的例子,展示了如何设计一个类,使其能够在多线程中安全地增加其内部计数器的值。

这个例子使用了std::mutex来保护对共享数据的访问,以及std::thread来创建和管理线程。

#include <iostream>
#include <thread>
#include <vector>
#include <mutex>// 定义一个线程安全的计数器类
class ThreadSafeCounter {
public:ThreadSafeCounter() : count_(0) {}// 增加计数器的值void increment() {std::lock_guard<std::mutex> lock(mutex_); // 自动锁定和解锁互斥锁++count_;}// 获取计数器的当前值int getCount() const {std::lock_guard<std::mutex> lock(mutex_); // 自动锁定和解锁互斥锁return count_;}private:mutable std::mutex mutex_; // 互斥锁用于保护count_int count_; // 计数器值
};// 线程函数,它接受一个ThreadSafeCounter对象的引用和一个整数n
void incrementCounterNTimes(ThreadSafeCounter& counter, int n) {for (int i = 0; i < n; ++i) {counter.increment(); // 增加计数器的值}
}int main() {const int numThreads = 5; // 线程数量const int incrementsPerThread = 100; // 每个线程增加的计数次数ThreadSafeCounter counter; // 创建线程安全的计数器实例std::vector<std::thread> threads; // 存储线程对象的向量// 创建多个线程,每个线程都增加计数器的值for (int i = 0; i < numThreads; ++i) {threads.emplace_back(incrementCounterNTimes, std::ref(counter), incrementsPerThread);}// 等待所有线程完成for (auto& thread : threads) {thread.join();}// 输出最终计数器的值std::cout << "Final counter value: " << counter.getCount() << std::endl;return 0;
}

在这个例子中,ThreadSafeCounter类使用了一个std::mutex来保护其内部计数器count_的访问。当调用increment()getCount()方法时,会自动通过std::lock_guard锁定互斥锁,确保同一时间只有一个线程可以访问计数器。

incrementCounterNTimes函数是一个线程函数,它接受一个ThreadSafeCounter对象的引用和一个整数n,然后增加计数器的值n次。在main函数中,我们创建了多个线程,每个线程都调用incrementCounterNTimes函数来增加计数器的值。

最后,我们等待所有线程完成,并输出最终的计数器值。由于使用了互斥锁,最终的值将是所有线程增加次数的总和,即numThreads * incrementsPerThread

改进1:atomic<boll> 类型

问题1:是 atomic<boll> 类型,为什么不直接使用 bool 类型?什么是 atomic<bool> 类型?🤔

回答:atomic<bool> 是 C++11 引入的原子类型,它是为了支持多线程环境中无锁的线程安全操作。使用原子类型可以确保对该类型的读写操作是原子的,即它们不会被其他线程中的操作中断。

当多个线程可能同时访问和修改一个变量时,直接使用基本数据类型(如 bool)可能会导致不确定的行为或数据竞态(race conditions)。数据竞态通常是多线程编程中的一个问题,当两个或更多的线程同时访问同一资源,并至少有一个线程修改该资源时,结果是不确定的。

使用 atomic<bool> 的好处:

1. 原子操作:atomic<bool> 保证了对其的读写操作是原子的,这意味着每个读或写操作都是不可中断的。2. 内存顺序:原子操作还提供了内存顺序语义,这确保了在多线程环境中的操作顺序。3. 无锁操作:与使用互斥锁相比,原子操作通常更快,因为它们通常是无锁的。

在示例中,atomic<bool> 可能会在主线程中被设置,并在工作线程中被检查。为了确保这种跨线程的通信是线程安全的,使用 atomic<bool> 是合适的。如果只使用普通的 bool,可能会导致数据竞态,从而引起不可预测的行为。

总之,atomic<bool> 提供了一种线程安全的方式来读取和修改一个布尔值,特别是在无需使用互斥锁的情况下。

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

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

相关文章

誉天华为认证存储HCIE课程怎么样

HCIA-Storage 课程介绍课程适合转行想进入IT行业者、零基础学员、IT从业人员、存储爱好者等 实验环境全真机&#xff0c;练习时间自由&#xff0c;7*24开机&#xff0c;可以随时通过远程连接进行试验课程内容 存储发展历史 存储硬件介绍 硬盘接口介绍 RAID技术 RAID2.…

解码视频流在opengl中的贴图投影计算

解码视频流在opengl中的贴图投影计算 修改顶点着色器cpp 文件放大缩小 我们把视频当成纹理,首先要确定贴入的坐标&#xff0c;原始坐标如下所示 static float vertices[] {// ---- 位置 ---- ---- 颜色 ---- - 纹理坐标 -1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f…

为BUG编程:函数重载的烦恼 char *匹配bool而不是string

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 这是一个BUG。 运行环境为linu…

表单全选反选(前端)

1.Html和JavaScript <table><tr><th class"allCheck"><input type"checkbox" name"" id"checkAll"> <span class"all">全选</span></th><th>商品</th><th>商…

【成功案例】间隔数月双团伙先后利用某ERP0day实施入侵和勒索的解密恢复项目

1.背景 在2024年3月23日&#xff0c;我们的Solar应急响应团队&#xff08;以下简称Solar团队&#xff09;应某公司之邀&#xff0c;介入处理了一起财务系统服务器遭受黑客攻击的事件。该事件导致服务器上大量文件被加密。我们的团队迅速获取了一个被加密的文件&#xff0c;并立…

深度剖析:计算机集群在大数据体系中的关键角色和技术要点

什么是计算机集群&#xff1f; 计算机集群是一组相互连接的计算机&#xff08;服务器&#xff09;&#xff0c;它们协同工作以完成共同的任务。集群中的每个计算机节点都可以独立运行&#xff0c;但它们通过网络连接在一起&#xff0c;以实现更高的可靠性、性能和可扩展性。 典…

多图详细教你注册Google(Gmail)新账号,常见问题和注意事项

对于做外贸&#xff0c;或者需要和外国客户、朋友沟通的小伙伴来说&#xff0c;一个Google账号&#xff08;也就是Gmail账号&#xff0c;下述统一用Google账号来表述&#xff09;是非常必要的&#xff0c;一方面是通过Gmail邮箱收发邮件、沟通往来&#xff0c;另一个方面是很多…

高性能RestTemplate连接池封装配置实战

高性能RestTemplate连接池封装配置实战 package net.xdclass.config;import org.apache.http.client.HttpClient; import org.apache.http.client.config.RequestConfig; import org.apache.http.config.Registry; import org.apache.http.config.RegistryBuilder; import org…

linux安装多个版本的java

linux安装多个版本的java如何配置 jenkins 高版本已经不支持java8了&#xff0c;低版本插件安装问题很多。 jenkins 需要java17&#xff0c;研发程序需要使用java8 https://mirrors.tuna.tsinghua.edu.cn/jenkins/war-stable/2.401.1/jenkins.war https://download.oracle.…

「PHP系列」If...Else语句/switch语句

文章目录 一、If...Else语句1. 基本语法2. 带有 elseif 的语法3. 示例示例 1&#xff1a;基本 if...else 结构示例 2&#xff1a;使用 elseif示例 3&#xff1a;嵌套 if...else 结构 4. 注意事项 二、switch语句1. 基本语法2. 示例示例 1&#xff1a;基本 switch 结构示例 2&am…

3.29 文章翻译RO——Robust scheduling of building energy system under uncertainty

highlight 我们建立了一个带有冷却器和冰热能储存的建筑能源系统模型。 提出了一种两阶段鲁棒策略来调度系统运行。 具有适当参数的鲁棒策略优于确定性方法。 鲁棒策略和MPC方法的性能相似。 本文提出了一种鲁棒调度策略&#xff0c;用于在预测不确定的情况下管理具有太阳能发电…

[计算机毕业设计]基于SSM的宠物管理系统-介绍及文章指导

&#x1f389;**欢迎来到琛哥的技术世界&#xff01;**&#x1f389; &#x1f4d8; 博主小档案&#xff1a; 琛哥&#xff0c;一名来自世界500强的资深程序猿&#xff0c;毕业于国内知名985高校。 &#x1f527; 技术专长&#xff1a; 琛哥在深度学习任务中展现出卓越的能力&a…

【Git项目部署到本地仓库】

1. 下载安装Git 根据您的操作系统&#xff0c;访问Git的官方网站&#xff1a;https://git-scm.com/download/win 具体安装教程请访问其他博客&#xff0c;例如&#xff1a;http://t.csdnimg.cn/I28VO 安装完成后&#xff0c;您可以通过在winR键输入cmd打开命令行输入 git -…

服务器设置了端口映射之后外网还是访问不了服务器

目录 排查思路参考&#xff1a; 1、确认服务是否在运行 2、确认端口映射设置是否正确 3、使用防火墙测试到服务器的连通性 4、检查服务内部的配置 5、解决办法 6、学习小分享 我们在一个完整的网络数据存储服务系统设备中都会存有业务服务器、防火墙、交换机、路由器&a…

实现一个Google身份验证代替短信验证

最近才知道公司还在做国外的业务&#xff0c;要实现一个登陆辅助验证系统。咱们国内是用手机短信做验证&#xff0c;当然 这个google身份验证只是一个辅助验证登陆方式。看一下演示 看到了嘛。 手机下载一个谷歌身份验证器就可以 。 谷歌身份验证器&#xff0c;我本身是一个基…

[springboot源码探索]返回值处理

[springboot源码探索]返回值处理 开始处理返回值 public class ServletInvocableHandlerMethod extends InvocableHandlerMethod {// ...// 返回值处理器组(组合模式,可以理解为一组返回值处理器)private HandlerMethodReturnValueHandlerComposite returnValueHandlers;publ…

编织数据经纬,洞见业务全景:Elasticsearch、Logstash与Kibana的铁三角关系深度解析

在信息化的浪潮中&#xff0c;Elasticsearch、Logstash与Kibana联手构建了一座坚固的数据城堡&#xff0c;被誉为“ELK Stack”。这三者的紧密协作&#xff0c;为企业带来了高效的数据采集、处理与分析能力&#xff0c;有力推动了业务洞察的深度与广度。本文将深入剖析Elastics…

hibernate session管理

hibernate session管理 hibernate自身提供了三种管理session的方法 session对象的生命周期与本地线程绑定 session对象的生命周期与JTA事务绑定 hibernate委托程序管理session对象的生命周期 分别对应于hibernate配置文件中hibernate.current_session_context_class属性的三个值…

C++11标准 - 声明(auto,decltype,nullptr)

C11标准 - 声明&#xff08;auto&#xff0c;decltype&#xff0c;nullptr&#xff09; 前言1. auto2. decltype3. nullptr 前言 c11提供了多种简化声明的方式&#xff0c;尤其是在使用模板时。 1. auto 在C98中auto是一个存储类型的说明符&#xff0c;表明变量是局部自动存…

ChatGPT实体化了!手机变身ChatGPT实体机器人,只需一个配件,能说话还会做梦,真的牛!

你有没有想过&#xff0c;如果有一天ChatGPT有了身体&#xff0c;跑到你办公桌上成了你的宠物&#xff0c;这是个多么有趣的场景&#xff0c;LOOI就是这样一款把幻想带进现实的产品 不得不说&#xff0c;ChatGPT让具身智能达到了新高度&#xff0c;LOOI便应运而生。 分享几个网…