QT:多线程与并发

news2024/9/24 9:25:29

Qt创建线程的三种方法

  1. 使用QThread类
    QThread 是Qt中用于处理线程的类。可以通过继承 QThread 并重写其 run() 方法来创建自定义的线程。
    注意:
    派生于QThread的类,构造函数属于主线程,run函数属于子线程,可以通过打印线程id
    判断。
    mythread.h
#pragma once
#include <QThread>

class Thread01 : public QThread
{
	Q_OBJECT

public:
	Thread01();
	void run() override;
};


mythread.cpp


#include "mythread.h"
#include <QDebug>

Thread01::Thread01()
{
	qDebug() << "Thread01 construct " << QThread::currentThreadId();
}

void Thread01::run()
{
	qDebug() << "Thread01 run " << QThread::currentThreadId();

	int index = 0;
	while (1)
	{
		qDebug() << index++;
		QThread::msleep(500);
	}
}


main.cpp

#include <QtWidgets/QApplication>
#include "mythread.h"
#include <iostream>

using namespace std;

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    cout << "main thread" << QThread::currentThreadId() << endl;
    Thread01 th;
    th.start();
    cout << "main thread end" << QThread::currentThreadId() << endl;
    return a.exec();
}

2、派生于QRunnable,重写run()方法,在run方法里处理其它任务,调用时需要借助Qt线程池

在这里插入图片描述

Thread02.h

#pragma once
#include <QRunnable>
class Thread02 : public QRunnable
{
public:
	Thread02();
	~Thread02();
	void run() override;
};

Thread02.cpp

#include "Thread02.h"
#include <QThread>
#include <QDebug>

Thread02::Thread02()
{
	qDebug() << "Thread02 construct " << QThread::currentThreadId();
}

Thread02::~Thread02()
{
	qDebug() << "Thread02 xigou func";
}

void Thread02::run()
{
	qDebug() << "Thread02 run " << QThread::currentThreadId();
}

3、moveToThread
派生于QObject,使用moveToThread方法
将QThread对象作为私有成员,在构造函数里moveToThread,然后启动线程

在这里插入图片描述
Thread03.h

#pragma once
#include <qobject.h>
#include <QThread>
class Thread03 :
    public QObject
{
public:
	Thread03();

public slots:
	void fun();

private:
	QThread m_th;
};


Thread03.cpp

#include "Thread03.h"
#include <QDebug>

Thread03::Thread03()
{
	this->moveToThread(&m_th);
	m_th.start();

	qDebug() << "Thread03 construct " << QThread::currentThreadId();
}

void Thread03::fun()
{
	qDebug() << "Thread03 fun " << QThread::currentThreadId();

	int index = 0;
	while (1)
	{
		qDebug() << "Thread03 fun " << index++;
		QThread::msleep(300);
	}
}

QTheadmy01.h

#pragma once

#include <QtWidgets/QWidget>
#include "ui_QTheadmy01.h"
#include "Thread03.h"
class QTheadmy01 : public QWidget
{
    Q_OBJECT

public:
    QTheadmy01(QWidget *parent = nullptr);
    ~QTheadmy01();

private slots:
    void on_pushButton_clicked();

signals:
    void sig_fun();

private:
    Ui::QTheadmy01Class ui;

    Thread03* m_pTh03 = nullptr;
};

QTheadmy01.cpp

#include "QTheadmy01.h"
#include "mythread.h"
#include <QDebug>

QTheadmy01::QTheadmy01(QWidget *parent)
    : QWidget(parent)
{
    ui.setupUi(this);

	qDebug() << "main construct " << QThread::currentThreadId();

	m_pTh03 = new Thread03();

	connect(this, &QTheadmy01::sig_fun, m_pTh03, &Thread03::fun);

}
void QTheadmy01::on_pushButton_clicked()
{
	//m_pTh03->fun();
	qDebug() << "on_pushButton_clicked";
	emit sig_fun();

	/*int index = 0;
	while (1)
	{
		qDebug() << index++;
		QThread::msleep(300);
	}*/
}
QTheadmy01::~QTheadmy01()
{}

