Qt: 多執行緒,繼承QThread,重寫run(理論+例項)
阿新 • • 發佈:2019-01-26
多執行緒的特點:
1、 多個執行緒共享程序的記憶體空間,多執行緒記憶體空間統一。
2、 每個執行緒都有自己獨立的棧空間,多個執行緒之間是相互獨立的。
3、 執行緒是作業系統運算排程的最小單位。
4、 程序支援多執行緒,但是必須有一個主執行緒。
5、 子執行緒都是通直接或者間接的通過主執行緒啟動。
6、 主執行緒結束,所有子執行緒也會結束。
常用函式:
MoveToThread();
CurrentThread(),返回當前執行緒的指標。
CurrentThreadId(),返回當前執行緒的控制代碼。
生存執行緒:執行緒被建立時,該執行緒所在的執行緒。
注意:
多執行緒不是必須的,大多數情況下,一個主執行緒就可以完成相應的工作。
執行緒越多,對系統造成的負擔越大。
實現多執行緒的方法:
1、Qthread(傳統方法):繼承自Qthread,實現run()函式,執行Qthread的start函式,執行緒開始執行。
2、Qtconcurrt(高階API,更加方便使用)
例:
下面以繼承QThread,重寫run()函式為例
功能:在主執行緒中建立兩個子執行緒,點選start和stop分別開始和結束列印文字。
ui檔案主介面:
先看效果圖:
原始碼:
//main.cpp
#include <QApplication> #include <QDebug> #include "threaddialog.h" #include <QThread> int main(int argc, char *argv[]) { QApplication a(argc, argv); ThreadDialog dialog ; dialog.show(); return a.exec(); <p>} </p>
//thread.h
#ifndef THREAD_H #define THREAD_H #include <QThread> #include <QtCore> #include <QObject> #include <QMutex> #include <iostream> using namespace std; class Thread : public QThread { Q_OBJECT public: Thread(); void setMessage(const QString &message); void stop(); private slots: void run(); private: QString messageStr; volatile bool stopped; }; #endif // THREAD_H
//thread.cpp
#include "thread.h"
#include <QTimer>
#include <QMutexLocker>
Thread::Thread()
{
stopped = false;
}
void Thread::setMessage(const QString &message)
{
messageStr = message;
}
void Thread::stop()
{
stopped = true;
}
void Thread::run()
{
while(!stopped)
{
qDebug()<<messageStr;
}
stopped = false;
std::cerr<<std::endl;
}
//threaddialog.h
#ifndef THREADDIALOG_H
#define THREADDIALOG_H
#include <QMainWindow>
#include "thread.h"
#include <QPushButton>
#include <QCloseEvent>
namespace Ui {
class ThreadDialog;
}
class ThreadDialog : public QMainWindow
{
Q_OBJECT
public:
explicit ThreadDialog(QWidget *parent = 0);
~ThreadDialog();
protected:
void closeEvent(QCloseEvent *e);
private:
Thread threadA;
Thread threadB;
QPushButton *threadABtn;
QPushButton *threadBBtn;
QPushButton *quitBtn;
private slots:
void startOrStopThreadA();
void startOrStopThreadB();
void on_quit_clicked();
private:
Ui::ThreadDialog *ui;
};
#endif // THREADDIALOG_H
//threaddialog.cpp
#include "threaddialog.h"
#include "ui_threaddialog.h"
#include <QTimer>
ThreadDialog::ThreadDialog(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::ThreadDialog)
{
ui->setupUi(this);
threadA.setMessage("I am A");
threadB.setMessage("I am B");
threadABtn = new QPushButton("Start A");
threadBBtn = new QPushButton("Start B");
quitBtn = new QPushButton("Quit");
connect(ui->threadABtn,SIGNAL(clicked(bool)),SLOT(startOrStopThreadA()));
connect(ui->threadBBtn,SIGNAL(clicked(bool)),SLOT(startOrStopThreadB()));
}
ThreadDialog::~ThreadDialog()
{
delete ui;
}
void ThreadDialog::closeEvent(QCloseEvent *e)
{
threadA.stop();
threadB.stop();
threadA.wait();
threadB.wait();
e->accept();
}
void ThreadDialog::startOrStopThreadA()
{
if(threadA.isRunning())
{
threadA.stop();
ui->threadABtn->setText("Start A");
}
else
{
threadA.start();
ui->threadABtn->setText("Stop A");
}
}
void ThreadDialog::startOrStopThreadB()
{
if(threadB.isRunning())
{
threadB.stop();
ui->threadBBtn->setText("Start B");
}
else
{
threadB.start();
ui->threadBBtn->setText("Stop B");
}
}
void ThreadDialog::on_quit_clicked()
{
close();
}