还有人认为C++容器是线程安全的吗?

news2024/11/19 9:39:59

C++标准库中的容器(如std::vector, std::list, std::map等)本身不是线程安全的、不是线程安全的、不是线程安全的,重要的事情讲三遍。这意味着如果你在多线程环境中同时访问(读或写)同一个容器实例,而没有进行适当的同步(如使用互斥锁、原子操作等),那么你的程序可能会遇到数据竞争和不一致的问题。幸运的时候你只是访问到了非预期的错误数据,但大多数情况下程序将会导致异常退出。

具体来说,C++标准库并没有为容器提供内置的线程安全机制。当你从多个线程访问容器时,必须确保:

  1. 读写分离:在任一时刻,要么只有一个线程在写入容器,要么所有线程都在读取容器,但不能同时有读和写操作。
  2. 使用同步机制:通过互斥锁(如std::mutex)、读写锁(如std::shared_mutex,C++17及以后)、条件变量、原子操作等同步机制来协调不同线程对容器的访问。

虽然C++标准库容器本身不是线程安全的,但我们可以使用类似 std::mutex 互斥锁来控制对容器的访问。以下示例展示了如何在多线程环境中安全地修改和访问 std::vector 中的数据。

示例:多线程安全地向 std::vector 添加元素

#include <iostream>  
#include <vector>  
#include <thread>  
#include <mutex>  
  
// 定义一个全局的互斥锁  
std::mutex g_mtx;  
  
// 定义一个全局的vector  
std::vector<int> g_data;  
  
// 线程函数,用于向vector中添加元素  
void add_data(int value) {  
    // 锁定互斥锁  
    std::lock_guard<std::mutex> lock(g_mtx);  
  
    // 安全地向vector中添加元素  
    g_data.push_back(value);  
  
    // lock_guard的析构函数会自动解锁互斥锁  
}  
  
int main() {  
    // 创建并启动10个线程,每个线程向vector中添加一个唯一的值  
    std::thread threads[10];  
    for (int i = 0; i < 10; ++i) {  
        threads[i] = std::thread(add_data, i);  
    }  
  
    // 等待所有线程完成  
    for (auto& th : threads) {  
        th.join();  
    }  
  
    // 输出vector的内容  
    for (int val : g_data) {  
        std::cout << val << ' ';  
    }  
    std::cout << std::endl;  
  
    return 0;  
}

以上示例我们定义了一个全局的 std::vector g_data 用于存储数据,和一个全局的 std::mutex g_mtx 用于同步对 data 的访问。add_data 函数接收一个 int 类型的参数 value,并使用 std::lock_guard(std::mutex) 来自动管理对 g_mtx 的锁定和解锁。

在 main 函数中,我们创建了一个 std::thread 数组 threads,并循环启动 10 个线程,每个线程调用 add_data 函数并传入一个唯一的值。

通过调用每个线程的 join 方法,等待所有线程完成它们的任务。确保在输出 g_data 的内容之前,所有元素都已被安全地添加到 data 中。

最后,遍历 g_data 并输出其内容。由于使用了互斥锁,可以确信将输出所有线程成功添加的元素。

-End-

#想了解更多精彩内容,关注下方公众号。

本人小杨哥:

超20年C++开发经验,独立软件开发;著名开源产品高并发C++应用服务器MYCP作者;开源企业即时通讯软件Entboost首席架构师;开发有【WordBN字远笔记】等共享软件产品。

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

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

相关文章

力扣14.最长公共前缀

思路&#xff1a;将字符串数组中第一个字符串用作参考&#xff1b; 8.将他的长度作为范围&#xff0c;因为超范围了之后就不会再有公共前缀了 9.将字符串数组的长度也作为范围&#xff0c;意思是便利字符串数组中的字符串 11.开始第一层循环&#xff0c;依次遍历第一个字符串的…

Python代码:作为程序员这22个Python单行代码,你还不知道吗?

