c++ qt--线程(一)(第八部分)

news2024/11/16 21:30:48

c++ qt–线程(一)(第八部分)

一.进程(Process)

在任务管理器中的进程页下,可以看到进程,任务管理器将进程分为了三类,应用、后台进程、window进程

在这里插入图片描述

应用:

打开的正在运行的软件

后台进程:

隐藏在后台,“悄悄”的运行

window进程:

操作系统启动、运行需要依赖的各种服务

1.进程的概念

是一个具有一定独立功能的程序在一个数据集上的一次动态执行的过程,是操作系统进行资源分配和调度的一个独立的基本单元,是应用程序运行的载体

进程是一种抽象的概念,从来没有统一的标准定义

2.进程的组成

进程由程序、数据集合、进程控制块三部分组成

3.进程的4个特征

1.动态性:进程是程序的一次执行过程,是临时的,有生命期的,是动态产生。动态消亡的

2.并发性:任何进程都可以同其他进程一起并发执行

3.独立性:进程是程序进行资源分配和调度的一个独立单元

4.结构性:进程由程序、数据集合、进程控制块三部分组成

4.应用程序和进程间的关系

一个应用程序下的多个进程是树形结构。

PID是进程的唯一标识符,PID最小的数是根节点

二.线程(Thread)

1.线程的概念

cpu能够进行调度、分配、执行、运算的最小的基本单位。是程序执行中一个单一的顺序控制流程,一个进程可以有一个或多个线程,各个线程之间共享进程的内存空间

2.线程的串行,并行和并发

串行:按照顺序。一个执行完再执行下一个

并行:同一个时刻,同时进行

并发:再同一个时间间隔内发生,指相同的时间间隔,交替执行

在单线程下,采用串行的方式执行

大部分操作系统的任务调度是采用轮换时间片的抢占式调度方式,一个线程执行一小段时间后暂停休息并等待着被唤醒,下一个线程被唤醒并开始执行,每个线程交替轮流执行,。线程执行的一小段时间叫做时间片

由于cpu的执行速度非常快,时间片非常短,在各个线程之间快速地切换,给人的感觉就是多个线程在“同时进行”,这就是常说的并发

3.线程的状态

1.新生态:创建出新的线程对象

2.就绪态:创建出线程后,进入就绪态,会将线程添加到就绪队列中,等待分配到cpu时间片,就会进行运行状态

3.运行态:运行态的线程如果时间片用完后,就会再次进入就绪状态,一般来说就绪态和运行态不需要认为参与,由操作系统进行调度,如果遇到sleep、wait、suspend、IO请求时就会进入阻塞态

4.阻塞态(挂起状态):一个正在运行的线程在某些特殊情况下,如被认为挂起或执行好事的I/O操作时,会让出cpu的使用权并暂时中止自己的执行,进入阻塞状态,处于阻塞状态的线程,就不能进入排队队列。只有当引起阻塞的原因被消除后,线程才可以转入就绪状态。当恢复线程,完成IO操作、等到资源,就会进入就绪状态

5.销亡态:线程正常执行结束、因异常退出、被强制终止,该线程结束生命周期

注意:

1.线程必须通过就绪态分配到时间片才能进入运行状态,而不能直接进入运行状态

2.就绪状态无法进入阻塞状态

3.其他状态的线程可直接进入销亡态

三.使用QT创建线程(进一步理解线程)

1.创建一个控制台窗口

在这里插入图片描述

2.创建线程

1.使用的头文件为

#include <windows.h>

2.创建线程

在main.cpp中的mian函数中写下面代码

int n=20;
//创建一个子线程,主线程可以看作是main函数 的执行
HANDLE handle=::CreateThread(nullptr/*使用默认的安全属性*/,//线程的安全属性,返回的是线程句柄,这里我们用线程句柄接一下
                   0//用默认的线程栈大小window(1M)
                   ,&ThreadProc//线程函数
                   ,&n//线程函数传递的参数
                   ,0//创建线程后,0:立即执行,CREATE_SUSPENDED:挂起
                   ,nullptr//返回线程ID
                   );

3.线程函数

在main.cpp中写下面代码

DWORD (WINAPI/*调用约定*/ ThreadProc) (LPVOID/* void* */ lpThreadParameter){

    return 0;//表示当前函数正常退出
}

4.通过输出观察两个线程的执行

