簡體   English   中英

QProcess:進程仍在運行時被銷毀

[英]QProcess: Destroyed while process is still running

我正在使用Qt為xmgrace(一個2D繪圖庫)開發自定義控件界面。 我的項目中包含3個組件:

  1. 用Qt制作的GUI
  2. 一個QThread,它在后台線程中從C運行一些共享的目標代碼。
  3. 一個xmgrace窗口使用管道連接到上述兩個窗口。 (使用grace_np庫)

通過更改共享對象代碼中聲明的某些全局變量的狀態,可以完成(1) --> (2)通信。

(1) --> (3)(2) --> (3)的通信使用grace_np庫提供的內置函數。

現在,導致問題的原因是(2) --> (1)通信。 我嘗試了兩種可能的方法:a)在Qt代碼中聲明一個共享對象,該對象會發出Qt信號並在C代碼中調用。 b)從線程返回並使用返回值執行某些操作,然后重新啟動線程。

這兩種方法都給出了不可靠的結果。 我的GUI卡住/導致分段錯誤,我得到了以下消息:

QProcess: Destroyed while process is still running

我不在代碼中的任何地方使用QProcess類。 因此,這已成為一個謎。 請提供一些可能的原因信息。

PS:通向(3)的管道是一種方法,並且僅需要這種方法。

編輯1:

僅供參考,我正在使用Qt 4.2,所以我不能使用QObject方法,然后再使用movetothread()抱歉,由於我的公司政策以及我沒有這樣做,所以沒有放置代碼知道要放什么(太大)。 共享的C代碼為400k +行

我相信我找到了解決我問題的元凶。 似乎使用類QMessageBox導致了此問題。 我最初使用的是QMessageBox的靜態功能。 現在,我嘗試在堆棧和堆上都聲明它,但是問題仍然存在。 但是我發現從我的代碼中刪除對QMessageBox的所有調用都可以解決問題。 但是,現在的問題是,如何顯示消息? 我只是在推測,但是QMessageBox的模式性質是否有可能阻塞了我的程序與xmgrace之間存在的管道,並隨后導致其退出? 然后,創建自定義QMessageBox(非模態)可能會解決此問題。

編輯2:

我不是從輔助線程調用QMessageBox。 加上我使用工作線程的方式,除非關閉程序,否則它永遠不會返回。 我的QThread :: run函數的形式如下:

QThread_Object::run()
{
  c_init();
  c_main();
}

其中c_init和c_run是從共享c代碼鏈接的函數。 因此,不可能直接從這些內部調用QMessageBox。 目前,我正計划不再使用QMessageBox,而是使用QMainWindow狀態欄。 但這並不能提供全部功能。 我想這可能是Qt 4.2中的錯誤

編輯3:

前面我提到過,導致(2) --> (1)通信是問題所在。 現在,我已經完全消除了這種通信,並且更精確地發現了問題是由啟動工作線程之后隨時調用QMessageBox引起的。 前面提到的通信是導致Qt間接發出信號並調用QMessageBox的原因,我認為這是罪魁禍首。

編輯4:

好的,我忘了提及自一開始以來圍繞此問題的最大謎團。 我基本上是通過ssh在我編寫並運行該程序的工作站上(場所B)工作的(場所A)。 B連接在2個物理網絡上。 A通過網絡1連接到B。現在,從我在A終端(即通過網絡1在ssh上)工作時, 從未發生此問題。 但是當我直接訪問B或通過網絡2通過ssh訪問B時,始終會發生這種情況。請注意,每次代碼僅在B上執行。 這兩個網絡都被人使用。

編輯5

最后,我通過對QDialog進行子類化並創建自定義MessageBox來解決了我的問題,因為我實際上並不需要QMessageBox的擴展功能。 我仍然不知道QMessageBox內部到底是什么引起了問題。 我想Qt中的一些bug始終是個謎。

由於沒有代碼,因此我在這里暗中進行了一些拍攝,但這聽起來像您的QProcess是有意或無意在堆棧上創建的,或者您的QThread被過早地破壞了。 我會把錢放在錯誤啟動的QThread對象上。 很難怪您,因為該文檔是(或者直到最近才)搞砸了。 考慮閱讀此線程該線程,並且根本不繼承QThread的子類。

編輯:如果QMessageBox是您的罪魁禍首,那么我猜您正在從子線程中顯示它。 文檔中

在GUI應用程序中,主線程也稱為GUI線程,因為它是唯一允許執行與GUI相關的操作的線程。

有幾種顯示子線程消息的方法。 我個人使用qt的錯誤報告方案,並將qCritical,qDebug等重定向到stderr 另一個更簡單的方法是讓您從GUI線程捕獲的工作線程中emit QString信號,然后顯示/收集錯誤。 我喜歡讓MainWindow收集錯誤,然后在工作線程完成時立即顯示所有錯誤。

編輯2:由於問題似乎是QMessageBox是模態的(即,在工作線程向前移動時阻塞了主線程),因此可以通過在其非模態模式下使用QMessageBox來輕松解決此問題。 只需在QMessageBox構造函數/靜態函數中將0作為父窗口小部件傳遞即可。 處理將繼續而無需等待用戶退出窗口-這也可能導致同時打開多個消息框。 如果這樣可以幫助您避免錯誤,請仔細檢查代碼,以確保關閉后窗已正確銷毀。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM