Qt 多執行緒程式設計、自動排序
阿新 • • 發佈:2021-11-19
需求: QT產生隨機數10000個 通過多執行緒(為了是主頁面不卡頓) 一個執行緒氣泡排序、一個執行緒快速排序,看看哪個演算法更快。
程式執行結果是這樣的
mythread.h
#ifndef MYTHREAD_H #define MYTHREAD_H #include <QThread> #include <QVector> //生成隨機數 class Generate : public QThread { Q_OBJECT public: explicit Generate(QObject *parent = nullptr); //槽函式用來接收主執行緒給的num值 void recvNum(int num); //受保護的 protected: void run() override; //訊號 signals: void sendArray(QVector<int>); private: int m_num; }; //氣泡排序 class BubbleSort : public QThread { Q_OBJECT public: explicit BubbleSort(QObject *parent = nullptr); void recvArray(QVector<int> list); protected: void run() override; signals: void finish(QVector<int> num); private: QVector<int> m_list; }; //快速排序 class QuickSort : public QThread { Q_OBJECT public: explicit QuickSort(QObject *parent = nullptr); void recvArray(QVector<int> list); protected: void run() override; private: void quickSort(QVector<int> &list, int l, int r); signals: void finish(QVector<int> num); private: QVector<int> m_list; }; #endif // MYTHREAD_H
mythread.cpp
#include "mythread.h" #include <QElapsedTimer> #include <QDebug> Generate::Generate(QObject *parent) : QThread(parent) { } void Generate::recvNum(int num){ m_num = num; } void Generate::run() { qDebug()<<"生成隨機數的執行緒地址:"<<QThread::currentThread(); QElapsedTimer time; QVector<int> list; //開始時間 time.start(); for(int i=0; i < m_num; i++){ //qrand()%100000 對10萬取餘、生成10萬以內的隨機數 list.push_back(qrand()%100000); } //總用時 int milsec = time.elapsed(); qDebug()<<"生成"<<m_num<<"個隨機數總用時間:"<<milsec<<"毫秒"; //傳送資料List通過sendArray這個方法 emit sendArray(list); } BubbleSort::BubbleSort(QObject *parent) : QThread(parent) { } //接受執行緒傳送來的 STL容器vector void BubbleSort::recvArray(QVector<int> list) { m_list = list; } void BubbleSort::run() { qDebug() << "氣泡排序的執行緒的執行緒地址: " << QThread::currentThread(); QElapsedTimer time; time.start(); int temp; 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]) { 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) : QThread(parent) { } 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); } 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); } }
widget.h
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include "mythread.h" QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACE class Widget : public QWidget { Q_OBJECT signals: //主執行緒傳送給子執行緒的訊號、產生多少個隨機數 void starting(int num); public: Widget(QWidget *parent = nullptr); ~Widget(); private: Ui::Widget *ui; }; #endif // WIDGET_H
widget.cpp
#include "widget.h" #include "ui_widget.h" Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui->setupUi(this); //建立子執行緒物件 Generate* gen = new Generate(this); BubbleSort* bubble = new BubbleSort(this); QuickSort* quick = new QuickSort(this); /* 訊號槽、當程式執行開始、 this當前程式 &Widget當前的視窗類, gen 生成隨機數的子程序物件、 需要呼叫recvNum槽函式接受主視窗發來的生成多少隨機數 */ connect(this,&Widget::starting,gen,&Generate::recvNum); // connect(this,SIGNAL(starting(int)),gen,SLOT(recvNum(int))); //啟動子執行緒 connect(ui->start,&QPushButton::clicked,this,[=](){ //子執行緒需要產生多少個隨機數 emit starting(10000); gen->start(); }); //傳送QVector容器 給冒泡和快拍兩個 connect(gen, &Generate::sendArray, bubble, &BubbleSort::recvArray); connect(gen, &Generate::sendArray, quick, &QuickSort::recvArray); //拿到主執行緒發過來的隨機數、通過sendArray發過來 connect(gen,&Generate::sendArray,this,[=](QVector<int> list){ bubble->start(); quick->start(); for(int i=0; i<list.size();++i) { ui->randomList->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))); } }); } Widget::~Widget() { delete ui; }