主线程
int n=20;
//创建一个子线程,主线程可以看作是main函数 的执行
HANDLE handle=::CreateThread(nullptr/*使用默认的安全属性*/,//线程的安全属性,返回的是线程句柄,这里我们用线程句柄接一下
                   0//用默认的线程栈大小window(1M)
                   ,&ThreadProc//线程函数
                   ,&n//线程函数传递的参数
                   ,0//创建线程后,0:立即执行,CREATE_SUSPENDED:挂起
                   ,nullptr//返回线程ID
                   );

//进行一个输入,看主线程与子线程的关系
for(int i=0;i<20;i++){
     qDebug()<<"--------------------------------主人 睡了"<<i;
     Sleep(1000);
}
子线程
DWORD (WINAPI/*调用约定*/ ThreadProc) (LPVOID/* void* */ lpThreadParameter){
   //进行一个输入,看主线程与子线程的关系
   int n=*(int*)lpThreadParameter;//将void*强转为int*最后取其中的值
   for(int i=0;i<n;i++){
       qDebug()<<"仆人在挣钱"<<i;
       Sleep(1000);
   }
    return 0;//表示当前函数正常退出
}

5.线程的挂起、恢复操作(这里对子线程挂起和恢复操作)

主线程

在main.cpp中的mian函数中写下面代码

int n=20;

HANDLE handle=::CreateThread(nullptr,
                   0
                   ,&ThreadProc
                   ,&n/
                   ,CREATE_SUSPENDED//这里改为了CREATE_SUSPENDED,挂起
                   ,nullptr
                   );

for(int i=0;i<20;i++){
     if(i==3){
             //返回的是恢复或挂起之前 挂起计数器的值,当挂起计数器的值为0时,线程才能继续运行
             //挂起几次,就得恢复几次,线程才能继续运行
            DWORD count=::ResumeThread(handle);//恢复某一个线程运行
            qDebug()<<"count111   "<<count;
        }

        if(i==7){
             DWORD count=::SuspendThread(handle);
             qDebug()<<"count222   "<<count;
        }

        if(i==10){
            DWORD count=::SuspendThread(handle);
            qDebug()<<"count333    "<<count;
        }

        if(i==13){
            DWORD count=::ResumeThread(handle);
            qDebug()<<"count444    "<<count;
        }

        if(i==15){
            DWORD count=::ResumeThread(handle);
            qDebug()<<"count555    "<<count;
        }
     qDebug()<<"--------------------------------主人 睡了"<<i;
     Sleep(1000);
}
子线程

在main.cpp中写下面代码

DWORD (WINAPI/*调用约定*/ ThreadProc) (LPVOID/* void* */ lpThreadParameter){
   //进行一个输入,看主线程与子线程的关系
   int n=*(int*)lpThreadParameter;//将void*强转为int*最后取其中的值
   for(int i=0;i<n;i++){
       qDebug()<<"仆人在挣钱"<<i;
       Sleep(1000);
   }
    return 0;//表示当前函数正常退出
}

6.线程的关闭和退出操作()

定义两个关于退出标志
bool isTreadQuit=false;//退出的标志,这里初始是不退出
bool isAlreadyQuit=false;//告诉主线程退出了,这里初始是不告诉
主线程

在main.cpp中的mian函数中写下面代码

int n=20;

//创建第一个线程时也会创建内核对象,这时使用计数默认+1
HANDLE handle=::CreateThread(nullptr,
                   0
                   ,&ThreadProc
                   ,&n/
                   ,0//这里改为了0,立即执行
                   ,nullptr
                   );

for(int i=0;i<20;i++){
    qDebug()<<"--------------------------------主人 睡了"<<i;
  	if(i==6){
            isTreadQuit=true;
            qDebug()<<"通知子线程退出";
            break;
    }
    
    //第一种 一直等子线程退出的标记
    //while(1){
    //    if(isAlreadyQuit){
    //         qDebug()<<"收到子线程退出的标记了";
    //         break;
    //    }
	//    Sleep(1000);
    //}
    
     //第二种,设置等待时间等子线程退出,这里设置的是7秒
    DWORD flag=WaitForSingleObject(handle,7000);//这里的参数单位是毫秒
    if(flag==WAIT_OBJECT_0){//在设定的等待时间内,子线程正常退出了
        qDebug()<<"子线程退出了";
    }else if(flag==WAIT_TIMEOUT){//在设定的等待时间内,子线程没有退出,等待超时了
        qDebug()<<"等待超时,强制杀死线程";
        ::TerminateThread(handle,-1);//强制杀死子线程,有风险的方式
    }
    
    if(handle){
        ::CloseHandle(handle);//关闭句柄,使用计数-1,当使用计数减为0的时候系统就会回收内核对象·
    }
    handle=nullptr;
    
    Sleep(1000);
}
子线程