每个程序员都必须知道的22个Python单行代码是一个相对主观的列表&#xff0c;因为不同的程序员可能会根据自己的经验和需求来定义哪些代码是“必须知道”的。不过&#xff0c;我可以根据Python的常用性和实用性&#xff0c;为你提供一系列非常有用且简洁的Python单行代码及其源…

51单片机 - DS18B20实验1-读取温度

上来一张图&#xff0c;明确思路&#xff0c;程序整体裤架如下&#xff0c;通过单总线&#xff0c;单独封装一个.c文件用于单总线的操作&#xff0c;其实&#xff0c;我们可以把点c文件看成一个类操作&#xff0c;其属性就是我们面向对象的函数&#xff0c;也叫方法&#xff0c…

Linux echo,printf 命令

参考资料 【Linux】ハイフンをいっぱい出したかっただけなのに【printfコマンド】 目录 一. echo命令1.1 -n 选项1.2 -e 选项1.3 配合扩展实现批量换行输出1.3.1 xargs -n 11.3.2 tr \n1.3.3 xargs printf "%s\n"1.4 ANSI转义序列1.5 彩色文本输出 二. printf 命令…

Centos7安装gitlab-ce(rpm安装方式)

本章教程&#xff0c;主要介绍如何在Centos7安装gitlab-ce。 一、安装基础环境 安装gitlab-ce之前&#xff0c;我们需要安装一下jdk版本。 sudo yum install java-11-openjdk-devel二、下载安装包 这里我们下载的是rpm包。更多gitlab-ce版本可以在这里查看&#xff1a;https://…

果蔬识别系统架构+流程图

相关文章和代码 果蔬识别系统 果蔬识别系统优化&#xff08;1~5&#xff09; 架构图 流程图 初始化 识别流程 学习流程 同步流程 与初始化类似&#xff0c;只是同步只同步一个storeCode数据 删除数据流程 导入数据

无人机几种常见的避障系统!!!

1. 视觉避障系统 工作原理&#xff1a; 视觉避障系统通过安装在无人机上的摄像头捕捉周围环境的图像&#xff0c;利用计算机视觉技术对图像进行处理和分析&#xff0c;提取出障碍物的信息。 通过对障碍物的识别和分类&#xff0c;无人机可以判断出障碍物的性质和危险程度&am…

AI 时代程序员的挑战与机遇

你好&#xff0c;我是看山。 在当今数字化快速发展的时代&#xff0c;AIGC&#xff08;如 ChatGPT、Midjourney、Claude 等&#xff09;大语言模型如雨后春笋般接二连三的涌现&#xff0c;与此同时&#xff0c;AI 辅助编程工具也日益普及。 这一系列的变化使得程序员的工作方…

pdf文件怎么转换成ppt?介绍几种pdf转ppt的方法

pdf文件怎么转换成ppt&#xff1f;将pdf文件转换成ppt格式是一种常见且实用的需求&#xff0c;特别是在制作演示文稿和准备报告时。pdf格式因其文件内容的固定排版和高兼容性而广泛应用于文档的保存和分享。然而&#xff0c;在某些情况下&#xff0c;将pdf文件转换为ppt格式可以…

拒绝千篇一律,AI帮你定制独一无二的个人写真

每个女人都渴望展现最美的自己&#xff0c;你是否厌倦了拍出千篇一律的照片&#xff1f;今天&#xff0c;我要告诉你一个秘密&#xff0c;用简单三步&#xff0c;即可打造属于你的独一无二个人写真&#xff01;文生图、蒙版换脸、图生图&#xff0c;三步化身超级模特&#xff0…

Java代码审计篇 | ofcms系统审计思路讲解 - 篇4 | XXE漏洞审计

文章目录 Java代码审计篇 | ofcms系统审计思路讲解 - 篇4 | XXE漏洞审计0. 前言1. XXE代码审计【有1处】1.1. 搜索JRXmlLoader1.1.1. JRAntApiWriteTask1.1.2. JRAntUpdateTask1.1.3. TableReportContextXmlRule1.1.4. JasperCompileManager【存在漏洞】 1.2. 搜索XMLReader1.2…

