我在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更加健壮,以便在管道损坏时停止?
谢谢!
答案 0 :(得分:3)
当step1死亡时,你有一个while循环,尝试一个会抛出异常的语句。因此,你会不断尝试使用100%的CPU,因为readline在抛出异常时不会阻塞。
使用time.sleep
添加时间延迟,或者更好的是,注意readline抛出的错误并捕获step1停止并退出程序而不是尝试读取时抛出的特定错误一根死管。
当管道为空时你可能想要一个睡眠操作符,而当管道死亡时你可能想要一个退出,但是在每种情况下我会抛出哪个消息作为练习让你确定。在这种情况下,睡眠操作员不是必需的,但它可以避免在无用的工作中遇到高CPU使用率的其他情况。
答案 1 :(得分:3)
其他人已经解释了为什么在某些情况下你会陷入无休止的循环。
在第二个(阅读)脚本中,您可以使用成语:
for line in sys.stdin:
process(line)
这样你就不会陷入无休止的循环。此外,您实际上没有显示您尝试在第二个脚本中捕获的异常,但我想您会不时遇到“管道损坏”错误,您可以 捕获如下所述:How to handle a broken pipe (SIGPIPE) in python?
整个方案可能如下所示:
try:
for line in sys.stdin:
process(line)
except IOError, e:
if e.errno == errno.EPIPE:
# EPIPE error
else:
# Other error