QThread常用相关函数、线程启动方式

一、常用相关函数

可以将常用的函数按照功能进行以下分类:

  • 线程启动

    • void start()

      调用后会执行run()函数,但在run()函数执行前会发射信号started(),操作系统将根据优先级参数调度线程。如果线程已经在运行,那么这个函数什么也不做。优先级参数的效果取决于操作系统的调度策略。

  • 线程执行

    • int exec()

      每一个线程可以有自己的事件循环,可以通过调用exec()函数来启动事件循环。

    • void run()

      线程的起点,在调用start()之后,新创建的线程就会调用这个函数,默认实现调用exec(),大多数需要重新实现这个函数,便于管理自己的线程。该函数返回后,线程便执行结束,就像应用程序离开main()函数一样。

  • 线程退出

    • void quit()

      使线程退出事件循环,返回0表示成功,相当于调用了QThread::exit(0)。

    • void exit(int returnCode = 0)

      使线程退出事件循环,返回0表示成功,任何非0值表示失败。

    • void terminate()

      在极端情况下,可能想要强制终止一个正在执行的线程,这时可以使用terminate()函数。但是,线程可能会立即被终止也可能不会,这取决于操作系统的调度策略,使用terminate()之后再使用QThread::wait(),以确保万无一失。

      警告:使用terminate()函数,线程可能在任何时刻被终止而无法进行一些淸理工作,因此该函数是很危险的,一般不建议使用,只有在绝对必要的时候使用。

    • void requestInterruption()

      Qt5新引入接口,请求线程的中断,用于关闭线程。该请求是咨询意见并且取决于线程上运行的代码,来决定是否及如何执行这样的请求。此函数不停止线程上运行的任何事件循环,并且在任何情况下都不会终止它。

  • 线程等待

    • void msleep(unsigned long msecs) [static]

      强制当前线程睡眠msecs毫秒。

    • void sleep(unsigned long secs) [static]

      强制当前线程睡眠secs秒。

    • void usleep(unsigned long usecs) [static]

      强制当前线程睡眠usecs微秒。

    • bool wait(unsigned long time = ULONG_MAX)

      线程将会被阻塞,等待time毫秒。和sleep不同的是,如果线程退出,wait会返回。

  • 线程状态

    • bool isFinished() const

      判断线程是否结束

    • bool isRunning() const

      判断线程是否正在运行

    • bool isInterruptionRequested() const
      如果线程上的任务运行应该停止,返回true;可以使用requestInterruption()请求中断。 Qt5新引入接口,用于使长时间运行的任务干净地中断。从不检查或作用于该函数返回值是安全的,但是建议在长时间运行的函数中经常这样做。注意:不要过于频繁调用,以保持较低的开销。示例程序如下:

      void run() 
      {// 是否请求终止while (!isInterruptionRequested()){// 耗时操作}
      }
      
  • 线程优先级

    • void setPriority(Priority priority)

      设置正在运行线程的优先级。如果线程没有运行,此函数不执行任何操作并立即返回。使用的start()来启动一个线程具有特定的优先级。优先级参数可以是QThread::Priority枚举除InheritPriortyd的任何值。

枚举QThread::Priority:

常量描述
QThread::IdlePriority0没有其它线程运行时才调度
QThread::LowestPriority1比LowPriority调度频率低
QThread::LowPriority2比NormalPriority调度频率低
QThread::NormalPriority3操作系统的默认优先级
QThread::HighPriority4比NormalPriority调度频繁
QThread::HighestPriority5比HighPriority调度频繁
QThread::TimeCriticalPriority6尽可能频繁的调度
QThread::InheritPriority7使用和创建线程同样的优先级. 这是默认值

二、QThread线程启动方式

一、继承QThread,实现它的run()函数,将需要执行的耗时代码放在run()里面运行

void myThread::run()
{m_stop = false;while (!m_stop){/*耗时任务*/...}
}

此方法,如果要退出可使用

void myThread::stop()
{m_stop = true;quit();wait();
}


使用时,调用start()函数,则相当于执行run()函数,在程任务执行完毕时,会发出 finished() 信号

/*子类化线程*/
mythread = new myThread();
connect(mythread,SIGNAL(finished()),this,SLOT(dealfinished()));
mythread->start();



二、使用moveToThread()。即子类化一个QObject实现需要执行的操作,再将派生类对象移到QThread中,并通过信号和槽触开始执行。

