我编写了一个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不喜欢福克。 (参见另一个StackExchane questoin)。我不得不把我的叉子移到最高级别(在Qt做任何事情之前),然后Qt不会在退出时挂起。
答案 0 :(得分:2)
处理状态代码
以下是 s , stat 和状态输出说明符(标题“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(等待通道)”显示阻塞的内核函数(= ~syscall)。
另见