QtConcurrent简介

QtConcurrent是Qt框架中用于简化多线程编程的一个模块,它提供了一系列高级API,使得开发者能够更容易地编写多线程代码,从而充分利用多核处理器的性能优势。
简化多线程编程:QtConcurrent隐藏了线程的创建、调度和销毁等底层复杂性,使得开发者能够专注于实现并行算法和任务,而无需担心线程管理的细节。
高层次的API:QtConcurrent通过QFuture和QThreadPool等类提供了一组高级API,允许开发者以声明性的方式表达并行任务,从而更容易地实现并行计算。
自动线程池管理:QtConcurrent利用Qt内部的线程池来管理线程资源,这些线程池可以根据系统的处理器核心数自动调整线程数量,以达到最优的性能。
灵活的结果处理:QtConcurrent支持阻塞和非阻塞两种模式来处理任务结果。开发者可以选择立即等待任务完成并获取结果,或者使用QFutureWatcher来异步获取结果并处理通知。
线程安全:QtConcurrent的API设计考虑了线程安全的问题,减少了数据访问冲突和竞态条件的发生。
在这里插入图片描述
Qtconcurrentmy.h

#pragma once

#include <QtWidgets/QWidget>
#include "ui_Qtconcurrentmy.h"

class Qtconcurrentmy : public QWidget
{
    Q_OBJECT

public:
    Qtconcurrentmy(QWidget *parent = nullptr);
    ~Qtconcurrentmy();
    int timeTask();

private slots:
    void on_pushButton_clicked();
private:
    Ui::QtconcurrentmyClass ui;
};

Qtconcurrentmy.cpp

#include "Qtconcurrentmy.h"
#include <QThread>
#include <QDebug>
#include <QtConcurrent>
#include <QFuture>
Qtconcurrentmy::Qtconcurrentmy(QWidget *parent)
    : QWidget(parent)
{
    ui.setupUi(this);
}

int Qtconcurrentmy::timeTask() {
    int num = 0;
    for (int i = 0; i < 1000000; i++)
    {
        num++;
        qDebug() << num;
    }

    return num;
}
void Qtconcurrentmy::on_pushButton_clicked() {
    //timeTask();

    QFuture<int> ft = QtConcurrent::run(this, &Qtconcurrentmy::timeTask);

    while (!ft.isFinished())
    {
        QApplication::processEvents(QEventLoop::AllEvents, 30);
    }

}
Qtconcurrentmy::~Qtconcurrentmy()
{}

QFuture<int> ft = QtConcurrent::run(this, &Qtconcurrentmy::timeTask);

使用QtConcurrent::run函数来在Qt的全局线程池中启动一个新的线程,并在这个新线程中执行Qtconcurrentmy类的timeTask成员函数。

while (!ft.isFinished())  
{  
    QApplication::processEvents(QEventLoop::AllEvents, 30);  
}

while循环检查ft(即QFuture对象)是否表示的任务已经完成。如果任务还没有完成(!ft.isFinished()返回true),则调用QApplication::processEvents来处理待处理的事件。

// 定义一个全局函数,它接受两个整数参数并返回它们的和  
int sum(int a, int b) {  
    return a + b;  
}  
// 使用QtConcurrent::run来在后台线程中执行全局函数sum,并传递参数  
QFuture<int> future = QtConcurrent::run(sum, 5, 3);  

获取QtConcurrent的返回值

获取QtConcurrent的结果,需要使用QFutureWatcher类,链接它的信号
finished,然后给watcher设置future,当监控到future执行结束后,可以获
取它的执行结果,调用的是result()函数;
Qtconcurrentmy.cpp

#include "Qtconcurrentmy.h"
#include <QThread>
#include <QDebug>
#include <QtConcurrent>
#include <QFuture>
#include <QFutureWatcher>


Qtconcurrentmy::Qtconcurrentmy(QWidget *parent)
    : QWidget(parent)
{
    ui.setupUi(this);
}

