QThreaded C++ 守护程序未正确关闭

Posted

技术标签:

【中文标题】QThreaded C++ 守护程序未正确关闭【英文标题】:QThreaded C++ daemon does not shutdown properly 【发布时间】:2014-02-24 04:40:18 【问题描述】:

我编写了一个 Qt5/C++ 程序,它在后台分叉和运行,响应信号停止并正常关闭。一切听起来都很棒,但是当我“ps ax | grep myprog”时,我看到一堆我的程序仍在运行;例如:

29244 ?        Ss   149:47 /usr/local/myprog/myprog -q
30913 ?        Ss     8:37 /usr/local/myprog/myprog -q
32484 ?        Ss     0:11 /usr/local/myprog/myprog -q

如果我在前台运行程序,则该进程不会在进程列表中徘徊 - 它会按预期消亡。这只发生在后台时。为什么?


更新:我发现我的程序处于 futex_wait_queue_me 状态(queue_me 并等待唤醒、超时或信号)。我确实有 3 个单独的线程 - 这可能是相关的。所以我在其中一个等待进程中附加了一个调试器,发现了这个:

(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) 

更新:

我注释掉了我的2个线程,所以现在只运行主线程,问题还是一样。

有没有一种特殊的方法可以让后台进程退出?为什么主线程不会关闭?


更新: 已解决 - Qt 不喜欢 Fork。 (参见另一个 StackExchane 问题)。我必须将我的 fork 移动到***别(在 Qt 执行任何操作之前),然后 Qt 不会在退出时挂起。

【问题讨论】:

请提供您的代码详细信息。 这些不是僵尸。僵尸会有一个Z,而你有一个Ss。给它们附加一个调试器,看看它们在等待什么。 你需要展示你的源代码。 【参考方案1】: http://man7.org/linux/man-pages/man1/ps.1.html#PROCESS_STATE%20CODES

过程状态代码

以下是 sstatstate 输出说明符(标题“STAT”或“S”)将显示的不同值描述进程的状态:

  D    uninterruptible sleep (usually IO)
  R    running or runnable (on run queue)
  S    interruptible sleep (waiting for an event to complete)
  T    stopped, either by a job control signal or because it is being traced.
  W    paging (not valid since the 2.6.xx kernel)
  X    dead (should never be seen)
  Z    defunct ("zombie") process, terminated but not reaped by its parent.

对于 BSD 格式,当使用 stat 关键字时,可能会显示额外的字符:

  <    high-priority (not nice to other users)
  N    low-priority (nice to other users)
  L    has pages locked into memory (for real-time and custom IO)
  s    is a session leader
  l    is multi-threaded (using CLONE_THREAD, like NPTL pthreads do)
  +    is in the foreground process group.

所以您的进程都处于“S:可中断睡眠”中。也就是说,它们都在等待阻塞系统调用。

您可能会通过此命令更好地提示您的程序正在等待什么:

$ ps -o pid,stat,wchan `pidof zsh`
  PID STAT WCHAN
 4490 Ss   rt_sigsuspend
 4814 Ss   rt_sigsuspend
 4861 Ss   rt_sigsuspend
 4894 Ss+  n_tty_read
 5744 Ss+  n_tty_read
...

"wchan (waiting channel)" 显示了一个阻塞的内核函数(=~ syscall)。

另见

https://askubuntu.com/questions/19442/what-is-the-waiting-channel-of-a-process

【讨论】:

好的 - 我试过了,我看到 myprog 被列为“futex_wait_queue_me”。很难找到这意味着什么。我的应用程序中有 3 个线程 - 这是否意味着线程仍在运行? (我以为我都阻止了他们)

以上是关于QThreaded C++ 守护程序未正确关闭的主要内容,如果未能解决你的问题,请参考以下文章

[C++]-Linux中创建Daemon程序

c++ Qt用opencv运行代码[关闭]

Qt5、C++:未加载 QMYSQL 驱动程序

包含源中的 Qt 未定义参考

比较 GTK+、Qt 和 MATLAB 为 C++ 编写的科学程序开发 GUI [关闭]

Qt Mac - 关闭后应用程序未恢复