“QObject調用moveToThread()后 該如何釋放”及QThread 的啟動關閉


QThread的另一種用法, 不用繼承QThread和重載run()函數:

1  QThread *thread = new QThread( );
2  Task    *task   = new Task();
3  task->moveToThread(thread);
4  connect( thread, SIGNAL(started()), task, SLOT(doWork()) );
5  connect( task, SIGNAL(workFinished()), thread, SLOT(quit()) );//從Qt4.4開始,qthreads-no-longer-abstract,run 默認調用 QThread::exec(),即啟動消息隊列
6  //automatically delete thread and task object when work is done:
7  connect( thread, SIGNAL(finished()), task, SLOT(deleteLater()) ); 8  connect( thread, SIGNAL(finished()), thread, SLOT(deleteLater()) ); 9  thread->start();
 1 class Task : public QObject
 2 {
 3 Q_OBJECT
 4 public:
 5     Task();
 6     ~Task();
 7 public slots:
 8     void doWork();
 9 signals:
10     void workFinished();
11 };

connect()的第五個參數 
有六種: 
1. Qt::AutoConnection 
2. Qt::DirectConnection 
3. Qt::QueuedConnection 
4. Qt::BlockingQueuedConnection 
5. Qt::UniqueConnection 
6. Qt::AutoCompatConnection

前兩種比較相似,都是同一線程之間連接的方式,不同的是Qt::AutoConnection是系統默認的連接方式。這種方式連接的時候,槽不是馬上被執行的,而是進入一個消息隊列,待到何時執行就不是我們可以知道的了,當信號和槽不是同個線程,會使用第三種QT::QueueConnection的鏈接方式。如果信號和槽是同個線程,調用第二種Qt::DirectConnection鏈接方式。

第二種Qt::DirectConnection是直接連接,也就是只要信號發出直接就到槽去執行,無論槽函數所屬對象在哪個線程,槽函數都在發射信號的線程內執行,一旦使用這種連接,槽將會不在線程執行!。

第三種Qt::QueuedConnection和第四種Qt::BlockingQueuedConnection是相似的,都是可以在不同進程之間進行連接的,不同的是,這里第三種是在對象的當前線程中執行,並且是按照隊列順序執行。當當前線程停止,就會等待下一次啟動線程時再按隊列順序執行 ,等待QApplication::exec()或者線程的QThread::exec()才執行相應的槽,就是說:當控制權回到接受者所依附線程的事件循環時,槽函數被調用,而且槽函數在接收者所依附線程執行,使用這種連接,槽會在線程執行。

第四種Qt::BlockingQueuedConnection是(必須信號和曹在不同線程中,否則直接產生死鎖)這個是完全同步隊列只有槽線程執行完才會返回,否則發送線程也會等待,相當於是不同的線程可以同步起來執行。

第五種Qt::UniqueConnection跟默認工作方式相同,只是不能重復連接相同的信號和槽;因為如果重復鏈接就會導致一個信號發出,對應槽函數就會執行多次。

第六種Qt::AutoCompatConnection是為了連接QT4 到QT3的信號槽機制兼容方式,工作方式跟Qt::AutoConnection一樣。顯然這里我們應該選擇第三種方式,我們不希望子線程沒結束主線程還要等,我們只是希望利用這個空閑時間去干別的事情,當子線程執行完了,只要發消息給主線程就行了,到時候主線程會去響應。

 

轉自:http://blog.csdn.net/liukang325/article/details/50454409


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM