【问题标题】:Python subprocess IOError: [Errno 4]Python 子进程 IOError:[Errno 4]
【发布时间】:2015-05-11 05:28:26
【问题描述】:

我正在实现 python 程序,它返回子进程的结果(如“ls”)。 子进程有订阅连续输出的特性,更具体的说,订阅两个结果,两个结果之间有一个短期(约1秒)。

所以,我设计了一个如下所示的类来订阅该输出。

class Subscribe:
    def __init__(self, sec):
        self.m_sec = sec
    def subscribeResult(self, p):
        self.m_timeout = False
        signal.signal(signal.SIGALRM, self.handleTimeout)
        signal.alarm(self.m_sec)
        returnValue = ""

        try:
            with p.stdout:
                for line in iter(p.stdout.readline, b''):
                    if self.m_timeout:
                        signal.alarm(0)
                        p.kill()
                        return "timeout"
                    returnValue += line
            p.stdout.close()
            p.wait()
        exception Exception, inst:
            print inst
            signal.alarm(0)
            p.kill()
            return "except"

        signal.alarm(0)
        rv = returnValue.strip()
        if rv == "":
            return "null"
        return rv
    def handleTimeout(self, signum, frame):
        self.m_timeout = True

它运行良好,但很少引发如下所示的 IO 异常。 : IOError: [Errno 4] 系统调用中断

代码有弱点吗? 请告诉我如何清除异常

【问题讨论】:

  • 您需要发布整个回溯消息,以便我们可以看到这个异常来自哪里。

标签: python subprocess ioerror


【解决方案1】:

在大多数情况下,只需重试您正在执行的任何系统调用,例如,subprocess 模块有一个辅助函数来忽略 EINTR 错误:

def _eintr_retry_call(func, *args):
    while True:
        try:
            return func(*args)
        except (OSError, IOError) as e:
            if e.errno == errno.EINTR:
                continue
            raise

用法:

readline = _eintr_retry_call(p.stdout.readline)

在 Python 3.5 中,它会自动发生。见PEP 0475 -- Retry system calls failing with EINTR

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多