/*QObject派生类,即耗时工作在这里实现*/
work = new Work;
/*通过信号和槽获取返回信息*/
connect(work,SIGNAL(resultReady(int)),this,SLOT(dealWorkresultReady(int)));/*将派生类对象移动到QThread中*/
thread = new QThread(this);
connect(thread,SIGNAL(finished()),this,SLOT(dealfinished_2()));
work->moveToThread(thread);
/*通过信号链接派生类的槽函数,并通过信号触发*/
connect(thread,SIGNAL(started()),work,SLOT(start()));
thread->start();

三、实现案例及代码

方式一:子类化QThread

mythread.h

#ifndef MYTHREAD_H
#define MYTHREAD_H#include <QThread>class myThread : public QThread
{Q_OBJECT
public:explicit myThread(QObject *parent = NULL);void stop();
protected:virtual void run();signals:void resultReady(int value);
private:bool m_stop;
};#endif // MYTHREAD_H

 mythread.cpp

#include "mythread.h"
myThread::myThread(QObject *parent) : QThread(parent)
{
}void myThread::stop()
{m_stop = true;quit();wait();
}void myThread::run()
{/*start会触发run,即需要执行的耗时工作加这里*/m_stop = false;int nValue = 0;while (nValue < 100 && !m_stop){emit resultReady(nValue);/*耗时0.5秒*/system("sleep 0.5");++nValue;/*发送信号,更新进度条*/}
}

 方式二:子类化QObject

work.h 

#ifndef WORK_H
#define WORK_H#include <QObject>class Work : public QObject
{Q_OBJECT
public:explicit Work(QObject *parent = NULL);void stop();public slots:void start();
signals:void resultReady(int value);
private:bool m_stop;
};#endif // WORK_H

work.cpp

#include "work.h"
Work::Work(QObject *parent) : QObject(parent)
{}void Work::stop()
{m_stop = true;
}void Work::start()
{m_stop = false;int nValue = 0;while (nValue < 100 && !m_stop ){emit resultReady(nValue);/*耗时0.5秒*/system("sleep 0.5");++nValue;}
}

效果图界面 widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QDateTime>
#include <QDebug>
Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{ui->setupUi(this);/*定时器,加载时间*/timer = new QTimer(this);connect(timer,SIGNAL(timeout()),this,SLOT(dealTimeout()));timer->start(1000);ui->progressBar->setValue(0);ui->progressBar->setMaximum(100);ui->progressBar_2->setValue(0);ui->progressBar_2->setMaximum(100);ui->progressBar_3->setValue(0);ui->progressBar_3->setMaximum(100);/*子类化线程*/mythread = new myThread(this);connect(mythread,SIGNAL(resultReady(int)),this,SLOT(dealresultReady(int)));connect(mythread,SIGNAL(finished()),this,SLOT(dealfinished()));/*QObject派生类,即耗时工作在这里实现*/work = new Work;/*通过信号和槽获取返回信息*/connect(work,SIGNAL(resultReady(int)),this,SLOT(dealWorkresultReady(int)));/*将派生类对象移动到QThread中*/thread = new QThread(this);connect(thread,SIGNAL(finished()),this,SLOT(dealfinished_2()));work->moveToThread(thread);/*通过信号链接派生类的槽函数,并通过信号触发*/connect(thread,SIGNAL(started()),work,SLOT(start()));}Widget::~Widget()
{delete ui;
}void Widget::dealresultReady(int value)
{ui->progressBar->setValue(value);
}void Widget::dealWorkresultReady(int value)
{ui->progressBar_3->setValue(value);
}void Widget::on_pushButton_1_clicked()
{if(!mythread->isRunning()){ui->pushButton_1->setText("stop");mythread->start();}else{ui->pushButton_1->setText("start_1");mythread->stop();}
}void Widget::on_pushButton_2_clicked()
{if(!thread->isRunning()){ui->pushButton_2->setText("stop");thread->start();}else{ui->pushButton_2->setText("start_2");work->stop();thread->quit();thread->wait();}
}void Widget::on_pushButton_clicked()
{ui->label_2->setText("<font style='color: red;'>完犊子,直接卡死! 点其他按钮么反应! 时间都没更新了!</font>");update();int cnt=0;while(cnt < 100){system("sleep 0.5");ui->progressBar_2->setValue(cnt);cnt++;update();}
}void Widget::dealfinished()
{qDebug()<< "start_1 over";
}void Widget::dealfinished_2()
{qDebug()<< "start_2 over";
}void Widget::dealTimeout()
{QDateTime dateTime = QDateTime::currentDateTime();QString date = dateTime.toString("hh:mm:ss");ui->label_3->setText("当前时间:"+date);
}

              
原文链接:https://blog.csdn.net/kchmmd/article/details/121202881

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

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

