作者legnaleurc (CA)
看板C_and_CPP
標題Re: [問題] Qt thread
時間Wed Apr 6 02:16:01 2011
※ 引述《PeterKiller (Peter)》之銘言:
: 開發平台(Platform): (Ex: VC++, GCC, Linux, ...) Ubuntu 10.10 gcc
: 額外使用到的函數庫(Library Used): (Ex: OpenGL, ...) Qt
: 問題(Question): 各位版上的高手好 最近在看學習筆記學Qt
: 學到Qthread時 發現他給的範例不能照常執行 來爬文發現在Qthread中
: 不能有QWidget的物件,需要用signal和slut實做。
: 現在遇到的困難是 我寫了一個遊戲開了兩條Qthread,其中第一條是遊戲邏輯,
: 第二條則是讓他一直刷新遊戲畫面,所以我在第二條Qthread中的run只是一直發signal
: 讓我的main thread(GUI thread)去執行update()這個函式..但是我編譯完執行後就發現
: 他整個程式都block住沒辦法動了,想請問各為有什麼解決的辦法?
: code 在此:
: main : http://codepad.org/mwJ3FXRn
: QWidget object :http://codepad.org/Ellr2zk0
: http://codepad.org/FNvMKyL9
: graph thread : http://codepad.org/TR3aeDvK
: 謝謝
強力推薦這篇文章:
http://developer.qt.nokia.com/wiki/ThreadsEventsQObjects
(有簡體中文版,但個人認為翻得不好)
這篇文章還指出 Qt 官方文件有部分是錯誤的
簡單的說,QThread 不是這麼用的(但是很多舊式的 code 都教你這麼用)
QThread 在 run() 裡的動作的確是在另一條 thread 上執行
但除了 run() 以外的部分,都是在原本的 thread (a.k.a. main thread) 上
所以你在 signal/slot connection 的時候,用的是 direct connection
因為兩個實體都在同一個 thread 裡
結果就造成 event loop blocking
若是兩個實體在不同 threads 上,signal/slot connection 才會
用 queued connection
QThread 在定位上其實是一個最低階的,用來管理 thread 的類別
這是為什麼 Qt 4.4 之後把它改為 concrete class 的原因
真正設計為用來繼承的是 QRunnable, 配合 QThreadPool 使用
QtConcurrent 則是最高階的 thread API
回到原題
你的 Graph_thread 不需要繼承 QThread,只要繼承 QObject 就好
然後建立一個 QThread 實體,使用 QObject::moveToThread()
那麼 connection 就會跨越 threads
假設你要跑在 thread 裡的函式叫 Graph_thread::doWork()
結束時會發出 signal 叫 Graph_thread::done()
QThread * thread = new QThread;
graph->moveToThread( thread ); // 使用新建的 thread
graph->connect( thread, SIGNAL( started() ), SLOT( doWork() ) );
thread->connect( graph, SIGNAL( done() ), SLOT( quit() ) );
thread->start();
PS: thread 的清理可使用 QObject::deleteLater()
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 123.205.248.119
※ 編輯: legnaleurc 來自: 123.205.248.119 (04/06 02:19)
→ uranusjr:推, 原來還有 started 跟 done 可以用, 我都傻傻的還是 04/06 02:22
→ uranusjr:subclass QThread 然後在 run() 裡面呼叫 doWork... 04/06 02:23
→ legnaleurc:這個作法的麻煩點是 QThread 什麼時候可以回收 04/06 02:24
→ legnaleurc:以原PO 的狀況,應該是不需要回收,因為它不會結束 04/06 02:25
推 PeterKiller:感謝 我馬上改試試看~ 04/06 02:33
推 PeterKiller:耶 可以順利執行了 太感謝了再推一次! 04/07 01:52
推 StrangeJ:推一個 09/24 10:18