【嵌入式——QT】QThread创建多线程

【嵌入式——QT】QThread创建多线程

  • 概述
  • 主要函数
  • 图示
  • 代码示例

概述

QThread类提供不依赖于平台的管理线程的方法,一个QThread类的对象管理一个线程,一般从QThread继承一个自定义类,并重定义虚函数run(),在run()函数里实现线程需要完成的任务。
将应用程序的线程称为主线程,额外创建的线程称为工作线程,一般在主线程里创建工作线程,并调用start()开始执行工作线程的任务。start()会在内部调用run()函数,进入工作线程的时间循环,在run()函数调用exit()或quit()可以结束线程的事件循环,或在主线程里调用terminate()强制结束线程。

主要函数

信号

  • void finished():线程结束时发射此信号;
  • void started():线程开始执行、run()函数被调用之前发射此信号;

槽函数

  • quit():退出线程的事件循环,并返回代码0,等效于exit(0);

  • start(QThread::Priority priority = InheritPriority):内部调用run()开始执行线程,操作系统根据Priority参数进行调度;

  • terminate():终止线程的运行,但不是立即结束线程,而是等待操作系统结束线程,使用terminate()之后应使用wait();

    Priority

    • QThread::IdlePriority: 仅在没有其他线程运行时调度;
    • QThread::LowestPriority:比低优先级安排得更少;
    • QThread::LowPriority:比NormalPriority更少被安排;
    • QThread::NormalPriority:操作系统的默认优先级;
    • QThread::HighPriority:比NormalPriority更经常被安排;
    • QThread::HighestPriority:比高优先级安排得更频繁;
    • QThread::TimeCriticalPriority:尽可能多安排时间;
    • QThread::InheritPriority:使用与创建线程相同的优先级。这是默认值;

公共函数

  • bool isFinished() const:线程是否结束;
  • bool isRunning() const:线程是否正在运行;
  • priority() const:返回线程的优先级;
  • setPriority(QThread::Priority priority):设置线程的优先级;
  • exit(int returnCode = 0):退出线程的事件循环;
  • wait(unsigned long time):阻止线程执行,直到线程结束,或等待线程超过time毫秒;

静态公共函数

  • idealThreadCount():返回系统上能运行的线程的理想个数;
  • msleep(unsigned long msecs):强制当前线程休眠msecs毫秒;
  • sleep(unsigned long secs):强制当前线程休眠secs秒;
  • usleep(unsigned long usecs):强制当前线程休眠usecs微秒;

保护函数

  • int exec():由run()函数调用,进入线程的事件循环,等待exit退出;
  • virtual void run():start()调用run()函数开始线程任务的执行,所以在run()函数里实现线程的任务功能;

图示

在这里插入图片描述

代码示例

QDiceThread.h