相关文章

杂谈-关于如何在博客或者技术站上提问才能获得作者更高的回复意愿和交流热情

如何提问一个有效的问题 &#x1f606; 首先为什么写这篇文章&#xff0c;由于在研究生的学习和工作过程中由于个人技术知识稍微丰富一点点也比较好学&#xff0c;经常会被提问或者自己提问-在博客&#xff0c;GitHub上&#xff0c;Stakflow上等等-也在和学弟学妹交流的过程中听…

Java面试题:工厂模式与内存泄漏防范?线程安全与volatile关键字的适用性?并发集合与线程池管理问题

Java面试深度剖析&#xff1a;设计模式、内存优化与并发处理 在Java技术栈中&#xff0c;设计模式、内存优化和并发处理是构建健壮、高效应用程序的关键。本文将通过三道精心设计的面试题&#xff0c;深入探讨这些知识点&#xff0c;旨在帮助读者在面试中展现深厚的技术功底&a…

C#调用Halcon出现尝试读取或写入受保护的内存,这通常指示其他内存已损坏。System.AccessViolationException

一、现象 在C#中调用Halcon&#xff0c;出现异常提示&#xff1a;尝试读取或写入受保护的内存,这通常指示其他内存已损坏。System.AccessViolationException 二、原因 多个线程同时访问Halcon中的某个公共变量&#xff0c;导致程序报错 三、测试 3.1 Halcon代码 其中tsp_width…

ELF-DISCOVER:大型语言模型自我构建推理结构

论文地址&#xff1a;https://arxiv.org/pdf/2402.03620.pdf Abstract 我们引入了SELF-DISCOVER&#xff0c;这是一个通用框架&#xff0c;用于让LLMs自我发现任务内在的推理结构&#xff0c;以解决对典型提示方法具有挑战性的复杂推理问题。该框架的核心是一个自我发现过程&…

测试交付类项目-文档规范

目的&#xff1a;为了确保项目的顺利进行和成功完成&#xff0c;并且为项目交付物提供准确的说明和指导。 文档提供时间&#xff1a;一般为产品验收完成&#xff0c;需求方初步确认完成后&#xff0c;需进行相关文档的提供&#xff0c;供需求方进行验收。 交付文档模板&#…

Python pip 换成国内镜像源

用 easy_install 和 pip 来安装第三方库很方便&#xff0c;它们的原理其实就是从Python的官方源pypi.python.org/pypi 下载到本地&#xff0c;然后解包安装。不过因为某些原因&#xff0c;访问官方的pypi不稳定&#xff0c;很慢甚至有些还时不时的访问不了。 跟 ubuntu 的 apt …

代码随想录算法训练营第七天|454.四数相加II、383. 赎金信、15. 三数之和、18. 四数之和

题目&#xff1a;454.四数相加II 文章链接&#xff1a;代码随想录 视频链接&#xff1a;LeetCode:454.四数相加|| 题目链接&#xff1a;力扣题目链接 图释&#xff1a; // 四数相加|| int fourSumCount(vector<int>& nums1, vector<int>& nums2, vect…

jeesite集成redis,redis工具类

一、 application.yml 配置文件新增 redis:host: 127.0.0.1port: 6379ssl: falsedatabase: 0password: timeout: 20000lettuce:pool:# 最大空闲连接数maxIdle: 3# 最大活动连接数maxActive: 20二、 pom.xml 配置文件新增 <!--redis--><dependency><groupId>r…

开窍后的9大表现 别害怕,开窍了你就是黑马

1. 对周围人&#xff0c;只筛选不改变。 不再试图改变任何人&#xff0c;比起之前替别人操心、提各种建议。现在不再执着改变对方&#xff0c;因为人在意识到问题&#xff0c;和解决问题之间有巨大的鸿沟。 2. 眼神特别。 开窍后最明显的一个特征就是眼神&#xff0c;无论是面…

项目经理到底要不要考PMP?有啥好处?

