QRunnable與多線程

前面的博文中,我們講過QtConcurrent模塊,該模塊是Qt中實現併發編程的高級API接口,而QRunnable結合QThreadPoll和QThread都是Qt中與併發編程相關的低級接口。今天我們先來看QRunnable和QThreadPool。

QRunnable類在Qt中是所有可運行對象的基類,代表了由run()函數表示的一個任務或一段要執行的代碼。我們一般使用該類和QThreadPool來在另一個獨立的線程中執行該代碼。並且,如果QRunnable對象的autoDelete()設爲true的話,QThreadPool會在run()運行結束後自動刪除該對象。

下面,我們寫一個例子,來使用一下該類。

新建一個Qt控制檯程序,然後寫一個派生自QRunnable的類,並重新實現其中的純虛函數run()即可。

#ifndef RUNNABLE_H
#define RUNNABLE_H
#include <QRunnable>

class Runnable : public QRunnable
{
public:
    Runnable();
    void run();
};

#endif // RUNNABLE_H
#include "runnable.h"
#include <QDebug>
#include <QThread>

Runnable::Runnable()
{

}

void Runnable::run()
{
    qDebug() << "child thread id: " << QThread::currentThreadId();
    int i = 10;
    while(i--)
    {
        qDebug() << QString("hello world %1").arg(i);
    }
}


然後在main函數中,使用QThreadPool來啓動一個Runnable對象,在獨立的線程中運行。

#include <QCoreApplication>
#include "runnable.h"
#include <QThreadPool>
#include <QDebug>
#include <QThread>

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

    qDebug() << "main thread id: " << QThread::currentThreadId();
    Runnable *r = new Runnable();
    QThreadPool::globalInstance()->start(r);
    //QThreadPool::globalInstance()->waitForDone();
    qDebug() << "end";

    return a.exec();
}
其運行結果如下:



根據打印的thread ID可知,這些輸出是由兩個的線程的輸出的,並且“end”先與子線程輸出。如果我們想等到子線程運行完成再輸出“end”,只需將代碼中註釋的那句打開即可。

運行結果如下:


此時,“end”就在子線程運行完成後才輸出,即我們等待了線程的結束。

我們還可以實現一個析構函數,來驗證QThreadPool是否爲我們釋放了Runnable對象。

Runnable::~Runnable()
{
    qDebug() << "deleted";
}
在此執行程序,輸出如下:



因爲QRunnable的autoDelete屬性默認爲true,所以QThreadPool會在run()函數運行結束後,自動幫我們刪除了Runnable對象。如果我們在main函數中,創建出Runnable對象後,修改該屬性爲false,那麼將看不到“deleted”,因爲此時Runnable對象的釋放工作,將由我們自己來負責。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章