int Qtconcurrentmy::timeTask() {
    int num = 0;
    for (int i = 0; i < 100; i++)
    {
        num++;
        qDebug() << num;
    }

    return num;
}
void Qtconcurrentmy::on_pushButton_clicked() {
    //timeTask();
    QFutureWatcher<int>* fw = new QFutureWatcher<int>;
    connect(fw, &QFutureWatcher<int>::finished, [&] {
        qDebug() << "QFutureWatcher finished";
        qDebug() << "result = " << fw->result();
        });


    QFuture<int> ft = QtConcurrent::run(this, &Qtconcurrentmy::timeTask);
    fw->setFuture(ft);

    while (!ft.isFinished())
    {
        QApplication::processEvents(QEventLoop::AllEvents, 30);
    }

}
Qtconcurrentmy::~Qtconcurrentmy()
{}

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

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

相关文章

【pytorch深度学习——小样本学习策略】网格搜索和遗传算法混合优化支持向量机的小样本学习策略进行预测

最近需要根据心率血氧数据来预测疲劳度&#xff0c;但是由于心率血氧开源数据量较少&#xff0c;所以在训练模型时面临着样本数量小的问题&#xff0c;需要对疲劳程度进行多分类&#xff0c;属于小样本&#xff0c;高维度问题。在有限样本的条件之下&#xff0c;必须要需要选择…

游戏开发设计模式之责任链模式

责任链模式&#xff08;Chain of Responsibility Pattern&#xff09;是一种行为型设计模式&#xff0c;它允许将请求沿着处理者链进行发送。每个处理者对象都有机会处理该请求&#xff0c;直到某个处理者决定处理该请求为止。 概念与定义 责任链模式的核心思想是将多个处理器…

vue3路由使用createWebHistory部署访问404问题 vite部署访问404问题

vue3路由使用createWebHistory部署访问404问题 vite部署访问404问题 开始createWebHistory() H5路由模式修改vite.config.js修改 router/index.js 路由模式修改Nginx配置1配置2配置3 createWebHashHistory() 哈希模式修改vite.config.js修改 router/index.js 路由模式Nginx配置…

文件IO和多路复用IO

目录 前言 一、文件 I/O 1.基本文件 I/O 操作 1.1打开文件 1.2读取文件内容 (read) 1.3写入文件 (write) 1.4关闭文件 (close) 2.文件指针 二、多路复用 I/O 1.常用的多路复用 I/O 模型 1.1select 1.2poll 1.3epoll 2.使用 select、poll 和 epoll 进行简单的 I/O…

