简体   繁体   English

QProcess:进程仍在运行时被销毁

[英]QProcess: Destroyed while process is still running

I am using Qt for developing a custom control interface to xmgrace, a 2D plotting library. 我正在使用Qt为xmgrace(一个2D绘图库)开发自定义控件界面。 I have 3 components in my project: 我的项目中包含3个组件:

  1. A GUI made in Qt 用Qt制作的GUI
  2. A QThread which runs some shared object code from C in a background thread. 一个QThread,它在后台线程中从C运行一些共享的目标代码。
  3. An xmgrace window connected to both the above using a pipe. 一个xmgrace窗口使用管道连接到上述两个窗口。 (Using the grace_np library) (使用grace_np库)

Communication from (1) --> (2) is done by changing status of some global variables declared in the shared object code. 通过更改共享对象代码中声明的某些全局变量的状态,可以完成(1) --> (2)通信。

Communication from (1) --> (3) & (2) --> (3) is using built in functions provided by the grace_np library. (1) --> (3)(2) --> (3)的通信使用grace_np库提供的内置函数。

Now, communication from (2) --> (1) is what is causing problems. 现在,导致问题的原因是(2) --> (1)通信。 I tried 2 possible ways I could think of: a) Declaring a shared object in Qt code which emits a Qt Signal and is called within the C code. 我尝试了两种可能的方法:a)在Qt代码中声明一个共享对象,该对象会发出Qt信号并在C代码中调用。 b) Returning from the thread and using the return value to perform some operation and then restart the thread. b)从线程返回并使用返回值执行某些操作,然后重新启动线程。

Both these methodologies have given unreliable results. 这两种方法都给出了不可靠的结果。 My GUI gets stuck/causes segmentation fault and I get the message: 我的GUI卡住/导致分段错误,我得到了以下消息:

QProcess: Destroyed while process is still running

I am not using the QProcess class anywhere in my code. 我不在代码中的任何地方使用QProcess类。 So this has become a mystery. 因此,这已成为一个谜。 Please provide some info on what could be the possible causes for this. 请提供一些可能的原因信息。

PS: The pipe to (3) is one way and is required that way only. PS:通向(3)的管道是一种方法,并且仅需要这种方法。

Edit 1: 编辑1:

FYI I'm using Qt 4.2, So I can't use the QObject approach and then use a movetothread() I'm sorry for not putting the code, as I can't due to company policies and also because I don't know what to put (Its too huge). 仅供参考,我正在使用Qt 4.2,所以我不能使用QObject方法,然后再使用movetothread()抱歉,由于我的公司政策以及我没有这样做,所以没有放置代码知道要放什么(太大)。 The shared c code is 400k+ lines 共享的C代码为400k +行

I believe I have found the culprit to my problem. 我相信我找到了解决我问题的元凶。 It seems that using the class QMessageBox is causing this problem. 似乎使用类QMessageBox导致了此问题。 I was initially using static function of QMessageBox. 我最初使用的是QMessageBox的静态功能。 Now I have tried declaring it over both the stack and the heap, but the problem still persists. 现在,我尝试在堆栈和堆上都声明它,但是问题仍然存在。 But I have found that removing all calls to QMessageBox from my code solves the problem. 但是我发现从我的代码中删除对QMessageBox的所有调用都可以解决问题。 But then the problem now is, how do I show messages? 但是,现在的问题是,如何显示消息? I am just speculating here, but is it possible that the modal nature of QMessageBox is blocking the pipe existing between my program and xmgrace and subsequently causing it to quit? 我只是在推测,但是QMessageBox的模式性质是否有可能阻塞了我的程序与xmgrace之间存在的管道,并随后导致其退出? Then creating a custom QMessageBox (non modal) might solve this issue. 然后,创建自定义QMessageBox(非模态)可能会解决此问题。

Edit 2: 编辑2:

I'm not calling the QMessageBox from the worker thread. 我不是从辅助线程调用QMessageBox。 Plus the way I'm using the worker thread, it never returns unless I close the program. 加上我使用工作线程的方式,除非关闭程序,否则它永远不会返回。 To give an idea my QThread::run function is of the form: 我的QThread :: run函数的形式如下:

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

where c_init & c_run are functions linked from shared c code. 其中c_init和c_run是从共享c代码链接的函数。 So it is impossible to call a QMessageBox from within these directly. 因此,不可能直接从这些内部调用QMessageBox。 For now I'm planning on doing away with the QMessageBox and using the QMainWindow status bar instead. 目前,我正计划不再使用QMessageBox,而是使用QMainWindow状态栏。 But then it doesn't give the entire functionality. 但这并不能提供全部功能。 I suppose this could be a bug in Qt 4.2 我想这可能是Qt 4.2中的错误

Edit 3: 编辑3:

