我正在尝试使用子进程模块启动子进程并从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
什么可能导致此异常?这里是否有任何非决定论或竞争条件可能导致邋??
答案 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()
来处理它。