QT原子变量:QAtomicInteger、QAtomicPointer、QAtomicFlag

引言:原子变量为何重要?

在多线程编程中,共享数据的原子性访问是保证线程安全的核心。传统互斥锁虽然有效,但会带来性能损耗和死锁风险。QT提供的原子类型(QAtomicIntegerQAtomicPointerQAtomicFlag)通过硬件级原子指令,实现了高效的无锁并发操作。本文将深入解析每种原子类型的使用场景及最佳实践。


一、QT原子类型详解与场景分析

1. QAtomicInteger<T>:整数原子操作

适用场景

  • 计数器:多线程环境下的计数(如请求次数统计)

  • 状态标志:非布尔类型的多状态标记(如0=空闲,1=运行中,2=终止)

  • 资源分配:原子分配ID或索引(避免重复分配)

典型示例

// 全局请求计数器
QAtomicInt requestCount(0);void handleRequest() {requestCount.fetchAndAddRelaxed(1);  // 原子递增// ...处理请求逻辑...
}

2. QAtomicPointer<T>:指针原子操作

适用场景

  • 无锁数据结构:实现无锁队列、栈等(见后文案例)

  • 单例对象指针:双重检查锁定模式中的指针原子操作

  • 动态对象切换:原子替换复杂对象的指针(如配置热更新)

示例代码

// 原子切换全局配置
QAtomicPointer<Config> globalConfig;void updateConfig(Config* newConfig) {Config* old = globalConfig.loadAcquire();while (!globalConfig.testAndSetRelaxed(old, newConfig)) {old = globalConfig.loadAcquire();}delete old;  // 安全释放旧配置
}

3. QAtomicFlag:轻量级布尔标志

