QT多线程学习(三)

2021-12-25  本文已影响0人  lxr_

上两篇篇举例使用了QT的多线程使用方式一和二
下面举例使用线程池实现多线程,参考链接可看上一篇
同样的,程序需要实现如下功能:
除了主线程外,创建随机数生成、冒泡排序、快速排序三个子线程,并将计算结果分别显示,可以得到每个线程花费时间,如下。


image.png
通过上面的执行结果我们发现与前两种方式不同,随机数产生线程和冒泡排序线程的线程ID是一样的,因为在生成随机数以后,这个线程就没有其他用处了,故就拿来作为冒泡排序的线程了。**
main.cpp
#include "QtThread.h"
#include <QtWidgets/QApplication>

int main(int argc, char* argv[])
{
    QApplication a(argc, argv);

    //https://blog.csdn.net/wadfji/article/details/54406767
    //传递QVector<int>时需要注册
    qRegisterMetaType<QVector<int>>("QVector<int>");

    QtThread w;
    w.show();
    return a.exec();
}

QtThread.h创建工程时起的类名

#pragma once

#include <QtWidgets/QMainWindow>
#include "ui_QtThread.h"

class QtThread : public QMainWindow
{
    Q_OBJECT

public:
    QtThread(QWidget* parent = Q_NULLPTR);

signals:
    void starting(int num);

private:
    Ui::QtThreadClass ui;
};

QtThread.cpp

#include "QtThread.h"

#include "mythread.h"

#include <qthreadpool.h>

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

    //1.创建任务类对象
    //创建生成随机数的子线程对象
    Generate* gen = new Generate;

    //创建排序类的对象
    BubbleSort* bubble = new BubbleSort;
    QuickSort* quick = new QuickSort;

    //主线程发送需要的随机数个数给生成随机数的子线程
    connect(this, &QtThread::starting, gen, &Generate::recvNum);

    //2.启动子线程,生成随机数子线程开始运行
    connect(ui.btn_start, &QPushButton::clicked, this, [=]() {
        emit starting(10000);
        QThreadPool::globalInstance()->start(gen); //放到线程池中
        });

    //3.生成随机数的子线程把数据发送给排序的两个子线程和主线程
    connect(gen, &Generate::sendArray, bubble, &BubbleSort::recvArray);   //排序线程接收数据
    connect(gen, &Generate::sendArray, quick, &QuickSort::recvArray);

    connect(gen, &Generate::sendArray, this, [=](QVector<int> list) {
        //排序线程开始运行
        QThreadPool::globalInstance()->start(bubble);

        QThreadPool::globalInstance()->start(quick);

        //显示随机生成的数
        for (int i = 0; i < list.size(); i++)
        {
            ui.randList->addItem(QString::number(list.at(i)));
        }
        });

    //主线程接收排序后的结果
    connect(bubble, &BubbleSort::finish, this, [=](QVector<int> list) {
        for (int i = 0; i < list.size(); i++)
        {
            ui.bubbleList->addItem(QString::number(list.at(i)));
        }
        });

    connect(quick, &QuickSort::finish, this, [=](QVector<int> list) {
        for (int i = 0; i < list.size(); i++)
        {
            ui.quickList->addItem(QString::number(list.at(i)));
        }
        });

    //不用释放资源,任务类已经设置为自动释放
}

mythread.h包含三个任务类对象

#pragma once

#include <QThread>

#include <qvector.h>
#include <qrunnable.h>

class Generate : public QObject, public QRunnable
{
    Q_OBJECT

public:
    explicit Generate(QObject* parent = nullptr);
    ~Generate();

    void recvNum(int num);

    void run() override;

signals:
    void sendArray(QVector<int> num);

private:
    int m_num;
};

//*****************冒泡排序*********************
class BubbleSort : public QObject, public QRunnable
{
    Q_OBJECT

public:
    explicit BubbleSort(QObject* parent = nullptr);
    ~BubbleSort();

    void recvArray(QVector<int> list);

    void run() override;

signals:
    void finish(QVector<int> list);

private:
    QVector<int> m_list;
};