很多新手项目经理或者想要转行做项目经理的人&#xff0c;都会很快的注意到”PMP”这个证书。并且开始认真思考自己要不要考这个证书&#xff1f;以及想知道这个证书考试的具体难度、流程和内容。 先说结论&#xff1a; 值得考&#xff0c; 很容易考。 我在备考的过程中惊异…

excel批量数据导入时用poi将数据转化成指定实体工具类

1.实现目标 excel进行批量数据导入时&#xff0c;将批量数据转化成指定的实体集合用于数据操作&#xff0c;实现思路&#xff1a;使用注解将属性与表格中的标题进行同名绑定来赋值。 2.代码实现 2.1 目录截图如下 2.2 代码实现 package poi.constants;/*** description: 用…

【消息队列开发】 实现消息持久化

文章目录 &#x1f343;前言&#x1f340;消息存储格式设计&#x1f6a9;queue_data文件设计&#x1f6a9;queue_stat文件设计&#x1f6a9;拓展 &#x1f384;实现统计文件&#xff08;queue_stat&#xff09;的读写⭕总结 &#x1f343;前言 本次开发目标&#xff0c;实现消…

2024阿里云域名优惠口令大全(3月更新)

2024年阿里云域名优惠口令&#xff0c;com域名续费优惠口令“com批量注册更享优惠”&#xff0c;cn域名续费优惠口令“cn注册多个价格更优”&#xff0c;cn域名注册优惠口令“互联网上的中国标识”&#xff0c;阿里云优惠口令是域名专属的优惠码&#xff0c;可用于域名注册、续…

C# MES通信从入门到精通(1)——串口传输文件

前言: 在上位机软件开发领域,有一些工厂的mes系统需要我们通过串口发送文件的方式把一些图片或者检测数据csv文件等发送给服务器,这种方式是一些比较旧的工厂采用的方式,但是这种方式也是存在的,本文就是讲解如何使用串口发送文件详情见下文。 1、串口发送文件思路 将需…

【刷题节】美团2024年春招第一场笔试【技术】

1.小美的平衡矩阵 import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scanner new Scanner(System.in);int n scanner.nextInt();int[][] nums new int[n][n], sum new int[n][n];char[] chars;for (int i 0; i < n; i) {…

介绍Oracle的SQL调化健康检查脚本(SQLHC)

概述 Oracle提供了一个SQL调优健康检查脚本&#xff08;SQLHC&#xff09;&#xff0c;用于检查需要优化的SQL的运行环境&#xff0c;生成报告以便帮助DBA找到SQL性能不佳的原因。SQLHC是SQLT的一个子集&#xff08;我后续的文章会介绍SQLT&#xff09;&#xff0c;但SQLHC与S…

迁移学习怎么用

如果想实现一个计算机视觉应用&#xff0c;而不想从零开始训练权重&#xff0c;比方从随机初始化开始训练&#xff0c;更快的方式是下载已经训练好权重的网络结构&#xff0c;把这个作为预训练&#xff0c;迁移到你感兴趣的新任务上。ImageNet、PASCAL等等数据库已经公开在线。…

vue form表单验证

第一种&#xff1a;非必填不能为空&#xff0c;并且需要正则验证 第二种&#xff1a;必填&#xff0c;正则验证&#xff0c;不能只输入空格验证 第三种&#xff1a;必填&#xff0c;正则验证&#xff0c;不能输入空格(v-model.trim) 第四种&#xff1a;选了多选框后必填 第一种…

【笔记】学习Android.mk(三)

一、在Android.mk文件中引入系统动态库 要在 Android.mk 文件中引入系统动态库&#xff0c;你可以使用 LOCAL_SHARED_LIBRARIES 变量来指定系统动态库。以下是一个示例&#xff1a; LOCAL_PATH : $(call my-dir)include $(CLEAR_VARS)# 定义模块名称和源文件 LOCAL_MODULE : …

C#,数值计算,希尔伯特矩阵(Hilbert Matrix)的算法与源代码

Hilbert, David (1862-1943) 1 希尔伯特(Hilbert) 德国数学家,在《几何学基础》中提出了第一套严格的几何公理(1899年)。他还证明了自己的系统是自洽的。他发明了一条简单的空间填充曲线,即埃里克魏斯汀的数学世界,即希尔伯特曲线,埃里克魏斯汀的数学世界,并证明了不…