C++11之线程
编译环境:Qt

join:阻塞当前线程,直到线程函数退出
detach:将线程对象与线程函数分离,线程不依赖线程对象管理
注:join和detach两者必选其一,否则线程对象的回收会影响线程的回收,导致程序崩溃
思考:执行detach之后的线程如何退出?
- 方法:设置标志位
#include "dialog.h"
#include<iostream>
using namespace std;
#include <QDebug>
#include<thread>#include <QApplication>int add(int a,int b)
{qDebug()<<"add";qDebug()<<"a+b = "<<a+b;_sleep(1000);return a+b;
}class AA
{
public:AA(){//在构造函数中创建线程//如果使用_beginthreadex 线程函数是staticthread th(&threadFun,this);th.detach();}//执行detach之后线程如何退出//设置标志位void threadFun(){while(!m_isQuit){_sleep(100);qDebug()<<"do some work";}}
private:bool m_isQuit = false;
};int main(int argc, char *argv[])
{QApplication a(argc, argv);{thread th(&add,3,4);//线程函数可以以参数形式传入//join函数 阻塞当前线程 直到线程函数退出
// _sleep(100);
// qDebug()<<"before join";
// th.join();
// qDebug()<<"thread join";//detach 将线程对象与线程函数分离,线程不依赖线程对象管理qDebug()<<"before detach";th.detach();qDebug()<<"after detach";//注:join和detach两者必选其一,否则线程对象的回收会影响线程的回收,导致程序崩溃}Dialog w;w.show();return a.exec();
}
看下面一段代码:

执行结果不等于300,为什么?
- ++g_value时分为三步:读,自增,写。在多线程情况下,可能存在多个线程读或写同一个值的情况,这就使得结果小于我们预期的值了。
线程并发引发的数据问题:
并发:同一时间间隔内,程序交替执行
解决:线程同步
线程同步:同一时间,只允许一个线程访问资源
实现线程同步方法:
- 互斥锁
- 读写锁
- 条件变量
- 原子操作
- 信号和槽
- 事件循环
1、互斥锁

lock_guard 与 unique_lock 管理互斥锁,让互斥锁使用更方便、更安全(可以避免死锁,比如我们使用完锁忘记释放了)
lock_guard 与 unique_lock 遵循RAII
- RAII,资源获取即初始化,是C++很重要的思想。

思考:如果需要在中途释放锁,怎么办?
- 使用 unique_lock
- 使用 lock_guard + 花括号实现,即锁一部分

锁锁定代码长度称为粒度,锁定的代码长度越长,锁的粒度越大,影响并发的效率。
2、条件变量
#include<condition_variable>
std::condition_variable con_var;con_var.notify_one();(通知一个)
con_var.notify_all();(通知所有)
con_var.wait();
wait() 函数:
- 有两个参数:第一个参数:是一个已经上锁的互斥锁(unique_lock),第二个参数:是一个可调用对象,其中包含函数指针,仿函数,bind ,lambda表达式
- 如果这个函数执行返回值是false ,就会通知无效,可以避免误通知
- 作用:阻塞当前线程,直到收到通知 notify_one notify_all
- 当调用wait时,释放互斥锁,阻塞当前线程,将线程放入条件变量等待的容器中
- 当收到通知时,获取互斥锁,执行后续代码
- wait()和通知的关系:在使用的时候,一定是wait之后才能收到通知,否则会失效

运行结果:
先打印出三个"before wait",之后每点击一下按钮,打印一个"after wait"

![]()
举例:

现在我们改变一下:

运行结果:
我们第一次按下按钮,quit取非为真,此时打印"after wait",再次按下,此时quit取非为假,此时无反应,第三次按下,此时quit又为真,打印"after wait"......
3、原子操作
#include<atomic>
atomic<int> cnt(0);
- cnt++;
- cnt--;
- cnt.load();
#include "dialog.h"#include<iostream>
using namespace std;#include <QDebug>
#include<thread>
#include <QApplication>#include<atomic>
atomic<int> cnt(0);void AutomicFunc()
{for(int i=0;i<100;i++){_sleep(10);//cnt++; //加锁的方式进行++,是原子操作,线程安全cnt = cnt + 1; //非原子操作,线程不安全_sleep(10);}
}int main(int argc, char *argv[])
{QApplication a(argc, argv);{thread th[3];for(int i=0;i<3;i++){th[i] = thread(&AutomicFunc);}for(int i=0;i<3;i++){th[i].join();}}qDebug()<<"count = "<<cnt.load();//取值Dialog w;w.show();return a.exec();
}
如有问题,欢迎交流指正!
相关文章:
C++11之线程
编译环境:Qt join:阻塞当前线程,直到线程函数退出 detach:将线程对象与线程函数分离,线程不依赖线程对象管理 注:join和detach两者必选其一,否则线程对象的回收会影响线程的回收,导致…...
界星空科技漆包线行业称重系统
万界星空科技为漆包线行业提供的称重系统是其MES制造执行系统解决方案中的一个重要组成部分。以下是对该系统的详细介绍: 一、系统概述 万界星空科技漆包线行业称重系统,是集成在MES系统中的一个功能模块,专门用于漆包线生产过程中的重量检…...
RabbitMQ的高级特性-事务
事务:RabbitMQ是基于AMQP协议实现的, 该协议实现了事务机制, 因此RabbitMQ也⽀持事务机制. SpringAMQP也提供了对事务相关的操作. RabbitMQ事务允许开发者确保消息的发送和接收是原⼦性的, 要么全部成功, 要么全部失败 配置事务管理器: Bean public Ra…...
Qt Linguist手册
概述 Qt 为将 Qt C 和 Qt Quick 应用程序翻译成当地语言提供了出色的支持。发布经理、翻译和开发人员可以使用 Qt 工具来完成他们的任务。 发布经理对应用程序的发布负总责。通常,他们负责协调开发人员和翻译人员的工作。他们可以使用 lupdate 工具同步源代码和翻…...
【简介Sentinel-1】
Sentinel-1是欧洲航天局哥白尼计划(GMES)中的地球观测卫星,由Sentinel-1A和Sentinel-1B两颗卫星组成。以下是对Sentinel-1的详细介绍: 一、基本信息 卫星名称:Sentinel-1 所属计划:欧洲航天局哥白尼计划…...
第 17 场小白入门赛蓝桥杯
第 17 场小白入门赛 2 北伐军费 发现每次选大的更优,所以可以排序之后,先手取右边,后手取左边。 实际发现,对于 A − B A-B A−B 的结果来说,后手对于这个式子的贡献是 − − a i --a_i −−ai ,也就…...
@antv/x6 导出图片下载,或者导出图片为base64由后端去处理。
1、导出为文件的格式,比如 PNG graph.exportPNG(function (dataURL) {console.log(dataURL);let img document.getElementById(img) as HTMLImageElement;img.src dataURL;},{backgroundColor: #fff,padding: [20, 20, 20, 20],quality: 1,width: graph.options.w…...
从零到精通:AI大模型的全方位学习路径解析,非常详细收藏我这一篇就够了
一、初聊大模型 1、什么是大模型? 大模型,通常指的是在人工智能领域中的大型预训练模型。你可以把它们想象成非常聪明的大脑,这些大脑通过阅读大量的文本、图片、声音等信息,学习到了世界的知识。这些大脑(模型&…...
PowerShell脚本在自动化Windows开发工作流程中的应用
PowerShell脚本在自动化Windows开发工作流程中的应用 在当今快速迭代的软件开发环境中,自动化已成为提高开发效率、减少人为错误、保障项目稳定性的重要手段。特别是在Windows平台上,PowerShell以其强大的脚本编写能力和对系统管理的深度集成࿰…...
【力扣 | SQL题 | 每日四题】力扣1783,1757,1747,1623,1468,1661
昨天晚上睡着了,今天把昨天的每日一题给补上。 1. 力扣1783:大满贯数量 1.1 题目: 表:Players ------------------------- | Column Name | Type | ------------------------- | player_id | int | | player_na…...
《深入探究 C++中的函数模板特化:开启编程新境界》
在 C的广袤世界中,函数模板特化是一项强大而富有魅力的技术,它为程序员提供了更高的灵活性和效率。本文将带你深入了解 C中函数模板特化是如何实现的,揭开这一神秘面纱,让你在编程之路上更上一层楼。 一、函数模板的基础概念 在…...
RTEMS面试题汇总及参考答案
目录 RTEMS是什么?它在嵌入式系统中扮演什么角色? RTEMS的全称是什么? RTEMS的主要特点有哪些? RTEMS支持哪些处理器架构? RTEMS的可剥夺型内核和不可剥夺型内核有何不同? RTEMS 的微内核设计及其优势 RTEMS 如何实现多任务处理和调度 RTEMS 的任务调度策略有哪…...
螺蛳壳里做道场:老破机搭建的私人数据中心---Centos下Docker学习03(网络及IP规划)
3 网络及IP规划 3.1 容器连接网络初步规划 规划所有容器与虚拟机的三张网卡以macvlan的方式进行连接(以后根据应用可以更改),在docker下创建nat、wifi、nei、wai四张网卡,他们和虚拟机及宿主机上NIC的相关连接参数如下表所示&am…...
BLOOM 模型的核心原理、局限与未来发展方向解析
1. 引言 1.1 BLOOM 模型概述 BLOOM(BigScience Large Open-science Open-access Multilingual Language Model)是一款由多个国际研究团队联合开发的大型语言模型。BLOOM 模型旨在通过先进的 Transformer 架构处理复杂的自然语言生成与理解任务。它支持…...
Kubernetes 深度洞察:重新认识 Docker 容器的奇妙世界
《Kubernetes 深度洞察:重新认识 Docker 容器的奇妙世界》 在 Kubernetes 的学习进程中,对 Docker 容器的深入理解至关重要。这一节,我们将重新认识 Docker 容器,探索其在 Kubernetes 生态系统中的关键作用。 一、Docker 容器的基本概念 Docker 容器是一种轻量级的虚拟化…...
柔性作业车间调度(FJSP)
1.1 调度问题的研究背景 生产调度是指针对一项可分解的工作(如产品制造),在尽可能满足工艺路线、资源情况、交货期等约束条件的前提下,通过下达生产指令,安排其组成部分(操作)所使用的资源、加工时间及加工的先后顺序,以获得产品制造时间或成本最优化的一项工作。 一般研究车间…...
速盾:游戏用CDN可以吗?
游戏用CDN是一种常见的解决方案,可以提高游戏的网络性能和加载速度。CDN(Content Delivery Network,内容分发网络)能够将游戏的静态资源分布到全球各地的边缘节点上,使用户可以从离他们最近的节点获取游戏资源…...
《重生到现代之从零开始的C语言生活》—— 字符函数和字符串函数
字符函数和字符串函数 字符分类函数 大家知道字符是分为很多种类型的 就比如说’a’ ‘1’ A’等等,所以我们需要一种函数来完成字符函数的分类 这就是字符分类函数 函数需要包含头文件<ctype.h> 函数的运行规则是:如果符合下列参数就返回真 …...
双指针:滑动窗口
题目描述 给定两个字符串 S 和 T,求 S 中包含 T 所有字符的最短连续子字符串的长度,同时要求时间复杂度不得超过 O(n)。 输入输出样例 输入是两个字符串 S 和 T,输出是一个 S 字符串的子串。样例如下: 在这个样例中,…...
云原生(四十八) | Nginx软件安装部署
文章目录 Nginx软件安装部署 一、Nginx软件部署步骤 二、安装与配置Nginx Nginx软件安装部署 一、Nginx软件部署步骤 第一步:安装 Nginx 软件 第二步:把 Nginx 服务添加到开机启动项 第三步:配置 Nginx 第四步:启动Nginx …...
【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...
Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...
蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...
剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...
Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?
Redis 的发布订阅(Pub/Sub)模式与专业的 MQ(Message Queue)如 Kafka、RabbitMQ 进行比较,核心的权衡点在于:简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...
C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...
