QT多线程run函数不能使用信号与槽
一、問題描述
今天遇到一個問題,我在一個子線程中定義一個信號與槽函數,然后直接連接,最后會報錯Socket notifiers cannot be enabled or disabled from another thread
connect(thread_udpSocket,&QUdpSocket::readyRead,this,&Mythread::read_UDPData); exec();二、問題解決
這是應為在高版本中QT的run函數限制比較多,基本無法使用信號與槽的方式,在子線程中只有run里面是子線程。別的都是父線程,所以調用其他函數就是夸線程調用了。
解決辦法:
1:我是直接在connect函數第五個參數添加一個直連的方式,但是這種方式隱患比較f多,如果測試基本沒問題,做產品不行
第五個參數代表槽函數在哪個線程中執行 :
1)自動連接(AutoConnection),默認的連接方式,如果信號與槽,也就是發送者與接受者在同一線程,等同于直接連接;如果發送者與接受者處在不同線程,等同于隊列連接。(這個是線程安全的,默認是這個)
2)直接連接(DirectConnection),當信號發射時,槽函數立即直接調用。無論槽函數所屬對象在哪個線程,槽函數總在發送者所在線程執行,即槽函數和信號發送者在同一線程(注意這個是不安全的)
3)隊列連接(QueuedConnection),當控制權回到接受者所在線程的事件循環時,槽函數被調用。槽函數在接受者所在線程執行,即槽函數與信號接受者在同一線程
4)鎖定隊列連接(QueuedConnection)
Qt::BlockingQueuedConnection:槽函數的調用時機與Qt::QueuedConnection一致,不過發送完信號后發送者所在線程會阻塞,直到槽函數運行完。接收者和發送者絕對不能在一個線程,否則程序會死鎖。在多線程間需要同步的場合可能需要這個。
5)單一連接(UniqueConnection)
Qt::UniqueConnection:這個flag可以通過按位或(|)與以上四個結合在一起使用。當這個flag設置時,當某個信號和槽已經連接時,再進行重復的連接就會失敗。也就是避免了重復連接
如果槽函數中有耗時操作,比如說while循環,主線程的信號子線程是不會響應的,除非使用直接連接(DirectConnection),connect(this, &Controller::kill, worker, &Worker::stopWork, Qt::DirectConnection);,此時,槽函數工作于主線程。
(Qt有兩種多線程的方法,其中一種是繼承QThread的run函數,另外一種是把一個繼承于QObject的類轉移到一個Thread里。 Qt4.8之前都是使用繼承QThread的run這種方法,但是Qt4.8之后,Qt官方建議使用第二種方法。兩種方法區別不大,用起來都比較方便,但繼承QObject的方法更加靈活。)
2:就是使用movetothead,封裝一個類和一個線程綁定,這個我還沒用,暫時改參數使用
總結
以上是生活随笔為你收集整理的QT多线程run函数不能使用信号与槽的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Qt信号和槽连接方式的选择
- 下一篇: QT关于全局变量的申请以及使用,所有cl