gpt4 book ai didi

Python:我是否需要在管道读取循环中捕获 EINTR

转载 作者:行者123 更新时间:2023-11-28 18:44:12 25 4
gpt4 key购买 nike

tl;博士

在 Python 中读取管道时,我是否应该处理 EINTR“系统调用中断”错误?如果是,我该如何测试此类代码?

描述

在下面的回溯中,self._dataq 是一个 multiprocessing.Queue(从技术上讲,我使用的是 billiard 库,但我认为它们基本上是相同的代码)。 Python 子进程偶尔会写入队列的另一端。我认为发生的事情是系统调用正在读取为队列提供数据的管道,并且信号到达了——可能是来自第二个 Ctrl+C 事件的 SIGINT(第一个 SIGINT 发生在你看到用户的 ^C 在日志输出的第二行,我的信号处理程序捕获了该 SIGINT,正如您在日志中的 WARNING 消息中看到的那样)。

[INFO     2014-03-05 14:16:06,000] Doing some work, la-dee-da
^C[WARNING 2014-03-05 14:16:07,344] Commencing shutdown. (Signal SIGINT, process 2469.). Press Ctrl+C again to exit immediately.
[DEBUG 2014-03-05 14:16:07,347] Terminating subprocess
Traceback (most recent call last):
[... a bunch of stuff omitted]
File "mycode.py", line 97, in __next__
result = self._dataq.get(timeout=0.1)
File "/usr/local/lib/python2.7/site-packages/billiard/queues.py", line 103, in get
if timeout < 0 or not self._poll(timeout):
IOError: [Errno 4] Interrupted system call

上面回溯中的语句 result = self._dataq.get(timeout=0.1) 位于循环的中间,如下所示。循环的主要目的是当 self.timedout() 开始返回 True 时,我可以放弃尝试从 self._dataq 读取.

import queue
while True:
try:
result = self._dataq.get(timeout=0.1)
except queue.Empty:
if self.timedout():
self.close()
raise MyTimedoutError()
else:
break

问题

如果我关于为什么发生 IOError 的理论是正确的,那么上面的 try...except block 应该捕获并忽略 IOError 由中断的系统调用引起。如果它是导致 EINTR 错误的信号,那么返回 Python 运行 except IOError: 语句的行为将允许运行 Python 级别的信号处理程序。

这样对吗?如果是这样,是否可以在我的代码中测试此更改?我不清楚如何编写不包含严重竞争条件的单元测试。

最佳答案

Python 3.5 通过将处理 EINTR 的责任放在 Python 运行时而不是应用程序代码上来解决这个问题。参见 PEP 475Python 3.5 Changelog .

关于Python:我是否需要在管道读取循环中捕获 EINTR,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22387024/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com