【嵌入式——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;其可以帮助管理者在短时间内处理完毕庞大的数据信息&…

富格林:谨记可信计策安全做单

富格林悉知&#xff0c;现货黄金由于活跃的行情给投资者带来不少的盈利的机会&#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…

优化您的部署:Docker 镜像最佳实践

介绍 在快速发展的软件开发和部署领域&#xff0c;Docker 已成为容器化的强大工具&#xff0c;为打包、分发和运行应用程序提供了一种标准化的高效方式。Docker 镜像在这一过程中发挥着至关重要的作用&#xff0c;是容器化应用程序的基础。为确保最佳性能、可扩展性和安全性&a…

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…

蓝桥杯day6刷题日记-航班时间-完全二叉树的权值-砝码称重

P8665 [蓝桥杯 2018 省 A] 航班时间 注意输出形式和读取数据的形式 #include <iostream> #include <algorithm> using namespace std; int n,h1,m1,s1,h2,m2,s2; int q[1000];int gettime() {int day 0;scanf("%d:%d:%d %d:%d:%d", &h1, &m1,…

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

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

html2canvas实现原理

html2canvas 是一个 JavaScript 库&#xff0c;可以将 HTML 元素转换为 Canvas 元素&#xff0c;进而实现对网页内容的截图功能。它的实现原理主要包括以下几个步骤&#xff1a; 1、解析和构建 DOM 树&#xff1a;html2canvas 首先会解析网页上指定的 HTML 元素&#xff0c;包…

开机动画结束正常进入桌面

systemUI 添加壁纸 1128 I am_proc_start: [0,1485,10019,com.android.systemui,service,{com.android.systemui/com.android.systemui.ImageWallpaper}] Line 87550: 03-08 17:29:15.680346 947 1128 I ActivityManager: Start proc 1485:com.android.systemui/u0a19 …

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:垃圾回收器名称”…

Android静默安装一(Root版)

近期开发上线一个常驻app&#xff0c;项目已上线&#xff0c;今天随笔记录一下静默安装相关内容。我分三篇静默安装&#xff08;root版&#xff09;、静默安装&#xff08;无障碍版&#xff09;、监听系统更新、卸载、安装。先说说我的项目需求&#xff1a;要求app一直运行&…

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

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

为什么c++要在c语言的基础上添加命名空间?命名空间如何定义和使用?

1、为什么c要在c语言上增添命名空间的概念 在c语言中&#xff0c;定义的全局变量与库中相同&#xff0c;或者和别人代码结合的时候可能存在相同的命名&#xff0c;此时就会命名冲突。c语言是没有办法很好的解决这个问题的。 假设这样一种情况&#xff0c;当一个班上有两个名叫…

jmeter的函数助手使用方法

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

网络学习:IPV6基础配置

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