Qt 重入和线程安全

重入和线程安全

在整个文档中,"重入"和 "线程安全 "这两个术语被用来标记类和函数,以表明它们在多线程应用程序中的使用方式:

  • 线程安全函数可以同时被多个线程调用,即使调用使用的是共享数据,因为共享数据的所有引用都已序列化。
  • 重入函数也可以同时被多个线程调用,但前提是每次调用都使用自己的数据。

因此,线程安全的函数总是可重入的,但可重入的函数并不总是线程安全的

推而广之,如果一个类的成员函数可以被多个线程安全调用,只要每个线程使用的是该类的不同实例,那么这个类就是可重入的。如果可以从多个线程安全地调用类的成员函数,即使所有线程都使用类的相同实例,该类也是线程安全的。

注意: 只有当 Qt 类被多个线程使用时,才会被记录为线程安全。如果函数未标记为线程安全或可重入,则不应在不同线程中使用。如果一个类未标记为线程安全或可重入,则该类的特定实例不得从不同线程访问。

重入

C++ 类通常是可重入的,原因很简单,因为它们只访问自己的成员数据。任何线程都可以调用可重入类实例的成员函数,只要其他线程不能同时调用该类同一实例的成员函数。例如,下面的Counter 类就是可重入类:

class Counter
{
public:Counter() { n = 0; }void increment() { ++n; }void decrement() { --n; }int value() const { return n; }private:int n;
};

该类不是线程安全的,因为如果多个线程试图修改数据成员n ,结果是未定义的。这是因为++ 和-- 操作符并不总是原子性的。事实上,它们通常扩展为三条机器指令:

  1. 将变量值载入寄存器。
  2. 递增或递减寄存器的值。
  3. 将寄存器的值存储回主内存。

如果线程 A 和线程 B 同时加载变量的旧值、递增寄存器并将其存储回去,那么它们最终会互相覆盖,而变量只会递增一次!

