【问题标题】:Forked (background) Qt app will not exit properly分叉(后台)Qt 应用程序将无法正确退出
【发布时间】:2014-02-25 20:09:10
【问题描述】:

我有一个在前台运行良好的多线程 Qt/C++ 应用程序,但是当它进行 dameonizes 时,它无法正常关闭。该进程仍然处于活动状态,但处于等待状态 - 请参阅等待程序的回溯:

(gdb) bt
#0  0x000000372460b575 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
#1  0x00007f8990fb454b in QWaitCondition::wait(QMutex*, unsigned long) ()
   from /opt/Qt/5.1.1/gcc_64/lib/libQt5Core.so.5
#2  0x00007f8990fb3b3e in QThread::wait(unsigned long) () from /opt/Qt/5.1.1/gcc_64/lib/libQt5Core.so.5
#3  0x00007f8990fb0402 in QThreadPoolPrivate::reset() () from /opt/Qt/5.1.1/gcc_64/lib/libQt5Core.so.5
#4  0x00007f8990fb0561 in QThreadPool::waitForDone(int) () from /opt/Qt/5.1.1/gcc_64/lib/libQt5Core.so.5
#5  0x00007f89911a4261 in QMetaObject::activate(QObject*, int, int, void**) ()
   from /opt/Qt/5.1.1/gcc_64/lib/libQt5Core.so.5
#6  0x00007f89911a4d5f in QObject::destroyed(QObject*) () from /opt/Qt/5.1.1/gcc_64/lib/libQt5Core.so.5
#7  0x00007f89911aa3ee in QObject::~QObject() () from /opt/Qt/5.1.1/gcc_64/lib/libQt5Core.so.5
#8  0x0000000000409d8b in main (argc=1, argv=0x7fffba44c8f8) at ../../src/main.cpp:27
(gdb) 

我现在意识到我的代码首先创建了一个线程,然后分叉,以防万一。前台进程正常退出(确认PID没了),但后台pid永远不会结束。这可能与我在父级中创建 QThread 的事实有关吗?如果是这样,我该如何让这个等待的线程死掉?

如果没有,是否有特殊方法可以退出已被守护的控制台应用程序? (在 Qt 中)

【问题讨论】:

    标签: qt process fork wait qthread


    【解决方案1】:

    Qt 没有经过测试与fork() 互操作,所以不要期望它会被支持。它是不可移植的,并且在大多数情况下是不必要的。

    您应该使用分离的QProcess 生成自己,然后立即退出。如果您需要在衍生过程中进行任何初始化,您可以将相关数据传递给子进程。

    My other answer 说明了这种技术的基础,并且可以移植到运行 Qt 的所有平台。在这种情况下,您将使用 QProcess::startDetached 在其自己的会话中启动子进程以充当守护进程。

    您可能还想看看QtService 解决方案。它可以在 Unix 和 Windows 之间移植,前者使用守护进程,后者使用原生服务 API。

    【讨论】:

    • 我不知道这一点!你能指出一个关于不使用 fork 的链接,以及一个关于如何用 QProcess 实现相同的链接吗? (我也会查看诺基亚文档)谢谢
    • 这是一个相关问题:stackoverflow.com/questions/21514446/…
    • @Michelle “链接”只是 Qt 源代码的 grep。 fork 在测试用例中的任何地方都没有出现(在 perl 测试执行程序代码之外)。它没有经过测试,因此期望它能够可靠地工作几乎是不可能的。
    • @Michelle 您无法使用QProcess 实现“相同”,因为QProcess 启动的任何内容都不会与您的进程共享内存或其他资源。你唯一能做的就是在命令行上传递数据,使用QSharedMemory,或者使用管道(又名QLocalSocket)。您几乎需要像在 Windows 上一样构建事物 - 忘记 fork
    • 你说得对——我重新编写了我的代码,所以我的 main 立即分叉,然后让 Qt 来做这件事(初始化、设置信号等),现在它很高兴。 Qt 只是不喜欢分叉...
    猜你喜欢
    • 2011-12-22
    • 1970-01-01
    • 1970-01-01
    • 2016-05-25
    • 2019-08-29
    • 1970-01-01
    • 1970-01-01
    • 2010-09-26
    相关资源
    最近更新 更多