从破管道读取时管道Python脚本需要100%的CPU(Piped Python script ta

2019-09-22 06:33发布

我有一个Ubuntu Linux机器上运行两个Python脚本。 所述第一一个发送其所有输出到标准输出,第二个从stdin读取。 他们是由一个简单的配管连接,即是这样的:

./step1.py <some_args> | ./step2.py <some_other_args>

什么第二步所做的是它的内容在一个无限循环的输入线并进行处理:

while True:
    try:
        l = sys.stdin.readline()
        # processing here

第一步崩溃不时。 当发生这种情况(不知道是否总是但是至少在多个场合)是一个,而不是崩溃/停止,第二步就会发疯,并开始采取100%的CPU,直到我手动杀死它。

为什么会出现这种情况,我怎么能做出第二步更健壮,使其停止时管道损坏?

谢谢!

Answer 1:

其他已经解释了为什么你在某些情况下,一个无限循环结束。

在第二(读取)脚本,可以用成语:

for line in sys.stdin:
    process(line)

这样,你就不会在死循环中结束。 此外,你实际上并没有显示出您尝试在第二个脚本来捕获该异常,但我想从你不时会经历一个“破管道”的错误,你可以和应该抓住如下所述: 如何处理断管(SIGPIPE)在python?

然后,整个计划看起来是这样的:

try:
    for line in sys.stdin:
        process(line)
except IOError, e:
    if e.errno == errno.EPIPE:
        # EPIPE error
    else:
        # Other error


Answer 2:

当第一步死了,你有上会抛出异常的语句尝试while循环。 因此,你会不断地尝试和使用100%的CPU当它抛出一个异常的readline不会阻止失败。

无论是时间延迟添加到与阅读time.sleep ,或者甚至更好,注意错误的ReadLine被抛钓时引发第一步时停止特定的错误和退出程序,而不是试图从死管阅读。

你可能想睡眠操作员何时管道是空和退出时的管死了,但它引发异常,我留在每种情况下,什么样的信息作为练习你来决定。 睡眠经营者不得在这种情况下必要的,但它会避免其他情况下,您可以打到无用功CPU使用率过高。



文章来源: Piped Python script takes 100% of CPU when reading from broken pipe