【C++】 Qt-线程挂起、恢复和退出

news2024/10/6 10:35:27

文章目录

      • 线程挂起和恢复
      • 内核对象
      • 线程退出

线程挂起和恢复

我们给设置线程的函数创建一个线程句柄用来接收返回值,并且将状态改为挂起状态

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cgqxSAYx-1689132952536)(C++.assets/image-20230704060636417.png)]

然后在循环中当第五秒时恢复线程,第八秒时连续挂起两次线程,并且返回输出挂起计数器的值(返回挂起之前的),最后在第10秒和第12秒分别恢复一次线程,同样返回 挂起计数器,恢复之前的数值

    for(int i=0;i<20;i++){
        qDebug()<<"-------------------睡觉:"<<i;

        if(i == 5){
            //恢复线程
            ::ResumeThread(handle);
        }
        if(i == 8){
            //挂起之前的:挂起计数器的值
            DWORD d1 = ::SuspendThread(handle);  //挂起
            qDebug()<<"d1 = "<<d1;  //0

            DWORD d2 = ::SuspendThread(handle);  //挂起
            qDebug()<<"d2 = "<<d2;  //1
        }
        if(i == 10){
            //恢复线程,返回的是挂起计数器,恢复之前的数值
            DWORD d3 = ::ResumeThread(handle);  //恢复
            qDebug()<<"d3 = "<<d3;  //2
        }
        if(i == 12){
            DWORD d4 = ::ResumeThread(handle);
            qDebug()<<"d4 = "<<d4;  //1
            
            //挂起几次,就要恢复几次,挂起计数器的值为0,线程开始执行
        }
        Sleep(1000);
    }

通过测试我们发现,挂起几次就要 恢复几次,挂起计数器 的值为0时,线程开始执行

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9gQ82Qyl-1689132952537)(C++.assets/image-20230704061101314.png)]

内核对象

内核是操作系统提供底层服务的一个模块,而内核对象则是内核分配的一个内存块,它是一种数据结构,不同的内核对象具有不同的结构,负责维护对象相关的信息 ,少数成员如:安全描述符、使用计数等是所有内核对象都有的,其他多数都是不同的。

内核对象的所有者是操作系统而非进程,即内核对象的生命周期并不一定会随着创建该对象的进程的消亡而消亡,内核对象的存在时间可以比创建该对象的进程长,内核对象的回收是通过使用计数来实现的。使用计数是所有内核对象固有的属性,操纵系统通过使用计数维护内核对象的生命周期。

操作系统内核知道当前有多少进程正在使用某个内核对象,内核对象被创建时,其使用计数为1,另一个进程访问该内核对象后,使用计数加1,当进程终止时,使用计数减1,手动关闭内核对象时,使用计数再减1,最终使用计数为 0时,操作系统将销毁该内核对象。

如果结束使用内核对象,需要调用CloseHandle()函数,BOOL CloseHandle(HANDLE hObject);

注意:并不是说调用这个函数,内核对象就被销毁了,而是使使用计数器减1.如果忘记CloseHandle那么在程序运行期间会发生内存泄漏,直到进程结束,操作系统会回收所有的资源。

线程退出

  1. 正常退出,如顺序执行完代码,或有限次的循环,执行完毕直接自己 主动退出。退出时记得CloseHandle()。
    if(handle){
        ::CloseHandle(handle);  //使用计数减1
        handle = nullptr;
    }
  1. 全局变量(双变量标记)

有些时候,创建的线程无法正常退出,可以设置退出标志,最好设置两个标志,可以让双方友好和谐的退出。保证所有子线程都退出后,主线程再退出。

bool isQuitThread = false;  //不退出

bool isQuit = false;  //不退出
    while(!isQuitThread){
        qDebug()<<"挣钱----";
        Sleep(1000);
    }
    qDebug()<<"我即将要退出了";
    isQuit = true;  //我即将要退出了,告诉主线程一声
    while(1){
        if(isQuit){
            qDebug()<<"等到了子线程退出";
            break;
        }
        Sleep(1000);
    }

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tJmzlc7E-1689132952538)(C++.assets/image-20230704070532463.png)]

  1. 终止线程

