[英]CPU usage/ speed tradeoff when reading from a named pipe in python
[英]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.