Python:我需要在管道读取循环中捕获EINTR吗 tl;博士
在Python中读取管道时,我应该处理EINTR“系统调用中断”错误吗?如果是,我如何测试这些代码 描述 在下面的回溯中,Python:我需要在管道读取循环中捕获EINTR吗 tl;博士,python,multiprocessing,pipe,system-calls,eintr,Python,Multiprocessing,Pipe,System Calls,Eintr,在Python中读取管道时,我应该处理EINTR“系统调用中断”错误吗?如果是,我如何测试这些代码 描述 在下面的回溯中,self.\u dataq是一个多处理.Queue(从技术上讲,我使用的是台球库,但我认为它们基本上是相同的代码)。Python子进程偶尔会写入队列的另一端。我认为发生的情况是,一个系统调用正在读取为队列提供信息的管道,并且一个信号到达了——可能是来自第二个Ctrl+C事件的SIGINT(第一个SIGINT出现在日志输出的第二行上,您看到用户的^C,我的信号处理程序捕捉到了该
self.\u dataq
是一个多处理.Queue
(从技术上讲,我使用的是台球库,但我认为它们基本上是相同的代码)。Python子进程偶尔会写入队列的另一端。我认为发生的情况是,一个系统调用正在读取为队列提供信息的管道,并且一个信号到达了——可能是来自第二个Ctrl+C事件的SIGINT(第一个SIGINT出现在日志输出的第二行上,您看到用户的^C
,我的信号处理程序捕捉到了该SIGINT,正如您在日志中的警告消息中所看到的)
问题:
如果我关于发生IOError
的原因的理论是正确的,那么上面的try
…except
块应该捕获并忽略由中断的系统调用引起的IOError
s。如果是导致EINTR错误的信号,而不仅仅是返回Python运行except IOError:
语句将允许运行Python级别的信号处理程序
这是正确的吗?如果是的话,有可能在我的代码中测试这个更改吗?我不清楚如何编写一个不包含严重争用条件的单元测试。我将在Python中将其称为bug。我找不到任何允许在EINTR
上引发IOError
的文档(尽管在其他I/O问题上引发是有意义的,这就是为什么您应该在忽略引发的异常之前检查errno属性的原因;请参阅),并且它没有直接映射到任何提供这种行为的低级C函数。在C级别处理所有EINTR
s的方法都有,但这并没有使其成为3.4(我怀疑它是否会成为2.x),所以这可能仍然是一个公平的游戏。Python 3.5通过将处理EINTR
的责任放在Python运行时而不是应用程序代码上来解决这个问题。请参阅和
[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