淺談 Qt 子線程 信號隊列
Qt子線程 信號隊列是本文要介紹的內(nèi)容,聲明:以下純屬個人理解,看到的就當(dāng)錯的看。對 Qt 的多線程編程沒有深究,只了解了基本的用法,夠我用就行了。
之所以寫這篇文章是因為前幾天遇到一個疑問:如果其他幾個線程同時向一個線程發(fā)signal,而這個線程沒有自己的事件循環(huán),那是不是會丟失signal呢?
下面是我總結(jié)的兩種子線程的工作方式
1、讓子線程進(jìn)入事件循環(huán),這樣的話多余的signal就會進(jìn)入該線程的事件隊列,不會丟失。問題是這時子線程的槽函數(shù)都是在該子線程對象所在的線程(很可能是主線程)執(zhí)行,這樣似乎失去了多線程的意義。
- void run()
- {
- exec();
- }
- void slot1(); //處理工作
- void slot2(); //處理工作
2、子線程沒有事件循環(huán),直接在run里處理工作,主線程可通過信號連接到該子線程的槽來控制flag,從而控制子線程的暫停和繼續(xù)。但是,如果還有另外幾個線程不時地向通過slot2()給somarg賦值的話,即使給slot2()加了鎖保證了不會被同時賦值,但那些同時進(jìn)入的賦值信號沒有隊列可進(jìn),這樣會不會就丟失了呢
- void run()
- {
- while(1)
- {
- while(flag)
- {
- dosomething(somarg);
- }
- }
- }
- void slot1(); //控制flag
- void slot2(); //給somarg賦值
經(jīng)試驗,雖然第一種辦法不需要exec()進(jìn)入事件循環(huán)也可以觸發(fā)槽們在調(diào)用這個線程對象的線程工作,但是這樣無法保證同時傳進(jìn)去的信號不會丟失;加上exec()后,子線程進(jìn)入事件循環(huán),不會馬上結(jié)束,并且會有事件隊列,這樣可以保證信號不會丟失。唯一的缺點(diǎn)就是這些槽不工作在子線程。
擬對策:
建立一個隊列線程,CQueueThread,這個線程進(jìn)入自己的事件循環(huán),在這個類中有其它線程的對象作為成員變量,這些線程則沒有各自的事件隊列,直接在run中死循環(huán)工作,主線程信號連接到CQueueThread的槽來控制其他線程開始工作,這樣信號會進(jìn)入事件隊列不會丟失,而那些死循環(huán)的繁雜工作則各自在各自的線程中運(yùn)行。
這個CQueueThread可以用主線程代替(主線程必然是有事件循環(huán)的),主線程中有個槽作緩沖用,接收來自各方的命令,再魚貫發(fā)往目標(biāo)線程。
"run()開的才是新線程,QThread的構(gòu)造函數(shù)以及其他成員都在你的主線程中。"
小結(jié): Qt 子線程 信號隊列的內(nèi)容介紹完了,希望本文對你有所幫助。關(guān)于線程的更多資料,請參考編輯推薦。