当前位置: 首页 > news >正文

C++编程实践——多线程变量共享问题展开分析

一、问题现象描述

在C++编程的技术点中,多线(进)程的编程是一个非常让人上头的内容。这种情况其实还可以拓展到一些抽象的场景,比如信号、消息和异步等情况。它们看上去和多线程关系不大,但其实内部和多线程都有着密不可分的关系(注意,没说联系,因为有些是类似与多线程应用的情况)。
在多线程编程中,有经验的开发者可能遇到过这种情况,当它们通过一个变量来交换某个状态或数据时,往往在开发和测试时都是没有问题的,但在部署到生产上时,一个月内偶尔会有一两次出现异常的问题。甚至在某些特殊情况下,还会出现偶尔崩溃的情况。这种问题,非常难于定位,而且非常不容易解决。

二、原因分析和说明

上面的问题表面看来没有什么复杂的,但其实内部有多种可能。而这些可能往往有的时候都想不到其中涉及到的知识面的宽度。下面对其中主要的进行一下分析说明:

  1. 多线程竞态
    Race condition,这种情况是开发者最容易想到的,也是最容易解决类似的问题的一种相对有效的方法。但这种方式让开发者有很不爽的地方,就是太重。不光影响效率还增加了代码的复杂度。这就需要开发者根据实际情况来斟酌选择。
  2. 缓存读写
    也就是常见的内存可见性的问题,就是在多线程的情况下,由于缓存的存在,导致更新无法被及时的响应,从而导致数据的不可见。另外还有缓存Line的问题,导致缓存被意外更新的情况。
  3. 指令乱序
    这种情况虽然不少见,但比较容易被人理解的是单实例中double check的问题
  4. 原子破坏性
    这种情况比较少见,但同样出现问题不好调试。比较典型的是就是早期某些第三方提供的在32位系统上用多个int来模拟int64甚至更长的长整型数据时,导致的数据异常。

三、定位问题

解决问题的方法是先找到并确定问题,然后再根据实际问题的情况来解决这些问题。对于问题的查找和调试可以采用下面的方法:

  1. 内存控制
    现代计算机中一般是多核系统,为了控制内存读写,可以使用内存屏障,比如使用:
#defineMEMORY_BARRIER()asmvolatile("mfence":::"memory")
  1. 打印日志
    在特定的代码中,对于不稳定态的情况下可以增加日志相关的代码。不过,有一点麻烦的是要考虑打印的线程安全性。
  2. 编译器中处理
    有两种情况,一种是启用编译器屏障;另外一种是严格控制编译器的优化。前者可以使用:
// 禁止编译器重排序#defineCOMPILER_BARRIER()asmvolatile("":::"memory")// 在代码中thread_shared_data=new_data;COMPILER_BARRIER();

后者则要根据情况来确定与编译器优化的关系的大小,并根据情况来缩小优化的控制。

四、解决办法

只有了解你的敌人,才能更好的打败他。既然明白了问题的来源,那么解决的思路也就有了,主要有:

  1. 使用锁
    正如上面所分析的,除了太重,没有别的坏处。这算是最安全的方法
  2. 使用原子变量
    这其实可以理解成第一种的一种轻量版。没有什么特别说明的
  3. 使用volatile关键字
    这种一般用于简单的场景下的操作,特别是在IO的操作过程中,不过不要迷信它。记住这一点就够了
  4. 其它
    在某些特殊场景如信号、消息等中,可以利用一些特定的方法如信号的屏蔽以及事件处理等来控制。这里就不再展开了。

总之,解决问题的方法有很多,细节就看开发者自己确定问题后能够采取哪种方法来应对了。不必拘泥于教条和书本。

五、总结

正如大家看到一个苹果上有一个小黑点,未必认为会是什么问题,亦或者认为削皮时多削一点就好了。但实际上打开后,内部可能整个苹果都烂得差不多了。本文提到的问题,其实也是这种情况,虽然问题不大,但真要解决进去,会发现可能会涉及到不少的知识面。与诸君共勉!

http://www.cnnetsun.cn/news/142985.html

相关文章:

  • 【Android FrameWork】第三十六天:随机数EntropyMixer
  • 介观交通流仿真软件:VISSIM (介观模式)_(16).高级仿真技术
  • 安卓 之 PassthruPatchRecord
  • YOLOv8 训练与检测系统智慧化交通公路上落石检测数据集 智慧道路交通路面障碍物检测数据集 智慧交通、山区公路监控、应急预警平台 YOLOv8 训练与检测系统
  • 基于django智慧农业管理系统设计开发实现
  • Android架构师面试指南:基于跨越速运职位要求的全面解析与参考答案
  • 【2025最新】基于SpringBoot+Vue的企业项目管理系统管理系统源码+MyBatis+MySQL
  • 企业级大学生考勤系统管理系统源码|SpringBoot+Vue+MyBatis架构+MySQL数据库【完整版】
  • 【2025最新】基于SpringBoot+Vue的物资综合管理系统管理系统源码+MyBatis+MySQL
  • 数学梗图数据集分析报告:999张高质量数学主题幽默图片资源
  • 【毕业设计】SpringBoot+Vue+MySQL 美食信息推荐系统平台源码+数据库+论文+部署文档
  • AI核心知识59——大语言模型之Mamba(简洁且通俗易懂版)
  • SpringBoot+Vue 流浪动物救助平台平台完整项目源码+SQL脚本+接口文档【Java Web毕设】
  • SpringBoot+Vue 手机销售网站管理平台源码【适合毕设/课设/学习】Java+MySQL
  • DPJ-138 基于单片机的指纹密码锁系统设计(源代码+proteus仿真)
  • SpringBoot+Vue 流浪动物救助平台管理平台源码【适合毕设/课设/学习】Java+MySQL
  • 【2025最新】基于SpringBoot+Vue的考试系统管理系统源码+MyBatis+MySQL
  • 企业级流浪动物救助平台管理系统源码|SpringBoot+Vue+MyBatis架构+MySQL数据库【完整版】
  • 物资综合管理系统信息管理系统源码-SpringBoot后端+Vue前端+MySQL【可直接运行】
  • MLX 有多快?在 8 个苹果硅芯片和 4 个 CUDA GPU 上的全面基准测试
  • 生产就绪特性-从开发到部署的完整解决方案
  • 【前端知识点总结】Promise的介绍
  • 2026年河北省职业院校技能大赛“网络系统管理”(高职组)系统服务-Linux部署样题
  • 当 AI 写论文遭遇 “答辩级拷问”:9 款主流工具的生死考验
  • 科研人的 “数据魔咒”:明明数据在手,却挖不出核心结论
  • [特殊字符] 写论文软件哪个好?先看毕业党最在意的 4 大核心标准
  • 历年贵州大学计算机保研复试机试真题
  • AI产业融合纵深发展,治理创新护航智能未来
  • 生成式AI重构内容生态,人机协同定义创作新范式
  • 软件世界的契约:理解开源协议的逻辑与边界