QT:多线程与并发

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()
{}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

li星野

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值