什么是处理(在python)的正确方法IO错误:[错误4]中断的系统调用,通过multiproces

2019-08-05 10:01发布

当我使用multiprocessing.Queue.get我有时会因EINTR异常。

我肯定知道,有时候,这是没有很好的理由(我开的TMUX buffr另一个窗格中),并且在这种情况下,我想继续工作,然后重试操作。

我可以想像,在其他一些情况下该错误是由于一个很好的理由,我应该停止运行或修复一些错误。

我怎样才能区分这两个?

提前致谢

Answer 1:

所述EINTR当应用程序接收的信号,同时等待其他输入可以从许多系统中返回的错误呼叫。 通常,这些信号可以是相当良性的,已经被Python处理,但潜在的系统调用最终还是被打断。 在做C / C ++编码,这是一个原因,你不能完全依赖像功能sleep() 在Python库有时在内部处理此错误代码,但很明显,在这种情况下,他们没有。

你可能会有兴趣看这个线程 ,其中讨论了这个问题。

以一般的方法EINTR是简单地处理错误,并再次重试操作-这应该是做的一个安全的事情get()在队列方法。 像这样,可以使用,传递队列作为一个参数和更换使用的get()在队列方法:

import errno

def my_queue_get(queue, block=True, timeout=None):
    while True:
        try:
            return queue.get(block, timeout)
        except IOError, e:
            if e.errno != errno.EINTR:
                raise

# Now replace instances of queue.get() with my_queue_get(queue), with other
# parameters passed as usual.

通常,你不应该需要担心EINTR在Python程序,除非你知道你在等待一个特定的信号(例如SIGHUP )以及您所安装的设置标志和依靠的主体的信号处理程序代码拿起标志。 在这种情况下,你可能需要打破你的循环,并检查信号标志,如果你收到EINTR

但是,如果你不使用任何信号处理,那么你应该能够忽略EINTR和重复你的操作-如果Python本身需要用它做什么,应在信号处理程序已经处理了它的信号。



Answer 2:

老问题,现代化的解决方案:像Python 3.5的,精彩的PEP 475 -重试系统调用与EINTR失败已经实施和解决问题为您服务。 以下是摘要:

在标准库中提供的系统调用的包装应当他们失败,并自动重试EINTR ,从这样的负担减轻应用程序代码。

通过系统调用,我们的意思是有关的其他系统资源的I / O或处理标准C库暴露的功能。

基本上,系统将捕获并重新为你的代码与失败的EINTR ,所以你不必再处理它。 如果你的目标较旧版本中, while True循环仍然是要走的路。 但是请注意,如果你正在使用Python 3.3或3.4,您可以搭乘专用例外InterruptedError ,而不是抓住IOError和检查EINTR



文章来源: What is the proper way to handle (in python) IOError: [Errno 4] Interrupted system call, raised by multiprocessing.Queue.get