适用场景

  • 一次性初始化:确保资源只初始化一次(替代pthread_once

  • 简单状态锁:作为轻量级锁(适用于极低竞争场景)

  • 任务启停控制:原子标记任务是否正在运行

实战案例

QAtomicFlag initializedFlag;void initializeResource() {if (!initializedFlag.testAndSetRelaxed(false, true)) {return;  // 已被其他线程初始化}// 执行初始化操作(仅一次)
}

二、高级场景与类型选择技巧

1. 如何选择原子类型?

需求场景推荐类型原因
需要增减数值QAtomicInteger<int>提供fetchAndAdd等原子算术操作
需要操作对象指针QAtomicPointer<T>支持指针的CAS(Compare-And-Swap)操作
简单的是/否状态判断QAtomicFlagQAtomicInt更轻量(仅需1字节存储)

2. 复杂场景组合应用

案例:无锁对象池

template<typename T>
class ObjectPool {
public:T* acquire() {Node* oldHead = head.loadRelaxed();while (oldHead && !head.testAndSetRelaxed(oldHead, oldHead->next)) {oldHead = head.loadRelaxed();}return oldHead ? oldHead->data : nullptr;}private:struct Node {T* data;Node* next;};QAtomicPointer<Node> head;  // 使用原子指针管理链表头
};

三、内存模型与性能优化指南

1. 内存顺序的选择策略

内存顺序适用场景
Relaxed单一变量的原子性保证(如计数器)无需线程间顺序约束
Acquire-Release需要建立线程间同步(如初始化完成后其他线程才能读取数据)
SequentiallyConsistent严格的全局顺序(默认模式,性能最低)

正确使用示例

// 线程安全延迟初始化
QAtomicPointer<HeavyObject> instance;
QAtomicFlag initialized;HeavyObject* getInstance() {if (!initialized.loadAcquire()) {          // Acquire保证看到最新状态QMutexLocker lock(&mutex);if (!initialized.loadRelaxed()) {instance.storeRelease(new HeavyObject);  // Release确保初始化完成initialized.storeRelease(true);}}return instance.loadAcquire();
}

2. 性能陷阱规避

  • 避免过度原子化:仅对真正共享的变量使用原子操作

  • 警惕ABA问题:使用QAtomicPointer时,结合版本号(QT的QAtomicPointer支持版本标记)

  • 平台适配性:ARM等弱内存模型平台需严格测试内存顺序


四、QT原子变量 vs C++11原子类型

从QT5到QT6的过渡建议:

特性QAtomic系列std::atomic
跨平台兼容性支持旧编译器(C++98)需要C++11支持
内存顺序控制提供Acquire/Release语义提供更细粒度的6种内存顺序
指针操作专有QAtomicPointerstd::atomic<T*>
推荐使用场景QT5项目、嵌入式开发QT6新项目、现代C++开发

五、总结与最佳实践

  1. 类型选择三要素:操作类型(整型/指针)、性能需求、内存顺序要求

  2. 简单原则:能用QAtomicFlag就不选QAtomicInt

  3. 复合操作仍需锁:原子变量无法替代所有互斥锁(例如需要保护多个变量的关联操作)

  4. 测试验证:使用ThreadSanitizer等工具验证原子操作的正确性

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

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

相关文章

大模型金融企业场景落地应用

一、商业银行体系 1. 江苏银行 企业背景&#xff1a;江苏银行是总部位于江苏南京的全国性股份制商业银行&#xff0c;在城商行中资产规模位居前列&#xff0c;积极拥抱金融科技&#xff0c;将数字化转型作为核心战略之一。近年来&#xff0c;江苏银行持续加大在人工智能、大数…

卡特兰数在数据结构上面的运用

原理 Catalan数是一个数列&#xff0c;其第n项表示n个不同结点可以构成的二叉排序树的数量。Catalan数的第n项公式为&#xff1a; &#xfffc; 其中&#xff0c;&#xfffc;是组合数&#xff0c;表示从2n个元素中选择n个元素的组合数。 Catalan数的原理可以通过以下方式理解&…

影视后期工具学习之PR(中)

pr剪辑之旅----声音设计 第五课 镜头语言和绿幕抠像 超级键效果(超级键通过简单的吸管取色和参数调整,即可实现专业级抠像与合成效果。无论是绿幕替换背景,还是创意双重曝光,都能轻松驾驭。建议结合「Alpha 通道」视图观察透明区域,逐步优化细节,最终导出高质量视频。)…

使用BootStrap 3的原创的模态框组件,没法弹出!估计是原创的bug

最近在给客户开发一个CRM系统&#xff0c;其中用到了BOOTSTRAP的模态框。版本是3。由于是刚开始用该框架。所以在正式部署到项目中前&#xff0c;需要测试一下&#xff0c;找到框架中的如下部分。需要说明的是。我用的asp.net mvc框架开发。测试也是在asp.net mvc环境下。 复制…

Camera2 与 CameraX 闲谈

目录 &#x1f4c2; 前言 1. &#x1f531; Camera2 2. &#x1f531; CameraX 3. &#x1f531; Camera2 与 CameraX 1&#xff09;使用复杂度与开发效率 2&#xff09;控制能力与应用场景 3&#xff09;设备兼容性与稳定性 4&#xff09;更新与维护 4. &#x1f4a0…

【大语言模型_8】vllm启动的模型通过fastapi封装增加api-key验证

背景&#xff1a; vllm推理框架启动模型不具备api-key验证。需借助fastapi可以实现该功能 代码实现&#xff1a; rom fastapi import FastAPI, Header, HTTPException, Request,Response import httpx import logging# 创建 FastAPI 应用 app FastAPI() logging.basicConfig(…

基于SpringBoot的名著阅读网站

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

Langchain 自定义工具和内置工具

使用介绍 自定义工具时的元素概念介绍 在Langchain中&#xff0c;工具&#xff08;Tool&#xff09;是与语言模型交互的基本单元。以下是自定义工具时的关键元素&#xff1a; name 定义&#xff1a;工具的名称&#xff0c;用于唯一标识该工具。作用&#xff1a;当工具被集成…

Gitee上库常用git命令

Gitee上库常用git命令 1、Fork 项目2、个人仓库修改3、追加提交4、创建PR5、多笔commit合一 1、Fork 项目 2、个人仓库修改 git add . // -s 表示自动添加邮箱签名信息&#xff0c;-m表示其后跟随commit描述 git commit -sm “add transition freeze” git push origin [目标…

Java 大视界 -- Java 大数据在智慧农业精准灌溉与施肥决策中的应用(144)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…

Redux,React-redux。基础

状态管理库&#xff0c;集中式存储状态&#xff0c;管理状态 ✅ redux //简单实现 redux源码 export function createStore(reducer) {// reducer由用户编写&#xff0c; 必须是一个函数&#xff0c;dispatch的时候&#xff0c;reducer要执行if (typeof reducer ! function) t…

5.2 位运算专题:LeetCode 268. 丢失的数字

1. 题目链接 LeetCode 268. 丢失的数字 2. 题目描述 给定一个包含 [0, n] 范围内 n 个不同整数的数组 nums&#xff08;实际长度为 n&#xff09;&#xff0c;找出数组中缺失的那个数字。 示例&#xff1a; 输入&#xff1a;nums [3,0,1] → 输出&#xff1a;2&#xff08;…

基于第三方库的人脸识别系统的设计与实现

标题:基于第三方库的人脸识别系统的设计与实现 内容:1.摘要 本文针对传统人脸识别系统开发复杂、效率低的问题&#xff0c;旨在设计并实现基于第三方库的人脸识别系统。通过选用合适的第三方人脸识别库&#xff0c;利用其成熟的算法和接口&#xff0c;简化系统开发流程。对收集…

【Android】VehiclePropertyAccess引起CarService崩溃

VehiclePropertyAccess引起CarService崩溃 VehiclePropertyAccess VehiclePropertyAccess属性&#xff0c;用于定义车辆属性的访问权限。权限包括 读&#xff1a;READ&#xff0c;只可以读取&#xff0c;不能写入。 VehiclePropertyAccess:READ写&#xff1a;WRITE&#xf…

【Go】Go语言并发模型:MPG

Go 语言并发模型&#xff1a;MPG Go 的并发模型主要由三个部分构成&#xff1a; M (Machine) 系统线程&#xff0c;用于实际执行任务。 P (Processor) 逻辑处理器&#xff0c;负责管理和调度 goroutine。每个 P 拥有一个本地队列和关联的全局 G 队列。 G (Goroutine) Go 语言…

SpringCloud配置中心:Config Server与配置刷新机制

文章目录 引言一、Config Server基础架构1.1 Server端配置1.2 配置文件命名规则 二、Config Client配置2.1 Client端配置2.2 配置注入与使用 三、配置刷新机制3.1 手动刷新配置3.2 使用Spring Cloud Bus实现自动刷新3.3 配置仓库Webhook自动触发刷新 四、高级配置管理策略4.1 配…

PyTorch生成式人工智能实战:从零打造创意引擎

PyTorch生成式人工智能实战&#xff1a;从零打造创意引擎 0. 前言1. 生成式人工智能1.1 生成式人工智能简介1.2 生成式人工智能技术 2. Python 与 PyTorch2.1 Python 编程语言2.2 PyTorch 深度学习库 3. 生成对抗网络3.1 生成对抗网络概述3.2 生成对抗网络应用 4. Transformer4…

allure结合pytest生成测试报告

结合 pytest 和 Allure 可以生成详细而美观的测试报告&#xff0c;帮助测试人员和开发者更好地理解测试结果。这包括测试的执行情况、步骤、附件&#xff08;如截图&#xff09;、分类以及优先级标记。下面是如何在 pytest 中使用 Allure 生成测试报告的步骤&#xff1a; 安装…

STM32标准库开发中断流程

在STM32标准外设库&#xff08;SPL&#xff09;开发中&#xff0c;外设中断的处理流程通常如下&#xff1a; 一、标准库外设中断处理流程 &#xff08;1&#xff09;使能外设时钟 在使用任何外设之前&#xff0c;都必须打开外设的时钟。例如&#xff0c;使用USART1的中断&…

【计算机网络】-计算机网络期末复习题复习资料

一、计算机网络体系结构&#xff08;800字&#xff09; 1. OSI参考模型 七层结构&#xff1a;物理层→数据链路层→网络层→传输层→会话层→表示层→应用层 各层核心功能&#xff1a; 物理层&#xff1a;比特流传输&#xff08;如RJ45、光纤接口&#xff09; 数据链路层&…