在main.cpp中写下面代码

DWORD (WINAPI/*调用约定*/ ThreadProc) (LPVOID/* void* */ lpThreadParameter){
    int n=*(int*)lpThreadParameter;
	while(!isTreadQuit){
        qDebug()<<"仆人在挣钱";
        Sleep(1000);
    }
	//第一种
    //isAlreadyQuit=true;
    return 0;
}

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

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

相关文章

MyBatis-Plus 总结

MyBatis-Plus简介 官网&#xff1a;https://baomidou.com/ GitHub&#xff1a;https://github.com/baomidou/mybatis-plus Gitee&#xff1a;https://gitee.com/baomidou/mybatis-plus 简介 MyBatis-Plus &#xff08;简称 MP&#xff09;是一个 MyBatis的增强工具&#x…

【C++入门到精通】C++入门 —— 多态(抽象类和虚函数的魅力)

阅读导航 前言一、多态的概念1. 概念2. 多态的特点 二、多态的定义及实现1. 多态的构成条件2. 虚函数3. 虚函数的重写⭕虚函数重写的两个例外1.协变(基类与派生类虚函数返回值类型不同)2.析构函数的重写(基类与派生类析构函数的名字不同) 4. override 和 final&#xff08;C11 …

SLAM从入门到精通(开始篇)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 很多同学喜欢学习linux&#xff0c;但是他们只是把linux当成是一个嵌入式技术在学习&#xff0c;而不是当成工具在使用。平时&#xff0c;要么是自…

appium+python自动化测试

获取APP的包名 1、aapt即Android Asset Packaging Tool&#xff0c;在SDK的build-tools目录下。该工具可以查看apk包名和launcherActivity 2、在android-sdk里面双击SDK-manager,下载buidl-tools 3、勾选build-tools&#xff0c;随便选一个版本&#xff0c;我这里选的是24的版…

YOLOv5、v8改进:CrissCrossAttention注意力机制

目录 1.简介 2. yolov5添加方法&#xff1a; 2.1common.py构建CrissCrossAttention模块 2.2yolo.py中注册 CrissCrossAttention模块 2.3修改yaml文件。 1.简介 这是ICCV2019的用于语义分割的论文&#xff0c;可以说和CVPR2019的DANet遥相呼应。 和DANet一样&#xff0c;…

DBeaver的安装和使用:windows版

DBeaver官网下载地址&#xff1a;https://dbeaver.io/download/ 下载完成后&#xff0c; 进入傻瓜式安装&#xff1a; 这里会进入重复界面&#xff0c;一样点击下一步即可 选择安装目录&#xff0c;尽量不要选C盘&#xff0c; 我的电脑只有c盘&#xff0c; 没办法 等待安装完成…

linux操作系统的权限的深入学习(未完)

1.Linux权限的概念 Linux下有两种用户&#xff1a;超级用户&#xff08;root&#xff09;、普通用户。 超级用户&#xff1a;可以再linux系统下做任何事情&#xff0c;不受限制 普通用户&#xff1a;在linux下做有限的事情。 超级用户的命令提示符是“#”&#xff0c;普通用户…

MVSNet 和 PatchMatchNet 的DTU数据集 几个不同之处 一定要注意

文章目录 1 测试集 数据加载不同2 训练集 数量 分辨率不同 1 测试集 数据加载不同 1.MVSNet 的DTU测试数据集和PatchmatchNet测试数据集不一样&#xff1b; 区别在于数据加载&#xff0c;前者 cams文件最后是最小深度和间隔&#xff0c;后者是最小深度和最大深度。 2 训练集 …

layui框架学习(41:表单模块)

之前的文章《layui框架学习》14-16中介绍了通过预设类及部分layui属性设置表单的外观样式&#xff0c;layui中还提供有表单模块以对表单元素进行各类动态化渲染和相关操作&#xff0c;本文学习并记录表单模块form的常用属性、函数及事件的用法&#xff08;如果内容已在之前文章…

时序预测 | MATLAB实现SSA-XGBoost(麻雀算法优化极限梯度提升树)时间序列预测

