繁体   English   中英

从破损的管道读取时,管道Python脚本占用100%的CPU

[英]Piped Python script takes 100% of CPU when reading from broken pipe

我在Ubuntu Linux机器上运行了两个Python脚本。 第一个将其所有输出发送到stdout,第二个从stdin读取。 它们通过简单的管道连接,即:

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

step2的作用是它在无限循环中读取输入行并处理它们:

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

Step1不时崩溃。 当发生这种情况时(不确定是否总是,但至少在几次)是不是崩溃/停止,step2变得疯狂并开始占用100%的CPU,直到我手动杀死它。

为什么会发生这种情况?如何使step2更加强大,以便在管道损坏时停止?

谢谢!

当step1死掉时,你有一个while循环,尝试一个会抛出异常的语句。 因此,您将不断尝试并使用100%的CPU失败,因为readline在抛出异常时不会阻塞。

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

当管道为空时你可能想要一个睡眠操作符,而当管道死亡时你可能想要一个退出,但是在每种情况下我抛出哪个消息作为练习让你确定。 在这种情况下,睡眠操作员不是必需的,但它可以避免在无用的工作中遇到高CPU使用率的其他情况。

其他人已经解释了为什么在某些情况下你会陷入无休止的循环。

在第二个(阅读)脚本中,您可以使用成语:

for line in sys.stdin:
    process(line)

这样你就不会陷入无尽的循环。 此外,你实际上没有显示你试图在第二个脚本中捕获哪个异常,但我想你会不时遇到一个“破管”错误,你可以并且应该按照这里描述的那样捕获: 如何处理python中的破管(SIGPIPE)?

整个方案可能如下所示:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM