Popen.communicate()抛出OSError:“[Errno 10]没有子进程”

时间:2009-06-17 18:40:15

标签: python linux

我正在尝试使用子进程模块启动子进程并从Python获取其输出:

#!/usr/bin/python2.4
import subprocess

p = subprocess.Popen(['ls', '-l', '/etc'],
                   stdout=subprocess.PIPE,
                   stderr=subprocess.PIPE)
out, err = p.communicate()

然而,我经历了一些诡异:有时,p.communicate()会抛出

OSError: [Errno 10] No child processes

什么可能导致此异常?这里是否有任何非决定论或竞争条件可能导致邋??

4 个答案:

答案 0 :(得分:6)

您是否在脚本中拦截了SIGCHLD?如果你是那么Popen将无法按预期运行,因为它依赖于它自己的处理程序来处理该信号。

您可以通过注释掉Popen调用然后运行:

来检查SIGCHLD处理程序
strace python <your_script.py> | grep SIGCHLD

如果你看到类似的东西:

rt_sigaction(SIGCHLD, ...)
那么,你有麻烦了。您需要在调用Popen之前禁用处理程序,然后在完成通信后重置它(这可能会引入竞争条件,所以要小心)。

signal.signal(SIGCHLD, handler)
...
signal.signal(SIGCHLD, signal.SIG_DFL)
'''
now you can go wild with Popen. 
WARNING!!! during this time no signals will be delivered to handler
'''
...
signal.signal(SIGCHLD, handler)

据报道有一个python错误,据我所知尚未解决:

http://bugs.python.org/issue9127

希望有所帮助。

答案 1 :(得分:3)

您可能遇到了此处提到的错误:http://bugs.python.org/issue1731717

答案 2 :(得分:0)

我无法在我的Python(2.4.6-1ubuntu3)上重现这一点。你是如何运行脚本的?这种情况多久发生一次?

答案 3 :(得分:0)

我使用我在主目录中内置的Python 2.6.4遇到了这个问题(因为我不想在机器上升级“内置”Python)。

我通过将subprocess.Popen()替换为(已弃用的)os.popen3()来处理它。