文章出處

簡述

QRunnable 是所有 runnable 對象的基類,而 QThreadPool 類用于管理 QThreads 集合。

QRunnable 類是一個接口,用于表示一個任務或要執行的代碼,需要重新實現 run() 函數。

QThreadPool 管理和循環使用單獨的 QThread 對象,以幫助程序減少創建線程的成本。每個 Qt 應用程序都有一個全局 QThreadPool 對象,可以通過調用 globalInstance() 訪問。

詳細描述

QThreadPool 支持多次執行相同的 QRunnable,通過調用 QThreadPool::tryStart(this) 從 run() 函數內。如果啟用了 autoDelete,當最后一個線程退出 run() 函數,QRunnable 將被刪除。多次調用 QThreadPool::start() 使用相同的 QRunnable,當啟用 autoDelete 時會創建一個競爭條件,不推薦使用。

一定時間未使用線程將會到期,默認到期超時是 30000 毫秒(30秒)。可以使用 setExpiryTimeout() 來改變,設定一個負值,則會禁用到期機制。

調用 maxThreadCount() 查詢使用線程的最大數量。如果需要,可以使用 setMaxThreadCount() 進行更改。默認的 maxThreadCount() 是 QThread::idealThreadCount()。activeThreadCount() 函數返回當前正在工作線程的數量。

reserveThread() 函數儲備一個線程用于外部使用。當線程完成后,使用 releaseThread(),以便它可以被重新使用。從本質上講,這些函數暫時增加或減少活躍線程的數量,并且當實現耗時的操作時對 QThreadPool 是不可見的,這比較有用。

注意: QThreadPool 是一個管理線程的低級類,高級替代品可以用 Qt Concurrent 模塊。

基本使用

要使用 QThreadPool 的一個線程,子類化 QRunnable 并實現 run() 虛函數。然后創建一個對象,并把它傳遞給 QThreadPool::start()。

class HelloWorldTask : public QRunnable{    void run() {        qDebug() << "Hello world from thread " << QThread::currentThread();    }}HelloWorldTask *hello = new HelloWorldTask();// QThreadPool取得所有權,并自動刪除 helloQThreadPool::globalInstance()->start(hello);

默認情況下,QThreadPool 會自動刪除 QRunnable。可以使用 QRunnable::setAutoDelete() 來改變自動刪除標志。

自定義信號/槽

打開 QRunnable 所在頭文件,會發現它并不繼承自 QObject,也就是說,根本無法使用 QObject 的特性,例如:信號/槽、事件等。

為了便于使用,我們可以繼承 QObject:

class HelloWorldTask : public QObject, public QRunnable{    Q_OBJECT// 自定義信號signals:    void finished();public:     void run() {         qDebug() << "Hello Thread : " << QThread::currentThreadId();         emit finished();     }};

使用時,連接信號槽即可:

class MainWindow : public QMainWindow{    Q_OBJECTpublic:    explicit MainWindow(QWidget *parent = 0)        : QMainWindow(parent)    {        qDebug() << "Main Thread : " << QThread::currentThreadId();        // ...        HelloWorldTask *hello = new HelloWorldTask();        connect(hello, SIGNAL(finished()), this, SLOT(onFinished()));        QThreadPool::globalInstance()->start(hello);        // ...    }private slots:    void onFinished() {        qDebug() << "SLOT Thread : " << QThread::currentThreadId();    }};

為了介紹所屬線程,使用 qDebug 將各自的線程 ID 進行調試輸出。結果如下:

Main Thread : 0xb308
Hello Thread : 0xb33c
SLOT Thread : 0xb308

顯然,槽函數所在線程與主線程相同。

如果想要槽函數在次線程中執行,只需改變信號槽的連接方式:

connect(hello, SIGNAL(finished()), this, SLOT(onFinished()), Qt::DirectConnection);

這時,就得到了想要的結果啦:

Main Thread : 0xb030
Hello Thread : 0xacf8
SLOT Thread : 0xacf8

就愛閱讀www.92to.com網友整理上傳,為您提供最全的知識大全,期待您的分享,轉載請注明出處。
歡迎轉載:http://www.kanwencang.com/bangong/20161116/54067.html

文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()