最近抽空研究了下QThread,使用起來方式多種多樣,可是在使用的同時,咱們也應該去了解Qt的線程它究竟是怎麼玩兒的。多線程
Qt的幫助文檔裏講述了2種QThread的使用方式,一種是moveToThread,另外一種是繼承QThread實現run方法,下面咱們分別來分析下函數
首先咱們來先分析move這種方式,他的使用可能像下面這樣測試
class Worker : public QObject { public slots: void doWork(const QString &) { emit resultReady(result); } }; class Controller : public QObject { QThread workerThread; public: Controller() { Worker *worker = new Worker; worker->moveToThread(&workerThread); connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater); connect(this, &Controller::operate, worker, &Worker::doWork); connect(worker, &Worker::resultReady, this, &Controller::handleResults); workerThread.start(); } ~Controller() { workerThread.quit(); workerThread.wait(); } };
這是一個標準的多線程使用方式,複雜的邏輯操做咱們能夠放在Worker對象的槽函數中進行,由於只有槽函數是在工做線程中執行的,下面我記錄了各個函數執行時所在的線程IDui
因爲線程ID是每次會發生編號,可能每一個人測試的結果不同this
細心的同窗就會發現了,Worker對象的構造函數和析構函數不在同一個線程裏邊:Worker對象的事件循環已經放到子線程中了,Worker對象刪除時,是工做線程經過拋出DeferredDelete事件執行的.net
下面結合我本身以前的一些使用理解,來分析下moveToThread是如何運做的:線程
假設有這麼一種場景,須要把對象obj從線程A移動到線程B翻譯
首先我本身看了Qt的這個函數源碼,這裏把他翻譯成爲了白話文,咱們你們能夠來看下code
假設說咱們繼承QThread實現了一個UsThread,使用起來可能像這樣對象
UsThread thd;
通過個人實踐,很惋惜,除了run函數之外,全部的函數執行,包括對象都在主線程中
若是你想着thd.moveToThread這麼幹,那麼可能會被打死
結論:我的推薦使用moveToThread這種方式進行子線程編寫
更詳細的測試結果能夠參考
QThread使用——關於run和movetoThread的區別