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

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_guardunique_lock 管理互斥锁,让互斥锁使用更方便、更安全(可以避免死锁,比如我们使用完锁忘记释放了)

lock_guardunique_lock 遵循RAII

  • RAII,资源获取即初始化,是C++很重要的思想。

思考:如果需要在中途释放锁,怎么办?

  1. 使用 unique_lock
  2. 使用 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之线程

编译环境&#xff1a;Qt join&#xff1a;阻塞当前线程&#xff0c;直到线程函数退出 detach&#xff1a;将线程对象与线程函数分离&#xff0c;线程不依赖线程对象管理 注&#xff1a;join和detach两者必选其一&#xff0c;否则线程对象的回收会影响线程的回收&#xff0c;导致…...

界星空科技漆包线行业称重系统

万界星空科技为漆包线行业提供的称重系统是其MES制造执行系统解决方案中的一个重要组成部分。以下是对该系统的详细介绍&#xff1a; 一、系统概述 万界星空科技漆包线行业称重系统&#xff0c;是集成在MES系统中的一个功能模块&#xff0c;专门用于漆包线生产过程中的重量检…...

RabbitMQ的高级特性-事务

事务&#xff1a;RabbitMQ是基于AMQP协议实现的, 该协议实现了事务机制, 因此RabbitMQ也⽀持事务机制. SpringAMQP也提供了对事务相关的操作. RabbitMQ事务允许开发者确保消息的发送和接收是原⼦性的, 要么全部成功, 要么全部失败 配置事务管理器&#xff1a; Bean public Ra…...

Qt Linguist手册

概述 Qt 为将 Qt C 和 Qt Quick 应用程序翻译成当地语言提供了出色的支持。发布经理、翻译和开发人员可以使用 Qt 工具来完成他们的任务。 发布经理对应用程序的发布负总责。通常&#xff0c;他们负责协调开发人员和翻译人员的工作。他们可以使用 lupdate 工具同步源代码和翻…...

【简介Sentinel-1】

Sentinel-1是欧洲航天局哥白尼计划&#xff08;GMES&#xff09;中的地球观测卫星&#xff0c;由Sentinel-1A和Sentinel-1B两颗卫星组成。以下是对Sentinel-1的详细介绍&#xff1a; 一、基本信息 卫星名称&#xff1a;Sentinel-1 所属计划&#xff1a;欧洲航天局哥白尼计划…...

第 17 场小白入门赛蓝桥杯

第 17 场小白入门赛 2 北伐军费 发现每次选大的更优&#xff0c;所以可以排序之后&#xff0c;先手取右边&#xff0c;后手取左边。 实际发现&#xff0c;对于 A − B A-B A−B 的结果来说&#xff0c;后手对于这个式子的贡献是 − − a i --a_i −−ai​ &#xff0c;也就…...

@antv/x6 导出图片下载,或者导出图片为base64由后端去处理。

1、导出为文件的格式&#xff0c;比如 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、什么是大模型&#xff1f; 大模型&#xff0c;通常指的是在人工智能领域中的大型预训练模型。你可以把它们想象成非常聪明的大脑&#xff0c;这些大脑通过阅读大量的文本、图片、声音等信息&#xff0c;学习到了世界的知识。这些大脑&#xff08;模型&…...

PowerShell脚本在自动化Windows开发工作流程中的应用

PowerShell脚本在自动化Windows开发工作流程中的应用 在当今快速迭代的软件开发环境中&#xff0c;自动化已成为提高开发效率、减少人为错误、保障项目稳定性的重要手段。特别是在Windows平台上&#xff0c;PowerShell以其强大的脚本编写能力和对系统管理的深度集成&#xff0…...

【力扣 | SQL题 | 每日四题】力扣1783,1757,1747,1623,1468,1661

昨天晚上睡着了&#xff0c;今天把昨天的每日一题给补上。 1. 力扣1783&#xff1a;大满贯数量 1.1 题目&#xff1a; 表&#xff1a;Players ------------------------- | Column Name | Type | ------------------------- | player_id | int | | player_na…...

《深入探究 C++中的函数模板特化:开启编程新境界》

在 C的广袤世界中&#xff0c;函数模板特化是一项强大而富有魅力的技术&#xff0c;它为程序员提供了更高的灵活性和效率。本文将带你深入了解 C中函数模板特化是如何实现的&#xff0c;揭开这一神秘面纱&#xff0c;让你在编程之路上更上一层楼。 一、函数模板的基础概念 在…...

RTEMS面试题汇总及参考答案

目录 RTEMS是什么?它在嵌入式系统中扮演什么角色? RTEMS的全称是什么? RTEMS的主要特点有哪些? RTEMS支持哪些处理器架构? RTEMS的可剥夺型内核和不可剥夺型内核有何不同? RTEMS 的微内核设计及其优势 RTEMS 如何实现多任务处理和调度 RTEMS 的任务调度策略有哪…...

螺蛳壳里做道场:老破机搭建的私人数据中心---Centos下Docker学习03(网络及IP规划)

3 网络及IP规划 3.1 容器连接网络初步规划 规划所有容器与虚拟机的三张网卡以macvlan的方式进行连接&#xff08;以后根据应用可以更改&#xff09;&#xff0c;在docker下创建nat、wifi、nei、wai四张网卡&#xff0c;他们和虚拟机及宿主机上NIC的相关连接参数如下表所示&am…...

BLOOM 模型的核心原理、局限与未来发展方向解析