#ifndef QDICETHREAD_H
#define QDICETHREAD_H#include <QObject>
#include <QThread>
#include <QMutex>
class QDiceThread : public QThread
{Q_OBJECTpublic:QDiceThread();~QDiceThread();void run() Q_DECL_OVERRIDE;void diceBegin();//掷一次骰子void dicePause();//暂停void stopThread();//结束线程bool readValue(int* seq, int* diceValue);signals:void newValue(int seq, int diceValue);//产生新点数的信号private :int m_seq = 0;//掷骰子次数序号int m_diceValue;//骰子点数bool m_paused = true;//暂停bool m_stop = false;//停止QMutex mutex;};#endif // QDICETHREAD_H

QDiceThread.cpp

#include "QDiceThread.h"
#include <QTime>
#include <QMutexLocker>
QDiceThread::QDiceThread() {}QDiceThread::~QDiceThread()
{
}void QDiceThread::run()
{m_stop = false;m_seq = 0;qsrand(QTime::currentTime().msec());while(!m_stop) {if(!m_paused) {//QMutexLocker用法// QMutexLocker Locker(&mutex);//mutex用法mutex.lock();m_diceValue = qrand();m_diceValue = (m_diceValue % 6)+1;m_seq++;//使用互斥量读取数据,暂时注释掉信号操作// emit newValue(m_seq, m_diceValue);//mutex用法mutex.unlock();}msleep(500);}quit();
}void QDiceThread::diceBegin()
{m_paused = false;
}void QDiceThread::dicePause()
{m_paused = true;
}void QDiceThread::stopThread()
{m_stop = true;
}bool QDiceThread::readValue(int* seq, int* diceValue)
{if(mutex.tryLock()) {*seq = m_seq;*diceValue = m_diceValue;mutex.unlock();return true;} else {return false;}
}

QThreadDialog.h

#ifndef QTHREADDIALOG_H
#define QTHREADDIALOG_H#include <QDialog>
#include "QDiceThread.h"
#include <QTimer>
namespace Ui
{class QThreadDialog;
}class QThreadDialog : public QDialog
{Q_OBJECTpublic:explicit QThreadDialog(QWidget* parent = nullptr);~QThreadDialog();void closeEvent(QCloseEvent* event);private slots:void on_pushButtonStart_clicked();void on_pushButtonPause_clicked();void on_pushButtonBegin_clicked();void on_pushButtonStop_clicked();void on_pushButtonClear_clicked();public slots:void threadStatusStart();void threadStatusFinished();void threadNewValue(int seq, int diceValue);void onTimeOut();private:Ui::QThreadDialog* ui;QDiceThread thread;QTimer timer;int mSeq, mDiceValue;
};#endif // QTHREADDIALOG_H

QThreadDialog.cpp

#include "QThreadDialog.h"
#include "ui_QThreadDialog.h"QThreadDialog::QThreadDialog(QWidget* parent): QDialog(parent), ui(new Ui::QThreadDialog)
{ui->setupUi(this);connect(&thread, SIGNAL(started()), this, SLOT(threadStatusStart()));connect(&thread, SIGNAL(finished()), this, SLOT(threadStatusFinished()));connect(&thread, &QDiceThread::newValue, this, &QThreadDialog::threadNewValue);connect(&timer, SIGNAL(timeout()), this, SLOT(onTimeOut()));
}QThreadDialog::~QThreadDialog()
{delete ui;
}void QThreadDialog::closeEvent(QCloseEvent* event)
{if(thread.isRunning()) {thread.stopThread();thread.wait();}event->accept();
}void QThreadDialog::on_pushButtonStart_clicked()
{thread.start();mSeq = 0;ui->pushButtonStart->setEnabled(false);ui->pushButtonStop->setEnabled(true);ui->pushButtonBegin->setEnabled(true);ui->pushButtonPause->setEnabled(false);
}void QThreadDialog::on_pushButtonStop_clicked()
{thread.stopThread();thread.wait();ui->pushButtonStart->setEnabled(true);ui->pushButtonStop->setEnabled(false);ui->pushButtonBegin->setEnabled(false);ui->pushButtonPause->setEnabled(false);
}void QThreadDialog::on_pushButtonBegin_clicked()
{thread.diceBegin();timer.start(100);ui->pushButtonBegin->setEnabled(false);ui->pushButtonPause->setEnabled(true);
}void QThreadDialog::on_pushButtonPause_clicked()
{thread.dicePause();timer.stop();ui->pushButtonBegin->setEnabled(true);ui->pushButtonPause->setEnabled(false);
}void QThreadDialog::on_pushButtonClear_clicked()
{ui->plainTextEdit->clear();
}void QThreadDialog::threadStatusStart()
{ui->labelStatus->setText("thread started");
}void QThreadDialog::threadStatusFinished()
{ui->labelStatus->setText("thread finished");
}void QThreadDialog::threadNewValue(int seq, int diceValue)
{QString str = QString::asprintf(u8"第%d次投掷骰子,点数为:%d", seq, diceValue);ui->plainTextEdit->appendPlainText(str);
}void QThreadDialog::onTimeOut()
{int tmpSeq =0, tmpValue = 0;bool valid = thread.readValue(&tmpSeq, &tmpValue);if(valid && (tmpSeq != mSeq)) {mSeq = tmpSeq;mDiceValue = tmpValue;QString str = QString::asprintf(u8"第%d次投掷骰子,点数为:%d", mSeq, mDiceValue);ui->plainTextEdit->appendPlainText(str);}
}

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

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

相关文章

基于java的健身房管理系统的设计与实现论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本健身房管理系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息&…

【MySQL】数据库的基础概念

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前学习计网、mysql和算法 ✈️专栏&#xff1a;MySQL学习 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章对你有帮助的话 欢迎 评论&#x1f4ac…

Redis 更新开源许可证 - 不再支持云供应商提供商业化的 Redis

原文&#xff1a;Rowan Trollope - 2024.03.20 未来的 Redis 版本将继续在 RSALv2 和 SSPLv1 双许可证下提供源代码的免费和宽松使用&#xff1b;这些版本将整合先前仅在 Redis Stack 中可用的高级数据类型和处理引擎。 从今天开始&#xff0c;所有未来的 Redis 版本都将以开…

Vue.js前端开发零基础教学(二)

目录 前言 2.1 单文件组件 2.2 数据绑定 2.2.2 响应式数据绑定 2.3 指令 2.3.1 内容渲染指令 2.3.2 属性绑定指令 ​编辑 2.3.3 事件绑定指令 2.3.4 双向数据绑定指令 2.3.5 条件渲染指令 2.3.6 列表渲染指令 2.4 事件对象 2.5 事件修饰符 学习目标&am…

sentinel使用控制台实现

1、添加依赖 <!--整合控制台--><dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-transport-simple-http</artifactId> <version>1.8.0</version></dependency> 此项方法&#xff0…

HarmonyOS入门学习

HarmonyOS入门学习 前言快速入门ArkTS组件基础组件Image组件Text组件TextInput 文本输入框Buttonslider 滑动组件 页面布局循环控制ForEach循环创建组件 List自定义组件创建自定义组件Builder 自定义函数 状态管理Prop和LinkProvide和ConsumeObjectLink和Observed ArkUI页面路由…

JVM第八讲:GC - Java 垃圾回收基础知识

GC - Java 垃圾回收基础知识 本文是JVM第八讲&#xff0c; Java 垃圾回收基础知识。垃圾收集主要是针对堆和方法区进行&#xff1b;程序计数器、虚拟机栈和本地方法栈这三个区域属于线程私有的&#xff0c;只存在于线程的生命周期内&#xff0c;线程结束之后也会消失&#xff0…

单片机第四季-第二课:uCos2源码-BSP

1&#xff0c;初始uCos2 文件中uC开头的为uCos相关的。 2&#xff0c;uCos2源码工程建立 建立Source Insight工程 寻找main函数 (1)RTOS其实就是一个大的裸机程序&#xff0c;也是从main开始运行的 (2)main之前也是有一个汇编的启动文件的 (3)main中调用了很多初始化函数 bsp部…

Linux信号补充——信号发送和保存

三、信号的发送与保存 3.1信号的发送 ​ 必须有操作系统来保存信号&#xff0c;因为他是管理者&#xff1b; ​ 信号给进程的task_struct发送信号&#xff0c;在task_struct中维护了一个整数signal有0-31位&#xff0c;共32个bit位&#xff1b;对于信号的管理使用的是位图结…

Java常见的垃圾回收器GC

本节讲解一下常见的垃圾回收器。需要特别注意的是&#xff0c;每一种垃圾回收器都会存在用户线程&#xff08;即用户程序&#xff09;暂停的问题&#xff0c;只不过每种回收器用户线程暂停的时长优化程度不一样。在启动JVM时&#xff0c;可以通过“指定参数-xx:垃圾回收器名称”…

贵价茶叶产区成谜,竹叶青茶是“行业黑马”还是“韭菜镰刀”?

撰稿|行星 来源|贝多财经 近日&#xff0c;央视“315”晚会曝光了自诩“高端商务白酒”的听花酒。这款白酒号称拥有提升免疫力、改善睡眠、保障男性功能等多种保健功能&#xff0c;标准装售价5860元&#xff0c;精品装售价更是达到5.86万元&#xff0c;昂贵程度令人瞠目结舌。…

jmeter的函数助手使用方法

如某个上传文件接口&#xff0c;一个文件只能同时被一个接口调用&#xff0c;如果被并发同时调用就会报错 创建多个测试文件 比如50并发&#xff0c;创建更多的文件防止并发多时随机数生成重复 生成随机数函数 工具–函数助手-选择random-输入范围&#xff08;1-696&#…

网络学习:IPV6基础配置

目录 一、配置接口的全球单播地址 二、配置接口本地链路地址 三、配置接口任播地址 四、配置接口PMTU 配置静态PMTU&#xff1a; 配置动态PMTU&#xff1a; 五、接口配置IPV6地址示例&#xff1a; 一、配置接口的全球单播地址 全球单播地址类似于IPv4公网地址&#xff0…

Redis技术学习|实战项目记录|短信登录(重点:拦截器)+ Redis代替session存储用户登录信息

学习资料声明 黑马程序员的Redis学习视频&#xff1a;黑马程序员Redis入门到实战教程 需要用到的知识&#xff1a;linux&#xff08;推荐韩顺平老师的教程&#xff0c;学到p30&#xff0c;创建好虚拟机和简单的几个命令就好。&#xff09;SSM。SpringBoot。 还用到了MybatisPl…

5G里面NR,gNB,en-gNB,ng-eNB是什么意思

不得不提一个国际组织&#xff0c;叫国际电信联盟(ITU, International Telecommunication Union)&#xff0c;简称国际电联。我们先看看国际电联的自我介绍&#xff1a; 国际电信联盟 『国际电联 (国际电信联盟) 是主管信息通信技术事务&#xff08;ICT&#xff09;的联合国机…

微信打卡小程序怎么做_用户的每日习惯培养神器

微信打卡小程序&#xff1a;你的每日习惯培养神器 在这个快节奏的现代社会&#xff0c;我们每天都在忙碌中度过&#xff0c;有时候甚至会忘记自己曾经立下的那些小目标、小习惯。然而&#xff0c;随着科技的不断发展&#xff0c;微信打卡小程序的出现&#xff0c;为我们的生活…

早期零撸项目,预注册即将截止, AI身份项目GenomeFi明牌空投教程

简介&#xff1a;GenomeFi基金会旨在用个人基因信息推动生物产业发展&#xff0c;他们通过AI大数据平台和区块链技术验证身份、保护个人信息、提升收入。GenomeFi和CLINOMICS&#xff08;一家基于基因组学疾病早期诊断的领先公司&#xff09;合作提供基因诊断、早期疾病检测、个…

朋友圈之于私域的意义

朋友圈作为社交媒体的一种&#xff0c;是品牌主进行私域流量营销的主要载体&#xff0c;具有推动产品销售、传播信息等多种作用。具体来说&#xff0c;朋友圈在私域中的意义可以体现在以下几个方面&#xff1a; 1. 传播信息&#xff1a;朋友圈可以成为品牌主向其潜在客户传递信…

代码随想录阅读笔记-字符串【重复的子字符串】

题目 给定一个非空的字符串&#xff0c;判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母&#xff0c;并且长度不超过10000。 示例 1: 输入: "abab"输出: True解释: 可由子字符串 "ab" 重复两次构成。 示例 2: 输入: "aba…

爬虫入门系列-HTML基础语法

&#x1f308;个人主页&#xff1a;会编辑的果子君 &#x1f4ab;个人格言:“成为自己未来的主人~” HTML基础语法 bs4解析比较简单&#xff0c;但是呢&#xff0c;首先你需要了解一丢丢的html知识&#xff0c;然后再去使用bs4去提取&#xff0c;逻辑和编写难度就会非常简…