美文网首页
QT多线程学习(三)

QT多线程学习(三)

作者: lxr_ | 来源:发表于2021-12-25 11:22 被阅读0次

    上两篇篇举例使用了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);      //发送排序完的数据给主线程
    }
    

    相关文章

      网友评论

          本文标题:QT多线程学习(三)

          本文链接:https://www.haomeiwen.com/subject/bqddqrtx.html