基于vue框架的北城招聘管理平台题目7lly3(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;用户,企业,企业信息,职位类型,职位信息,简历信息,职位应聘,求职意愿,面试信息,录取信息,实习信息,冻结信息,解冻信息 开题报告内容 基于Vue框架的北城招聘管理平台 开题报告 一、引言 随着互联网的飞速发展和企业对人才需求的不断增…

无人机之如何利用无人机进行地形测绘

一、无人机的选择 多旋翼无人机&#xff1a;多旋翼无人机具有较好的稳定性和悬停能力&#xff0c;适用于复杂地形和需要高精度影像测绘任务。 固定翼无人机&#xff1a;固定翼无人机飞行速度快&#xff0c;续航能力强&#xff0c;更适合大面积的地形测绘工作。 消费级无人机…

python怎么删除模块

1、用命令行删除 安装pip $ wget https://bootstrap.pypa.io/get-pip.py $ python get-pip.py 删除指定的模块或者包&#xff1a; pip uninstall xxx 2、手动删除 去Python的第三方模块或包的存放位置进行手工删除文件和文件夹&#xff0c;然后删除easy-install.pth文件中的相…

Canvas实现电子签名功能

实现代码如下&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Canvas实现手写板</t…

开发指南056-定时任务

业务场景中定时任务很常见。平台实现定时任务的原则如下&#xff1a; 1、定时任务的定义在业务库&#xff08;没必要集中到核心库&#xff0c;另外定时任务的服务要访问业务库&#xff09;。 2、定时任务的服务为独立微服务。 平台的定时任务基于&#xff1a; <dependenc…

20240824 每日AI必读资讯

谷歌搜索引擎全面揭秘&#xff01;近百份文档泄露&#xff0c;博主爆肝数周逆向工程 - 继5月的文件泄露事件后&#xff0c;谷歌的搜索引擎又被掀了个底朝天。 - DeepMind发论文解释了Vizier系统的机制&#xff0c;博客作者Mario Fischer还对近百份文档做了彻底的调研分析&…

单位信息宣传考核投稿方法不对让我尝尽了苦头

自从我担任单位的信息宣传员以来,便深刻体会到“信息宣传”四个字背后的重量。每月的信息宣传考核任务就像一座大山,压在我心头。起初,我像大多数同行一样,习惯于通过电子邮件向各大媒体投稿,但这种方式让我尝尽了苦头。 记得开始尝试通过邮箱投稿时,我满怀信心地将精心准备的文…

C语言-内存管

内存区间 全局/静态存储区 不仅仅包含全局变量&#xff0c;还包含静态变量&#xff08;包括在函数内部定义的静态局部变量&#xff09;、字符串常量以及main函数开始执行之前就被初始化的所有其他数据。这些数据的生命周期贯穿整个程序执行期间。 对于一个C语言程序而言&…

SQL-DQL-数据查询语言

数据查询语言 1、基础查询 2、条件查询 3、聚合函数 4、分组查询 5、分页查询 6、案例 7、执行顺序 select 字段列表 from 表名列表 where 条件列表 group by 分组字段列表 having 分组后条件列表 order by 排序字段列表 limit 分页参数1、基础查询 select 字段1[as 别…

OpenCV与AI深度学习 | 基于改进YOLOv8的景区行人检测算法

本文来源公众号“OpenCV与AI深度学习”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;基于改进YOLOv8的景区行人检测算法 作者&#xff1a;贵向泉&#xff0c;刘世清&#xff0c;李立等 来源&#xff1a;《计算机工程》期刊 编…

Linux 命令集合

1. linux 系统版本 1.1 linux系统的分类 linux系统&#xff0c;主要分Debian系和RedHat系&#xff0c;还有其它自由的发布版本。 1、Debian系主要有Debian&#xff0c;Ubuntu&#xff0c;Mint等及其衍生版本&#xff1b; 2、RedHat系主要有RedHat&#xff0c;Fedora&#xf…

AI可预测地震,科技的“预知未来”?

在科幻小说和电影中&#xff0c;预知未来的能力总是让人向往。而在现实世界中&#xff0c;科学家们正利用人工智能&#xff08;AI&#xff09;技术&#xff0c;向着预测自然灾害这一“未来”的目标迈进。 近日&#xff0c;德州大学奥斯汀分校&#xff08;UT Austin&#xff09;…

【C++】C++的模板初识

目录 思维导图大纲&#xff1a; 1. 什么是模板&#xff1f; 2. 模板的分类 区别&#xff1a;函数模版和模版函数 / 类模版和模版类 2.1 函数模板 2.1.1 用法 2.1.2 原理 2.1.3 函数模板的实例化 2.1.4 模板参数的匹配原则 2.2 类模板 2.2.1 用法 2.2.2 原理 …

Linux--gdb的常用命令

目录 前言 一、gdb是什么&#xff1f; 二、常用命令 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 对于程序有两个版本&#xff0c;一个是debug版和release版&#xff0c;要想进行调试必须使用debug版本&#xff0c;再Linux上进行调试就要用到调试器…

660高数刷题

1 周期函数的周期等于上下限的差值则值相等 2 3 4 5 6 泰勒公式要展开到多少阶

快速幂算法【算法 08】

快速幂算法详解 在计算机编程中&#xff0c;快速幂算法是一种高效计算大整数幂次的算法。相较于直接的暴力计算&#xff0c;快速幂能够在对数级别的时间复杂度下完成运算&#xff0c;因此它在许多算法和问题中&#xff08;如数论、组合数学、密码学等&#xff09;都有广泛的应用…