簡述
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
文章列表