C++初阶:类和对象(上)

&#x1f680;前言&#xff1a; 本文主要讲述了&#xff0c;面向过程和面向对象&#xff0c;并引入类&#xff0c;然后就以类为基础并讲解。 目录 &#x1f349;1.面向过程和面向对象的初步认识&#xff1a; &#x1f952;2.类的引入&#xff1a; &#x1f351;3.类的定义…

dd 命令:复制和转换文件

一、dd 命令简介 ​dd​ 命令是一个在 Unix 和类 Unix 系统中用于复制文件和转换文件的命令行工具。它的功能非常强大&#xff0c;可以用于各种目的&#xff0c;例如创建镜像文件、备份和恢复数据、复制数据等。 ​dd​ 是一个用于读取、转换和写入数据的工具&#xff0c;通常…

Metasploit 渗透测试之Metasploit快速入门

简介 Metasploit 是目前世界上领先的渗透测试工具&#xff0c;也是信息安全与渗透测试领域最大的开源项目之一。它彻底改变了我们执行安全测试的方式。Metasploit之所以流行&#xff0c;是因为它可以执行广泛的安全测试任务&#xff0c;从而简化渗透测试的工作。Metasploit 适…

海外云手机怎么实现TikTok多账号防关联?

TikTok多账号运营&#xff0c;作为众多用户选择的引流策略&#xff0c;旨在通过多账号的协同作用&#xff0c;更快速、高效地推动主账号的流量增长。然而&#xff0c;这一策略面临着一个关键难题——TikTok账号防关联。本文将简要介绍海外云手机如何解决这一问题。 在TikTok多账…

解题 - 模拟实现 atoi

文章目录 前言 一、atoi 函数是什么&#xff1f; 二、模拟实现 atoi 总结 前言 路漫漫其修远兮&#xff0c;吾将上下而求索&#xff1b; 一、atoi 函数是什么&#xff1f; atoiint atoi(const char* str);所要引用的头文件: <stdlib.h>原理&#xff1a;将字符串转换…

计算几何学习

凸包 凸组合&#xff0c; λ < λ 1 , λ 1 , . . . , λ n > T \lambda <\lambda_1,\lambda_1,...,\lambda_n>^T λ<λ1​,λ1​,...,λn​>T 其中 λ 1 λ 2 . . . λ n 1 \lambda_1\lambda_2...\lambda_n 1 λ1​λ2​...λn​1,且 λ i ≥ 0 \l…

深度解析 MintRich 独特的价格曲线机制玩法

随着 Meme 币赛道的迅速崛起&#xff0c;NFT 市场也迎来了新的变革。作为一个创新的 NFT 发行平台&#xff0c;Mint.Rich 正掀起一场全民参与的 NFT 热潮。其简易的操作界面和独特的价格曲线设计&#xff0c;让任何人都能以极低的门槛发行和交易自己的 NFT&#xff0c;从而参与…

多线程实现数据处理与打印分离

注意&#xff0c;结构体传入数据 一开始int* 不能变成void 传入int ** 也会失效&#xff0c; 只能一开始在message 结构体里有 int* 类型才能运行 这是通过打印表格得到的 使用raylib 开发 #include <raylib.h> #include <stdio.h> #include <math.h> #…

【零成本】七日杀 服务器搭建 异地联机 无需公网IP、服务器

主要内容 什么是七日杀 搭建前需要准备什么 详细步骤 1.Steam中下载七日杀服务器工具 2.修改七日杀服务配置文件 3.启动七日杀服务器应用 4.运行 MoleSDN 进行异地联机 5.小伙伴打开游戏加入 鼠鼠的服务器 什么是七日杀 《七日杀》是一款沙盒生存恐怖游戏&#xff0c;…