1. 引言 1.1 BLOOM 模型概述 BLOOM&#xff08;BigScience Large Open-science Open-access Multilingual Language Model&#xff09;是一款由多个国际研究团队联合开发的大型语言模型。BLOOM 模型旨在通过先进的 Transformer 架构处理复杂的自然语言生成与理解任务。它支持…...

Kubernetes 深度洞察:重新认识 Docker 容器的奇妙世界

《Kubernetes 深度洞察:重新认识 Docker 容器的奇妙世界》 在 Kubernetes 的学习进程中,对 Docker 容器的深入理解至关重要。这一节,我们将重新认识 Docker 容器,探索其在 Kubernetes 生态系统中的关键作用。 一、Docker 容器的基本概念 Docker 容器是一种轻量级的虚拟化…...

柔性作业车间调度(FJSP)

1.1 调度问题的研究背景 生产调度是指针对一项可分解的工作(如产品制造),在尽可能满足工艺路线、资源情况、交货期等约束条件的前提下,通过下达生产指令,安排其组成部分(操作)所使用的资源、加工时间及加工的先后顺序,以获得产品制造时间或成本最优化的一项工作。 一般研究车间…...

速盾:游戏用CDN可以吗?

游戏用CDN是一种常见的解决方案&#xff0c;可以提高游戏的网络性能和加载速度。CDN&#xff08;Content Delivery Network&#xff0c;内容分发网络&#xff09;能够将游戏的静态资源分布到全球各地的边缘节点上&#xff0c;使用户可以从离他们最近的节点获取游戏资源&#xf…...

《重生到现代之从零开始的C语言生活》—— 字符函数和字符串函数

字符函数和字符串函数 字符分类函数 大家知道字符是分为很多种类型的 就比如说’a’ ‘1’ A’等等&#xff0c;所以我们需要一种函数来完成字符函数的分类 这就是字符分类函数 函数需要包含头文件<ctype.h> 函数的运行规则是&#xff1a;如果符合下列参数就返回真 …...

双指针:滑动窗口

题目描述 给定两个字符串 S 和 T&#xff0c;求 S 中包含 T 所有字符的最短连续子字符串的长度&#xff0c;同时要求时间复杂度不得超过 O(n)。 输入输出样例 输入是两个字符串 S 和 T&#xff0c;输出是一个 S 字符串的子串。样例如下&#xff1a; 在这个样例中&#xff0c…...

云原生(四十八) | Nginx软件安装部署

文章目录 Nginx软件安装部署 一、Nginx软件部署步骤 二、安装与配置Nginx Nginx软件安装部署 一、Nginx软件部署步骤 第一步&#xff1a;安装 Nginx 软件 第二步&#xff1a;把 Nginx 服务添加到开机启动项 第三步&#xff1a;配置 Nginx 第四步&#xff1a;启动Nginx …...

【力扣数据库知识手册笔记】索引

索引 索引的优缺点 优点1. 通过创建唯一性索引&#xff0c;可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度&#xff08;创建索引的主要原因&#xff09;。3. 可以加速表和表之间的连接&#xff0c;实现数据的参考完整性。4. 可以在查询过程中&#xff0c;…...

ffmpeg(四):滤镜命令

FFmpeg 的滤镜命令是用于音视频处理中的强大工具&#xff0c;可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下&#xff1a; ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜&#xff1a; ffmpeg…...

【论文笔记】若干矿井粉尘检测算法概述

总的来说&#xff0c;传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度&#xff0c;通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比

目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec&#xff1f; IPsec VPN 5.1 IPsec传输模式&#xff08;Transport Mode&#xff09; 5.2 IPsec隧道模式&#xff08;Tunne…...

搭建DNS域名解析服务器(正向解析资源文件)

正向解析资源文件 1&#xff09;准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2&#xff09;服务端安装软件&#xff1a;bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...

Qemu arm操作系统开发环境

使用qemu虚拟arm硬件比较合适。 步骤如下&#xff1a; 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载&#xff0c;下载地址&#xff1a;https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...

前端中slice和splic的区别

1. slice slice 用于从数组中提取一部分元素&#xff0c;返回一个新的数组。 特点&#xff1a; 不修改原数组&#xff1a;slice 不会改变原数组&#xff0c;而是返回一个新的数组。提取数组的部分&#xff1a;slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...

【java】【服务器】线程上下文丢失 是指什么

目录 ■前言 ■正文开始 线程上下文的核心组成部分 为什么会出现上下文丢失&#xff1f; 直观示例说明 为什么上下文如此重要&#xff1f; 解决上下文丢失的关键 总结 ■如果我想在servlet中使用线程&#xff0c;代码应该如何实现 推荐方案&#xff1a;使用 ManagedE…...

二维数组 行列混淆区分 js

二维数组定义 行 row&#xff1a;是“横着的一整行” 列 column&#xff1a;是“竖着的一整列” 在 JavaScript 里访问二维数组 grid[i][j] 表示 第i行第j列的元素 let grid [[1, 2, 3], // 第0行[4, 5, 6], // 第1行[7, 8, 9] // 第2行 ];// grid[i][j] 表示 第i行第j列的…...

window 显示驱动开发-如何查询视频处理功能(三)

​D3DDDICAPS_GETPROCAMPRANGE请求类型 UMD 返回指向 DXVADDI_VALUERANGE 结构的指针&#xff0c;该结构包含特定视频流上特定 ProcAmp 控件属性允许的值范围。 Direct3D 运行时在D3DDDIARG_GETCAPS的 pInfo 成员指向的变量中为特定视频流的 ProcAmp 控件属性指定DXVADDI_QUER…...