上例中如果子线程因为某种原因,一直无法退出,将导致主线程一直等待,无法做其他的事情。所以等待应该是有时限的。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gtP73Gg0-1689132952538)(C++.assets/image-20230704070735326.png)]

    //等待子线程退出,等待多少毫秒,阻塞函数
    DWORD flag = ::WaitForSingleObject(handle,3000);
    if(flag == WAIT_TIMEOUT){  //等待超时
        qDebug()<<"等待超时,强制杀死";
        //强制杀死子线程
        ::TerminateThread(handle,-1);  //最后万不得已的手段,有风险
    }else if(flag == WAIT_OBJECT_0){  //正常等到子线程退出了
        qDebug()<<"等到了子线程退出";
    }

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8imG6lxZ-1689132952538)(C++.assets/image-20230704070848878.png)]

注意:TerminateThread 是一个比较危险的方法,应当用在最后万不得已最极端的情况,如果目标线程正在使用关键段,关键段不会被释放。线程在堆区申请空间,不会被释放,可能会导致内存泄漏。

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

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

相关文章

【C++ OJ练习】7.字符串相加

1.题目链接 力扣 2.解题思路 拿到每个字符后 减去字符0 转化成对应的数字 再相加即可 倒着加 因为有进位的情况 最后头插或 者尾插加逆置 3.代码 class Solution { public:string addStrings(string num1, string num2) {//倒着往回加int end1 num1.size() - 1;int end2…

走进Vue2飞入Vue3

✅作者简介&#xff1a;大家好&#xff0c;我是Cisyam&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Cisyam-Shark的博客 &#x1f49e;当前专栏&#xff1a; 前端相关 ✨特色专栏&…

C语言中的宏

宏定义又称为宏替换&#xff0c;简称“宏”&#xff0c;在C语言预处理阶段被处理&#xff0c;编译器会根据宏定义进行文本替换。这样做的好处有许多&#xff0c;它可以为程序员在编程时提供方便&#xff0c;并能在一定程度上提高程序的运行效率。 本文将通过一部分场景&#xf…

原码、反码和补码之间的转换

(꒪ꇴ꒪(꒪ꇴ꒪ ),hello我是祐言博客主页&#xff1a;C语言基础,Linux基础,软件配置领域博主&#x1f30d;快上&#x1f698;&#xff0c;一起学习&#xff01;送给读者的一句鸡汤&#x1f914;&#xff1a;集中起来的意志可以击穿顽石!作者水平很有限&#xff0c;如果发现错误…

DataEase中点数据集,报Data source connection exception: Access denied for user错误

【现象】&#xff1a; 2023-07-12 10:53:19,436 DEBUG .DeEngineMapper.selectByExampleWithBLOBs: 137 - < Total: 1 java.sql.SQLException: Access denied for user ****** (using password: YES)at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:965…

MySQL基础篇第8章(聚合函数)

文章目录 1、聚合函数介绍1.1 AVG和SUM函数1.2 MIN和MAX函数1.3 COUNT函数 2、GROUP BY2.1 基本使用2.2 使用多个分组2.3 GROUP BY中使用WITH ROLLUP 3、HAVING3.1 基本使用3.2 WHERE和HAVING的对比 4、SELECT的执行过程4.1 查询的结构4.2 SELECT执行顺序4.3 SQL的执行原理 1、…

【MQ】Windows上RabbitMQ的安装与启动

文章目录 下载Erlang安装RabbitMQ 下载Erlang RabbitMQ基于Erlang语言&#xff0c;因此使用RabbitMQ之前需要先安装Erlang&#xff0c;如下 Erlang语言下载 这里我是用的是25.2.2这个版本&#xff0c;我的机器是64bit的&#xff0c;所以下win64的即可。 下载完毕安装包之后点…

Wholebody 3D keypoint估计:从H3WB开始

目录 前言一、&#xff28;&#xff13;&#xff37;&#xff22;1.下载2.标注格式3.任务分析验证评估 总结 前言 这份工作是首次尝试去检测&#xff13;D全人体姿态的工作&#xff0e;我们使用的数据集是基于Human3.6M的&#xff13;&#xff24;全人体关键点数据集&#xff…

【宝塔】宝塔部署ThinkPHP项目

最近搞了个培训教育的小程序&#xff0c;后端服务用的是ThinkPHP。使用的过程中&#xff0c;发现对于这种小项目用php还是很不错的选择&#xff0c;开发便捷&#xff0c;轻量级。宝塔神器也是很不错的&#xff0c;值得推荐使用。 下面介绍一下项目中用宝塔部署ThinkPHP项目&…

USB枚举过程详解

1 USB枚举流程 1.1 USB枚举流程 USB SETUP command的状态阶段的状态包是个ZLP。 Anchor chips -> Netchip -> PLX -> Avago -> Broadcom The USB3380 is EOL and the kits that were by Taiwan Bplus. PLX USB3380设备控制器使用2个32bit寄存器存放setup的8个字节&…

数据库-表的增删改查

这里写目录标题 新增&#xff08;Create&#xff09;查询条件查询运算符逻辑运算符分页查询 修改&#xff08;Update&#xff09;删除&#xff08;Delete&#xff09; 注释&#xff1a;在SQL中可以使用“–空格描述”来表示注释说明 新增&#xff08;Create&#xff09; 语法…

spark3新特性之动态分区裁剪

Spark3.0为我们带来了许多令人期待的特性。Spark中的静态分区裁剪在介绍动态分区裁剪之前&#xff0c;有必要对Spark中的静态分区裁剪进行介绍。因此&#xff0c;在这种情况下&#xff0c;我们不能再应用静态分区裁剪&#xff0c;因为filter条件在join表的一侧&#xff0c;而对…

【小米的技术分享】拯救程序员的“救命稻草”:Git回滚命令大揭秘!

大家好&#xff0c;我是小米。作为一名热爱技术的程序员&#xff0c;经常使用Git进行版本控制是我们的家常便饭。但是&#xff0c;难免会遇到一些意外&#xff0c;比如不小心提交了错误的代码或者合并了错误的分支&#xff0c;这时候就需要用到Git回滚命令了。今天&#xff0c;…

chrome谷歌浏览器书签不同步的解决办法

背景&#xff1a;多台电脑使用时&#xff0c;发现浏览器书签并没有及时同步&#xff0c;找到最终的解决办法&#xff1a; 第1步&#xff1a;chrome地址栏中输入&#xff1a; chrome://sync-internals/ 第2步&#xff1a;点击 Disable Sync (Clear Data) 点击Request Start 第3…

马上掌握的LayUI树形权限菜单,助力你的权限管理!

目录 一、树形菜单的介绍 1、什么是树形菜单&#xff1f; 二、实现思路流程 三、实现步骤 1、查看数据 1&#xff09;表数据 2&#xff09; 最终效果 2、编程 1&#xff09;实体类编写 2&#xff09;PermissionDao编写&#xff08;难点&#xff09; 第一 在线转json…

vue+springboot基于Web的电子产品销售系统设计与实现 gqon2a

随着人们生活水平的高速发展&#xff0c;电子产品销售方面在近年来呈直线上升&#xff0c;人们也了解到电子产品的实用性&#xff0c;因此电子产品的销售数量也逐年递增&#xff0c;电子产品销售的增加加大了在管理上的工作难度。为了能更好的维护电子产品销售管理秩序&#xf…

Grafana 图形面板定制方案

Grafana 在一个 Panel 中添加多数据源同时展示以及修改通过 transform 修改图表图例的方式。 多个数据在一个折线图中 在 Grafana 中我们可能会希望多个数据在一个Panel 中展示&#xff0c;比如&#xff1a; 通过编辑 Panel 增加 Query 数据我们即可做到&#xff1a;像上面中…

SQL数据库连接类型与常用函数

目录 1. 创建表插入数据 2. 连接类型 2.1 内连接 2.2 外连接 2.2.1 左外连接 2.2.2 右外连接 2.3 交叉连接 2.4 子查询&公用表达式 2.5 UNION连接 3. SQL常用函数 3.1 CASE WHEN函数 3.2 COALESCE函数 3.3 NULLIF函数 3.4 LEAST 和 GREATEST函数 3.5 DISTINCT…

LayUi之树形结构的详解(附有全案例代码)

&#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 接下来看看由辉辉所写的关于LayUi的相关操作吧 目录 &#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 一. 什么是树形结构 二.树形结构在什么时…

表格编程之争:Python VS VBA?Excel用户:新编程语言才真香

Python和VBA哪个更好用&#xff1f; Python和VBA是两种不同的编程语言&#xff0c;它们都有自己的特点和优缺点。在表格编程方面&#xff0c;VBA在Excel中的应用非常广泛&#xff0c;可以通过宏来实现自动化操作和数据处理&#xff0c;也可以通过VBA代码来实现自定义函数和界面…