1. 程式人生 > >Qt: 多執行緒,繼承QThread,重寫run(理論+例項)

Qt: 多執行緒,繼承QThread,重寫run(理論+例項)

多執行緒的特點:

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