时序预测 | MATLAB实现SSA-XGBoost(麻雀算法优化极限梯度提升树)时间序列预测 目录 时序预测 | MATLAB实现SSA-XGBoost(麻雀算法优化极限梯度提升树)时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 Matlab实现SSA-XGBoost时间序列预测&#xff0c;麻…

VS警告 C4819 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失

1、问题 Microsoft visual studio 2019跑仿真的时候出现该警告&#xff0c;在高级保存选项设置编码为Unicode(UTF-8 无签名)还是会有该警告。 2、解决方法 右键项目&#xff0c;打开属性设置&#xff0c;选中&#xff1a;工程 -> 右键选择"属性" -> C/C ->…

JSON文件读写教程【jsoncpp源码编译】【结尾附三方库下载链接】

目录 1 数据下载(jsoncpp源码)2 文件编译3 测试用例4 下载链接:内容: JSON文件的读取与保存可以使用jsoncpp库来实现,这里介绍该库的下载及编译方法。 1 数据下载(jsoncpp源码) 数据下载:Github地址 图1 github源码示意图 2 文件编译 2.1 点击Download ZIP,下载源码。 …

大数据分析与AI在农业领域的应用

文章目录 数据采集与监测数据分析与预测个性化管理与优化决策支持系统结合物联网技术优势与前景 &#x1f388;个人主页&#xff1a;程序员 小侯 &#x1f390;CSDN新晋作者 &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 ✨收录专栏&#xff1a;Java知识介绍 ✨文章内容&a…

使用ChatGPT给Python代码写单元测试

先写一个简单的python函数&#xff0c;找chatgpt写单元测试&#xff1a; 有一个python函数&#xff0c;请帮忙写单元测试&#xff0c;函数长这样&#xff1a; def test2(a: list, b: list) -> float:"""计算两个坐标的距离:param a list 格式如&#xff1a…

记一次蓝屏日志

记一次Win 蓝屏日志&#xff1a; &#x1f4f2;引&#xff1a; 虽然说&#xff0c;我是一个在职两年半的程序员&#xff0c;但是对于这个问题其实也和大部分人一样&#xff0c;一脸懵逼&#x1f916; 那是一个风和日丽的早上&#xff0c;w开开心心去上班摸鱼&#x1f41f;&a…

LiteOS qemu realview-pbx-a9 环境搭建与运行

前言 最近打算移植搭建 一些常见的 RTOS 的 qemu 开发学习环境&#xff0c;当前 RT-Thread、FreeRTOS 已经成功运行 qemu&#xff0c;LiteOS 初步验证可以正常 运行 qemu realview-pbx-a9&#xff0c;这里做个记录 首先学习或者研究 RTOS&#xff0c;只是看内核源码&#xff0…

SNN论文总结

Is SNN a great work ? Is SNN a convolutional work ? ANN的量化在SNN中是怎么体现的&#xff0c;和threshold有关系吗&#xff0c;threshold可训练和这个有关吗&#xff08;应该无关&#xff09; 解决过发放不发放的问题。 Intuation SNN编码方式 Image to spike patter…

性能优化维度

CPU 首先检查 cpu&#xff0c;cpu 使用率要提升而不是降低。其次CPU 空闲并不一定是没事做&#xff0c;也有可能是锁或者外部资源瓶颈。常用top、vmstat命令查看信息。 vmstat 命令: top: 命令 IO iostat 命令&#xff1a; Memory free 命令&#xff1a; 温馨提示&#xff1a…

Qt应用开发(基础篇)——日历 QCalendarWidget

一、前言 QCalendarWidget类继承于QWidget&#xff0c;是Qt设计用来让用户更直观的选择日期的窗口部件。 时间微调输入框 QCalendarWidget根据年份和月份初始化&#xff0c;程序员也通过提供公共函数去改变他们&#xff0c;默认日期为当前的系统时间&#xff0c;用户通过鼠标和…

《C语言编程环境搭建》工欲善其事 必先利其器

C语言编译器 GCC 系列 GNU编译器套装(英语&#xff1a;GNU Compiler Collection&#xff0c;缩写为GCC)&#xff0c;指一套编程语言编译器&#xff0c;常被认为是跨平台编译器的事实标准。原名是&#xff1a;GNU C语言编译器(GNU C Compiler)。 MinGW 又称mingw32 &#xff0c…