Qt 多線程串口通信問題?

現在我的項目關於線程和串口通信這裡出了很多問題。思路現在就是我首先自己封裝了QSerialport的open、read、write函數,然後在通信層中開了 一個線程,在這個線程的構造函數中new了我封的serialport,並且就在這裡打開,然後在下面的函數中進行了write和read的調用(封包是調用封包的函數,解包是觸發接收到數據之後給的信號retureData)。

然後問題就來了

1.每次都寫到串口了(open返回true,write返回了長度), 但是沒有發出去。

2.只能發一次數據,並且有正確返回,但是接受完之後程序就崩潰了。

我感覺是線程的時間什麼地方有問題,因為線程不是我寫的,我只是封裝了類,但是我們老大又說QSerialPort類不能跨線程調用。

我也不是很懂。

如果看明白我的問題,希望給我留個言,我們老大叫我來調所有通信,壓力好大,兩周了都沒進展。這周五還得回學校拿畢業證、感覺才實習就做些這完全搞不懂啊!


Qt的QThread不是讓你繼承著寫的

你應該寫個類用來操作QSerialPort,類成員里放一個QSerialPort指針,然後把對外交互的函數都寫成槽,再寫一個init函數

然後,在你構造這個類的地方,也構造一個QThread,將類對象moveToThread(thread),thread-&>start()

從此,所有通過信號槽執行的該類函數,都會在子線程里運作

將thread的started信號綁定到obj的init函數上,init函數里進行new QSerialPort和open操作

讀操作,把QSerialPort的readyRead信號綁到這個obj的槽上。槽里調用read,然後把讀的結果用信號emit到外部

寫操作,在obj里提供一個write槽函數,函數內直接調用串口類的write。外部使用時,emit一個信號,該信號觸發obj的write槽函數

另外,你們老大說的沒錯,QIODevice的子類都不應跨線程操作

————————————————————————

總結,Qt的子線程寫法:

1、不要寫死循環!需要持續做的事情,做個timer,綁到timeout信號上

2、寫一個object,將其moveToThread

3、該object,對外的所有操作,全部用信號槽。通過槽接收外部的調用操作(比如open、close、write),通過信號發送數據給外部(比如接收到的數據)

4、需要在子線程分配的資源,比如QSerialPort,全部在該object的某個槽函數(如init)中進行,將該槽函數綁定到線程的started信號上

5、程序退出時,不要直接delete object,因為那個對象不處於子線程。將qApp的aboutToQuit函數,綁定到object的deletelater槽上,這樣就會由那個線程負責delete這個object。然後將object的destroyed信號,綁定到線程的quit槽上,將線程的finished信號綁定到線程對象的deletelater槽上。這樣,程序即將退出-&>由子線程刪除object-&>線程停止-&>線程對象銷毀

6、線程對象,以及move到線程里的對象,都不要設置parent

QThread這個基於類的子線程,比起傳統的基於函數的子線程好處在於,你可以在線程中放任意多個對象運行。只要你保證所有對象都是通過信號槽運作,而不是像寫c的子線程那樣用while(true)運作,那麼一個QThread就可以管理任意多個對象


Qt的信號槽,事件,線程封裝這麼好用,留出來槽不就行了。

提示:QObject::moveToThread


你說:

在這個線程的構造函數中new了我封的serialport,並且就在這裡打開

提醒一下,線程對象構造,仍然是現有舊線程中執行。


哇,接樓上的,剛好一年,我現在也在調串口,多線程,有問題,就在此刻,正在加班。。。


好好調試,多翻外文資料,封裝庫有的,源代碼也很easy


推薦閱讀:

linux線程是如何進行切換的?
在不改變方法簽名(method signature)的情況下, 請描述這段代碼的問題以及如何解決?
測試線程同步中出現的阻塞問題?
多線程執行順序控制?
求詳解該InterlockedIncrement的實現?

TAG:QtC開發框架 | 多線程 | 串口通信 |