导致类不可重入的典型设计模式

  • 使用静态数据成员或全局状态
    • 如果类依赖静态变量或全局资源,多个实例或线程共享这些状态时可能引发冲突。
  • 单例模式未正确实现线程安全
    • 单例类若在初始化时未加锁,多线程可能创建多个实例,破坏单例语义。
  • 未保护共享外部资源
    • 类若操作文件、数据库连接等外部资源时未加锁,多线程访问会导致资源冲突。
  • 依赖非线程安全的第三方库
    • 若类封装了非线程安全的第三方 API,直接暴露给多线程环境会导致不可重入。
  • 成员函数修改共享内部状态
    • 若类的成员函数修改共享的成员变量,且未同步,多线程调用会破坏状态。
    • 比如缓存类(不可冲入):多线程调用 add() 可能导致 std::map 内部状态损坏。
    • class Cache {
      private:std::map<std::string, std::string> data_;
      public:void add(const std::string& key, const std::string& value) {data_[key] = value;  // 多线程写入可能破坏 map 结构}
      };

线程安全

显然,访问必须序列化:线程 A 必须不间断(原子地)执行步骤 1、2、3,然后线程 B 才能执行相同的步骤;反之亦然。让类具有线程安全的简单方法是使用QMutex 保护对数据成员的所有访问:

class Counter
{
public:Counter() { n = 0; }void increment() { QMutexLocker locker(&mutex); ++n; }void decrement() { QMutexLocker locker(&mutex); --n; }int value() const { QMutexLocker locker(&mutex); return n; }private:mutable QMutex mutex;int n;
};

QMutexLocker 类会在构造函数中自动锁定互斥体,并在函数结束调用析构函数时解除锁定。锁定互斥确保来自不同线程的访问将被序列化。mutex 数据成员使用mutable 限定符声明,因为我们需要在value() 中锁定和解锁互斥体,而 是一个常量函数。

Qt 类注意事项

许多 Qt 类都是可重入的,但它们并不是线程安全的,因为如果让它们成为线程安全的,就会产生重复锁定和解锁QMutex 的额外开销。例如,QString 是可重入的,但不是线程安全的。您可以安全地同时从多个线程访问QString 的不同实例,但无法安全地同时从多个线程访问QString 的同一实例(除非您使用QMutex 保护自己的访问)。

有些 Qt 类和函数是线程安全的。这些主要是与线程相关的类(如QMutex )和基本函数(如QCoreApplication::postEvent() )。

注: 多线程领域的术语并不完全标准化。POSIX 使用的可重入和线程安全定义与其 C API 有些不同。在 Qt 中使用其他面向对象的 C++ 类库时,请务必理解这些定义。

Reentrancy and Thread-Safety | Qt 6.8

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

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

相关文章

Elasticsearch:构建 AI 驱动的搜索体验

Elasticsearch 介绍 当你开始使用 Elastic 时&#xff0c;你将使用 Elasticsearch Relevance Engine™&#xff08;ESRE&#xff09;&#xff0c;它专为 AI 搜索应用程序提供支持。借助 ESRE&#xff0c;你可以利用一整套开发者工具&#xff0c;包括 Elastic 的文本搜索、向量…

鸿蒙生态开发

鸿蒙生态开发概述 鸿蒙生态是华为基于开源鸿蒙&#xff08;OpenHarmony&#xff09;构建的分布式操作系统生态&#xff0c;旨在通过开放共享的模式连接智能终端设备、操作系统和应用服务&#xff0c;覆盖消费电子、工业物联网、智能家居等多个领域。以下从定义与架构、核心技术…

JVM如何处理Java中的精度转换: 从源码到字节码

你好&#xff0c;我是 shengjk1&#xff0c;多年大厂经验&#xff0c;努力构建 通俗易懂的、好玩的编程语言教程。 欢迎关注&#xff01;你会有如下收益&#xff1a; 了解大厂经验拥有和大厂相匹配的技术等 希望看什么&#xff0c;评论或者私信告诉我&#xff01; 文章目录 一…

vue-next-admin修改配置指南

官方文档地址&#xff1a;vue-next-admin 1.如何开启侧边栏logo 在scr-layout-navbars-topBar-setings.vue中添加 getThemeConfig.value.isShowLogo true; 设置为true即可默认打开 2.修改侧边栏顶部的logo与文字 先把想要的图标存到我的项目然后下载 然后把后面的几个文件拉…

gin学习

gin学习笔记&#xff0c;不仅包含了基本的增删查改外&#xff0c;还包括参数传递&#xff0c;上传下载&#xff0c;模版、session与中间件等&#xff0c;方便收藏自习可用 文章目录 获得个请求get打印字符串get请求xmlget请求跳转http方法路由可以通过Context的Param方法来获取…

Flutter运行错误:UG! exception in phase ‘semantic analysis‘

最近在Mac Mini M4上通过Android Studio导入Flutter项目并运行&#xff0c;结果一直跑不起来&#xff0c;错误日志如下&#xff1a; 执行命令查看版本信息&#xff1a; flutter doctor --verbose通过输出信息Java version OpenJDK Runtime Environment (build 21.0.41242208…

【计算机网络运输层详解】

文章目录 一、前言二、运输层的功能1. 端到端通信2. 复用与分用3. 差错检测4. 流量控制5. 拥塞控制 三、运输层协议&#xff1a;TCP 和 UDP1. TCP&#xff1a;面向连接的可靠传输协议2. UDP&#xff1a;无连接的传输协议 四、端口号与进程通信1. 端口号分类2. 端口通信模型 五、…

51单片机和STM32 入门分析

51单片机和STM32是嵌入式开发中两种主流的微控制器&#xff0c;它们在架构、性能、应用场景等方面存在显著差异。以下是两者的对比分析及选择建议&#xff1a; 1. 51单片机与STM32的定义与特点 51单片机 定义&#xff1a;基于Intel 8051内核的8位微控制器&#xff0c;结构简单…

开源视觉语言模型MiniMax-VL-01:动态分辨率+4M超长文本,性能比肩GPT-4o

在人工智能领域&#xff0c;构建能够像人类一样理解、思考和行动的智能体&#xff08;AI Agent&#xff09;一直是研究人员的终极目标之一。而实现这一目标的关键在于模型是否具备足够强大的感知能力、记忆能力和推理能力。近期&#xff0c;国内人工智能公司MiniMax重磅开源了其…

excel 列单元格合并(合并列相同行)

代码 首先自定义注解CellMerge&#xff0c;用于标记哪些属性需要合并&#xff0c;哪个是主键**&#xff08;这里做了一个优化&#xff0c;可以标记多个主键&#xff09;** import org.dromara.common.excel.core.CellMergeStrategy;import java.lang.annotation.*;/*** excel…

flowable适配达梦7 (2.1)

经过第一版的问题解决&#xff0c;后端项目可以启动&#xff0c;前端页面也集成进去。 前端在流程设计页面报错 之后发现主要是组件中modelerStore这个值没有 解决方法:在data增加对象 给component/process/designer.vue 中涉及到的每个子组件传入 :modelerStore“modeler…

Prometheus Exporter系列-Mysql_Exporter一键部署

新项目旧项目都需要给研发配置mysql监控&#xff0c;这里mysql监控对应aws 阿里云 腾讯云 华为云的云mysql产品或开源自建mysql。 exporter安装虽然简单&#xff0c;经常手动操作不免让人心烦&#xff0c;一键完成省去繁琐的常规操作。 配置信息对的情况下测试多次都可以正常安…

2025年移动端开发性能优化实践与趋势分析

启动速度优化 本质&#xff1a;缩短首次可见帧渲染时间。 方法&#xff1a; iOS&#xff1a;利用Core ML本地模型轻量化部署&#xff0c;减少云端等待。Android&#xff1a;强制启用SplashScreen API&#xff0c;通过setKeepOnScreenCondition控制动画时长。冷启动需将耗时操…

【MySQL篇】DEPENDENT SUBQUERY(依赖性子查询)优化:从百秒到秒级响应的四种优化办法

&#x1f4ab;《博主介绍》&#xff1a;✨又是一天没白过&#xff0c;我是奈斯&#xff0c;从事IT领域✨ &#x1f4ab;《擅长领域》&#xff1a;✌️擅长阿里云AnalyticDB for MySQL(分布式数据仓库)、Oracle、MySQL、Linux、prometheus监控&#xff1b;并对SQLserver、NoSQL(…

全文 - MLIR Toy Tutorial Chapter 1: Toy Language and AST

Toy 语言 本教程&#xff0c;将会借助一个玩具语言来讲解&#xff0c;这个语言我们称其为 Toy。Toy 是一个基于张量的语言&#xff0c;它允许你定义函数&#xff0c;执行一些数学计算&#xff0c;并且打印结果。做这样的设定&#xff0c;是因为我们希望让教程保持简明&#xff…

排序复习_代码纯享

头文件 #pragma once #include<iostream> #include<vector> #include<utility> using std::vector; using std::cout; using std::cin; using std::endl; using std::swap;//插入排序 //1、直接插入排序&#xff08;稳定&#xff09; void InsertSort(vecto…

CSS语言的双向链表

CSS语言的双向链表 引言 在计算机科学中&#xff0c;数据结构是一个极为重要的概念&#xff0c;而链表则是最常见的数据结构之一。链表可以分为单向链表和双向链表&#xff0c;其中双向链表因其灵活性和高效性而受到广泛应用。在前端开发的领域&#xff0c;尤其是CSS&#xf…

简单理解机器学习中top_k、top_p、temperature三个参数的作用

AI系列文章&#xff1a; AWS AI认证考试中经常提及几个重要的工具介绍 简单理解机器学习中top_k、top_p、temperature三个参数的作用 用Deepseek Kimi 快速生成高质量的ppt 在机器学习中&#xff0c;top_k、top_p 和 temperature 是用于控制生成模型&#xff08;如语言模型…

红宝书第十三讲:详解JavaScript核心对象:Array、Object、Date、RegExp

红宝书第十三讲&#xff1a;详解JavaScript核心对象&#xff1a;Array、Object、Date、RegExp 资料取自《JavaScript高级程序设计&#xff08;第5版&#xff09;》。 查看总目录&#xff1a;红宝书学习大纲 一、Object&#xff1a;万物皆对象的“盒子” Object是JavaScript中…

昆仑技术重构AI大模型落地范式,长期作“加法”迎来国产生态化“拐点”

作者 | 曾响铃 文 | 响铃说 DeepSeek的爆火&#xff0c;在业内迅速掀起了一场国产化的变革。“国产大模型国产算力”软硬协同的范式正在被重构&#xff0c;AI产业国产化的含金量持续提升&#xff0c;越来越多的企业在这一趋势下加速走上数智化转型路径。 其中&#xff0c;以…