为什么subprocess.Popen.wait使用busy循环?

时间:2014-11-05 12:53:09

标签: python subprocess

据记载here,Popen.wait确实忙着等待。我相信一些操作系统有系统调用来等待进程结束,而不需要繁忙的循环。为什么不使用这种机制?

2 个答案:

答案 0 :(得分:1)

from subprocess import Popen, PIPE

handle = Popen('ping -n 100 www.google.se', shell=True, stdout=PIPE)
while handle.poll() is None: # <-- Equivilant of .wait()
    print(handle.stdout.readline())

wait是.poll()的一个简写函数,它基本上做同样的事情,除非你在一个保持循环中手动使用.poll(),你可以在这个过程中计算东西。

通常它用于转储stdout / stderr的东西(如果你不能阻止应用程序或引发异常)。

使用shell也有风险,但在学习和测试时可以省去很多麻烦。

真正完全不阻止任何事情的唯一方法(即使是上面的方法&#34;块&#34;下一行的代码)是utelize线程:

from threading import *
from subprocess import Popen, PIPE

class worker(Thread):
    def __init__(self, command):
        Thread.__init__(self)
        self.handle = Popen(command, shell=True, stdout=PIPE)
        self.start()

    def run(self):
        while self.handle.poll() is None:
            print('Thread-output',self.handle.stdout.readline()) # Note, you might loose the last output.. just saying.

print('I\'m a panda..')
worker('ping -n 100 www.google.se')
print('And i work really well simultaneously...')

调试时的有用提示:

from subprocess import Popen, PIPE, STDOUT
handle = Popen('ping -n 100 www.google.se', shell=True, stdout=PIPE, stderr=PIPE)
# You need to flush the output buffers:
handle.stderr.readline()
handle.stdout.readline()
# or
handle = Popen('ping -n 100 www.google.se', shell=True, stdout=PIPE, stderr=STDOUT)
handle.stdout.readline() # Does both stdout+stderr at the same time, saves you a line.

# and always close your open filehandles.
handle.stdout.close()
handle.stderr.close() # If you've separated both.

关于您的操作系统问题

我认为你可能指的是系统服务或守护进程? 这些类型的&#34;流程&#34;如您所述,它们被指定为阻止或非阻止(这是您正在寻找的术语)。这些进程的每个init-script的开发人员确定进程是否应该阻塞,直到完成(或达到超时),或者进程是否应分叉到后台。

可能阻塞的东西是OpenLDAP或内部邮件传输器,而其他进程(如OpenVPN或Apache)可能会分叉到后台,系统可以继续启动它的启动顺序。

答案 1 :(得分:-1)

我并非完全正面。我不认为有一种方法可以让waitpid或同等产品具有完全无创的同步超时。另外,我认为一些Unices对于waitpid如何使用信号有不同的规则。

评论说他们从Thread.wait窃取了循环,而且threading.py中的评论表明它用于响应。