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