为啥不能等待 Qt 进程在静态析构函数中完成?

Posted

技术标签:

【中文标题】为啥不能等待 Qt 进程在静态析构函数中完成?【英文标题】:Why is it not possible to wait for a Qt process to finish in a static destructor?为什么不能等待 Qt 进程在静态析构函数中完成? 【发布时间】:2013-01-03 20:39:11 【问题描述】:

以下代码启动一个需要一秒钟才能完成的进程,然后等待该进程完成后再退出。出于某种原因,即使进程完成,以下代码仍会在 p->waitForFinished() 中挂起。

#include <QtCore/QProcess>    

class A

  public:
    A():
        p(0)
    
    

    ~A()
    
        p->waitForFinished();
        delete p;
    

    void start()
    
        p = new QProcess(0);
        p->start("sleep 1");
    

    QProcess *p;
;

int main(void)

  static A a;
  a.start();

  return 0;

不过,只要a不是静态声明的,而是如下:

A a;

waitForFinished() 调用成功。这是一个 Qt 错误,还是这是预期的行为?我的怀疑是,一旦调用A 的析构函数,检测应用程序是否成功完成所需的某种逻辑已经被销毁。

【问题讨论】:

【参考方案1】:

你试图以两种不同的方式同时清理QProcess创建的线程,所以这是你程序中的一个错误。

您已通过从main 返回来分离线程(这会终止进程中的所有线程,如果它们是可连接的,则将它们分离)。

您已经清理了QProcess 线程,通过waitForFinished 加入它。

你可以分离一个线程,也可以加入它,但你不能两者都做,即使是间接的。显然,分离获胜,连接挂起。

这很可能是因为QProcess 使用了自己的终止信号,而不是线程库中内置的终止信号。因此,main 的返回会在线程发送终止信号之前终止线程,让 waitForFinished 函数等待永远不会发送的信号。

作为一般规则,线程不应在构造函数中创建,也不应在析构函数中清除。这主要是因为这些操作的时间需要比可能的更明确的控制。并且它们不应该在main 开始之前创建,也不应该在main 返回之后清理——同样,因为您需要控制这些事情发生的上下文。

【讨论】:

以上是关于为啥不能等待 Qt 进程在静态析构函数中完成?的主要内容,如果未能解决你的问题,请参考以下文章

析构函数为啥能释放对象内存?

C++ 类设计总结回顾------析构函数

为啥我必须在析构函数中调用 MPI.Finalize() ?

析构函数私有类方法;继承;环境部署;多线程多进程;锁

为啥在调用它的析构函数后我可以访问这个堆栈分配的对象? [复制]

17. 虚析构函数再谈动态绑定多态到底是啥抽象类