//********************快速排序*************************
class QuickSort : public QObject, public QRunnable
{
    Q_OBJECT

public:
    explicit QuickSort(QObject* parent = nullptr);
    ~QuickSort();

    void recvArray(QVector<int> list);

    void run() override;

private:
    void quickSort(QVector<int>& list, int l, int r);

signals:
    void finish(QVector<int> list);

private:
    QVector<int> m_list;
};

mythread.cpp

#include "mythread.h"
#include <qelapsedtimer.h>
#include <qdebug.h>

//*******************生成随机数******************
Generate::Generate(QObject* parent)
    : QObject(parent), QRunnable()
{
    setAutoDelete(true);  //设置为自动销毁
}
Generate::~Generate()
{
}

void Generate::run()
{
    qDebug() << "生成随机数的线程的线程地址:" << QThread::currentThread();

    QVector<int> list;
    QElapsedTimer time;
    time.start();

    for (int i = 0; i < this->m_num; i++)
    {
        list.push_back(qrand() % 100000);
    }

    int milsec = time.elapsed();

    qDebug() << "生成" << this->m_num << "个随机数总共用时:" << milsec << "毫秒";

    emit sendArray(list);      //发送信号给主线程
}

void Generate::recvNum(int num)
{
    this->m_num = num;
}

//*****************冒泡排序**********************
BubbleSort::BubbleSort(QObject* parent) :QObject(parent), QRunnable()
{
    setAutoDelete(true);

}
BubbleSort::~BubbleSort()
{

}

void BubbleSort::recvArray(QVector<int> list)
{
    this->m_list = list;
}
void BubbleSort::run()
{
    qDebug() << "冒泡排序的线程地址:" << QThread::currentThread();

    QElapsedTimer time;
    time.start();

    for (int i = 0; i < m_list.size(); i++)
    {
        for (int j = 0; j < m_list.size() - i - 1; j++)
        {
            if (m_list[j] > m_list[j + 1])
            {
                int temp = m_list[j];
                m_list[j] = m_list[j + 1];
                m_list[j + 1] = temp;
            }
        }
    }

    int milsec = time.elapsed();

    qDebug() << "冒泡排序总共用时:" << milsec << "毫秒";

    emit finish(m_list);      //发送信号给主线程
}

//********************快速排序**************************
QuickSort::QuickSort(QObject* parent) :QObject(parent), QRunnable()
{
    setAutoDelete(true);
}
QuickSort::~QuickSort()
{

}
//快速排序
void QuickSort::quickSort(QVector<int>& s, int l, int r)
{
    if (l < r)
    {
        int i = l, j = r;
        //拿出第一个元素保存到x中,第一个位置成为一个坑
        int x = s[l];
        while (i < j)
        {
            //从右向左找小于x的数
            while (i < j && s[j] >= x)
            {
                //左移,直到遇到小于等于x的数
                j--;
            }
            if (i < j)
            {
                //将右侧找到的小于x的元素放入左侧坑中,右侧出现一个坑
                //左侧元素索引后移
                s[i++] = s[j];
            }
            //从左向右找大于等于x的数
            while (i < j && s[i] < x)
            {
                //右移,直到遇到大于x的数
                i++;
            }
            if (i < j)
            {
                //将左侧找到的元素放入右侧坑中,左侧出现一个坑
                //右侧元素索引向前移动
                s[j--] = s[i];
            }
        }
        //此时,i=j,将保存在x中的数填入坑中
        s[i] = x;
        quickSort(s, l, i - 1);
        quickSort(s, i + 1, r);

    }
}
//接收数据
void QuickSort::recvArray(QVector<int> list)
{
    m_list = list;
}
void QuickSort::run()
{
    qDebug() << "快速排序的线程地址:" << QThread::currentThread();

    QElapsedTimer time;
    time.start();

    quickSort(m_list, 0, m_list.size() - 1);

    int milsec = time.elapsed();

    qDebug() << "快速排序总共用时:" << milsec << "毫秒";

    emit finish(m_list);      //发送排序完的数据给主线程
}
上一篇下一篇

猜你喜欢

热点阅读