I mentioned earlier that communication from (2) --> (1) was what was causing problems. 前面我提到过,导致(2) --> (1)通信是问题所在。 Now I have done away with this communication completely and have discovered more precisely that the problem is caused by invoking QMessageBox anytime after starting the worker thread. 现在,我已经完全消除了这种通信,并且更精确地发现了问题是由启动工作线程之后随时调用QMessageBox引起的。 Earlier the communication mentioned above was causing Qt to emit a signal indirectly and invoke a QMessageBox which I believe was the culprit. 前面提到的通信是导致Qt间接发出信号并调用QMessageBox的原因,我认为这是罪魁祸首。

Edit 4: 编辑4:

Ok, I forgot to mention the biggest mystery surrounding this problem since the beginning. 好的,我忘了提及自一开始以来围绕此问题的最大谜团。 I basically work(Place A) via ssh on a workstation(Place B) on which I code and run this program. 我基本上是通过ssh在我编写并运行该程序的工作站上(场所B)工作的(场所A)。 B is connected on 2 physical networks. B连接在2个物理网络上。 A is connected to B through Network 1. Now this problem has never occured while working from my terminal at A (ie on ssh via Network 1). A通过网络1连接到B。现在,从我在A终端(即通过网络1在ssh上)工作时, 从未发生此问题。 But it consistently occurs when I access B directly or through ssh over Network 2. Please note that every time the code is executed on B only. 但是当我直接访问B或通过网络2通过ssh访问B时,始终会发生这种情况。请注意,每次代码仅在B上执行。 Both these networks are used by hundereds. 这两个网络都被人使用。

Edit 5 编辑5

Finally, I have solved my problem by sub-classing QDialog and making a custom MessageBox as I don't really require the extended functionality of QMessageBox. 最后,我通过对QDialog进行子类化并创建自定义MessageBox来解决了我的问题,因为我实际上并不需要QMessageBox的扩展功能。 I still don't know what precisely within QMessageBox was causing the problem. 我仍然不知道QMessageBox内部到底是什么引起了问题。 I suppose some bug within Qt which will always remain a mystery. 我想Qt中的一些bug始终是个谜。

Since there's no code I'm shooting in the dark a little here, but it sounds like your QProcess was created on the stack, intentionally or not, or your QThread is getting destroyed prematurely. 由于没有代码,因此我在这里暗中进行了一些拍摄,但这听起来像您的QProcess是有意或无意在堆栈上创建的,或者您的QThread被过早地破坏了。 I'd put money on your QThread objects being launched incorrectly. 我会把钱放在错误启动的QThread对象上。 It's hard to blame you since the documentation is (or was until recently) screwy. 很难怪您,因为该文档是(或者直到最近才)搞砸了。 Consider reading this thread and this thread and don't sub-class QThread at all. 考虑阅读此线程该线程,并且根本不继承QThread的子类。

Edit: If QMessageBox is your culprit, then I'm guessing that you're displaying it from the child thread. 编辑:如果QMessageBox是您的罪魁祸首,那么我猜您正在从子线程中显示它。 From the documentation : 文档中

In GUI applications, the main thread is also called the GUI thread because it's the only thread that is allowed to perform GUI-related operations. 在GUI应用程序中,主线程也称为GUI线程,因为它是唯一允许执行与GUI相关的操作的线程。

There are several ways to display messages from a child thread. 有几种显示子线程消息的方法。 Personally, I use qt's error reporting scheme and redirect qCritical, qDebug, etc to stderr . 我个人使用qt的错误报告方案,并将qCritical,qDebug等重定向到stderr Another easier way to do it would be for you to emit a QString signal from your worker thread that's caught by your GUI thread, which then displays/collects the error. 另一个更简单的方法是让您从GUI线程捕获的工作线程中emit QString信号,然后显示/收集错误。 I like to have my MainWindow collect the errors and then display them all at once when the worker thread finishes. 我喜欢让MainWindow收集错误,然后在工作线程完成时立即显示所有错误。

Edit 2: Since the problem seems to be QMessageBox being modal (ie, blocking your main thread while the worker thread moves forward), you can easily solve this by using QMessageBox in its non-modal modes. 编辑2:由于问题似乎是QMessageBox是模态的(即,在工作线程向前移动时阻塞了主线程),因此可以通过在其非模态模式下使用QMessageBox来轻松解决此问题。 Simply pass 0 as the parent widget in the QMessageBox constructor/static function. 只需在QMessageBox构造函数/静态函数中将0作为父窗口小部件传递即可。 Processing will continue without waiting for the user to exit the window--this might also result in multiple message boxes being open at the same time. 处理将继续而无需等待用户退出窗口-这也可能导致同时打开多个消息框。 If that helps you avoid the error, go over your code carefully to make sure the windows are properly destroyed after closing. 如果这样可以帮助您避免错误,请仔细检查代码,以确保关闭后窗已正确销毁。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM