Qt 串口通信 waitForReadyRead函數與waitForBytesWritten函數導致的內存增長問題記錄


這段時間做項目需要有一個進行快速采集信息的設備,但是在單獨測試的過程中發現程序的內存占用會一直增長,也就是所謂的內存泄露問題。這個問題困擾了我們幾個星期,我嘗試了通過事件循環重寫waitfor系列函數來解決這個問題,但是由於線程包含問題導致了新的問題。。。今天在Qt的官方論壇上搜索時發現15年就有人發現了這個問題,然后上傳了bug庫並得到了解決,所以特此記錄。

1.問題描述

 通過形如下面的代碼進行串口的讀取或者寫入(高頻率),會導致運行exe的內存占用不斷提升,在一定時間后內存泄露到一定程度會導致軟件崩潰。

1 while (1) 2 { 3     if (port.waitForReadyRead(10)) 4  { 5         port->readAll(); 6  } 7 }

2.問題原因分析

 因為waitfor系列函數是通過readyRead()信號與bytesWritten()信號來實現的,如果產生這兩個信號過快(就像上面的代碼,死循環執行瘋狂產生信號),會導致對應到槽函數的事件(信號到槽的執行是一種事件,我之前寫過,這個事件將會到對應線程的消息隊列中排隊等待執行)一直在消息隊列中瘋狂阻塞,阻塞的結果就是消息隊列不斷膨脹,從而內存不斷增加,直到隊列到達上限導致程序崩潰。

3.問題解決方案

 知道原理后問題解決就很簡單了,說穿了就是讓線程去執行消息隊列中的事件而不是一直產生,而Qt專門為這種情況制定了一個函數:qApp->processEvents(),這個函數的意思就是讓調用此函數的線程執行其消息隊列中的事件,直至沒有事件可以執行為止。可見在死循環中加上這個函數之后,相關的內存泄露問題將迎刃而解,就像下面這樣:

1 while (1) 2 { 3     if (port.waitForReadyRead(10)) 4  { 5         qApp->processEvents(); 6         port->readAll(); 7  } 8 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM