【发布时间】:2018-11-11 18:31:49
【问题描述】:
在 Ubuntu 14.04 上的 python 2.7 中,我启动了一个这样的进程:
bag_process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
for i in range(5):
print "Countdown: {}".format(5 - i - 1)
time.sleep(1)
print "Sending SIGINT to PID {}".format(bag_process.pid)
bag_process.send_signal(signal.SIGINT)
(bag_out, bag_err) = bag_process.communicate()
程序挂在communicate() 行。当我打开另一个终端时,我运行ps -ef | grep ### 来查找子进程的pid,我看到它是<defunct>。
为什么子程序失效,而父程序挂在communicate()?如果子进程在收到SIGINT 后真正退出,我怎样才能让父程序可靠地处理它而不挂起?
【问题讨论】:
-
它已经失效了,因为它已经退出了,但是父进程还没有读出退出代码,见en.wikipedia.org/wiki/Zombie_process。也许 SIGINT 对子进程所附加的管道做了一些事情,比如发出重新打开文件句柄的信号?如果没有流程本身,这不是我们可以更具体的。
-
您的死程序是否有可能启动仍然活着的子程序(它们从未关闭它们继承的 stdout 和 stderr),或者通过套接字将其 stdout 或 stderr FD 传递给仍然打开它们的其他程序?这两种情况都可以为
communicate()无法完成和返回提供可靠的解释。 -
@MartijnPieters 谢谢,但我相信
communicate()方法使用wait()来获取退出状态,即使communicate()本身不返回退出状态。 github.com/python/cpython/blob/2.7/Lib/subprocess.py#L452 -
@CharlesDuffy 好主意,但没有骰子...我为已失效的 pid 进行了搜索,它没有被列为任何其他 PID 的 PPID。
-
@EdwardNedHarvey:是的,但它永远不会到达那里,因为管道被某处阻塞。
标签: python python-2.7 subprocess defunct