Linux 终止子进程
我很好奇,为什么下面的代码会冻结。当我杀死python3解释器时,“cat”进程仍然是一个僵尸。我预计子进程将在主进程完成之前终止 当我将SIGTERM手动发送到Linux 终止子进程,linux,python-3.x,pyqt4,subprocess,kill-process,Linux,Python 3.x,Pyqt4,Subprocess,Kill Process,我很好奇,为什么下面的代码会冻结。当我杀死python3解释器时,“cat”进程仍然是一个僵尸。我预计子进程将在主进程完成之前终止 当我将SIGTERM手动发送到cat/dev/zero时,该过程已正确完成(几乎立即完成) 我用不同的方法解决了这个问题,结果如下: 我必须用shell=False调用subprocess.Popen,因为否则它会创建2个进程(shell和进程),并且_cmd.kill()会向shell发送信号,而“进程”仍然是一个僵尸,正如您自己指出的,僵尸的原因是信号被shel
cat/dev/zero
时,该过程已正确完成(几乎立即完成)
我用不同的方法解决了这个问题,结果如下:
我必须用shell=False调用subprocess.Popen,因为否则它会创建2个进程(shell和进程),并且_cmd.kill()会向shell发送信号,而“进程”仍然是一个僵尸,正如您自己指出的,僵尸的原因是信号被shell捕获,不会影响由它创建的进程。但是,有一种方法可以杀死shell及其创建的所有进程;您必须使用进程组功能。看看我说过的,如果你能在没有
shell=True的情况下管理,那总是更好的-看看我的答案。我有一种模糊的感觉,你需要在杀死它之后调用p.wait()
,来清理僵尸进程,但我不记得为什么了。太好了,它可以工作了!我将在周一上班时在受影响的机器上测试它。只需在run()函数的末尾添加self.quit()和在stop()函数的末尾添加self。谢谢你,汤玛西,不客气-很高兴听到我的直觉在现实中有一些根据。
#!/usr/bin/env python3
import subprocess
import re
import os
import sys
import time
from PyQt4 import QtCore
class Command(QtCore.QThread):
# stateChanged = QtCore.pyqtSignal([bool])
def __init__(self):
QtCore.QThread.__init__(self)
self.__runned = False
self.__cmd = None
print("initialize")
def run(self):
self.__runned = True
self.__cmd = subprocess.Popen(["cat /dev/zero"], shell=True, stdout=subprocess.PIPE)
try:
while self.__runned:
print("reading via pipe")
buf = self.__cmd.stdout.readline()
print("Buffer:{}".format(buf))
except:
logging.warning("Can't read from subprocess (cat /dev/zero) via pipe")
finally:
print("terminating")
self.__cmd.terminate()
self.__cmd.kill()
def stop(self):
print("Command::stop stopping")
self.__runned = False
if self.__cmd:
self.__cmd.terminate()
self.__cmd.kill()
print("Command::stop stopped")
def exitApp():
command.stop()
time.sleep(1)
sys.exit(0)
if __name__ == "__main__":
app = QtCore.QCoreApplication(sys.argv)
command = Command()
# command.daemon = True
command.start()
timer = QtCore.QTimer()
QtCore.QObject.connect(timer, QtCore.SIGNAL("timeout()"), exitApp)
timer.start(2 * 1000)
sys.exit(app.exec_())