python-3.x - ValueError ("I/O operation on closed pipe") 将 asyncio 与子进程一起使用时

标签 python-3.x python-asyncio

我的代码的简化版本如下所示:

def run_async(spawn_coro, timeout):
    async def _read_print_line(process):
        line = await process.stdout.readline()
        line = line.decode('utf-8', errors='replace')
        sys.stdout.write(line)

    process = await spawn_coro
    try:
        while not process.stdout.at_eof():
            # We should cancel if no output has been received for a certain timeout
            await asyncio.wait_for(_read_print_line(process), timeout)
    except asyncio.TimeoutError:
        print('Timed out executing "{}".  No output received for {} seconds'.format(cmd, timeout))
        process.kill()
    await process.wait()

processes = [asyncio.create_subprocess_shell(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) for cmd in cmds]

loop = asyncio.ProactorEventLoop()   # This is windows
asyncio.set_event_loop(loop)
all_jobs = asyncio.gather(
    *(run_async(process, timeout) for process in processes)
)
loop.run_until_complete(all_jobs)
loop.close()

当进程退出时,我得到一堆这样的错误输出:

Exception ignored in: <function _ProactorBasePipeTransport.__del__ at 0x000001CD9B582AF8>
Traceback (most recent call last):
  File "C:\Users\divis\AppData\Local\Programs\Python\Python37\lib\asyncio\proactor_events.py", line 93, in __del__
    warnings.warn(f"unclosed transport {self!r}", ResourceWarning,
  File "C:\Users\divis\AppData\Local\Programs\Python\Python37\lib\asyncio\proactor_events.py", line 57, in __repr__
    info.append(f'fd={self._sock.fileno()}')
  File "C:\Users\divis\AppData\Local\Programs\Python\Python37\lib\asyncio\windows_utils.py", line 102, in fileno
    raise ValueError("I/O operation on closed pipe")
ValueError: I/O operation on closed pipe
Exception ignored in: <function BaseSubprocessTransport.__del__ at 0x000001CD9B571DC8>
Traceback (most recent call last):
    warnings.warn(f"unclosed transport {self!r}", ResourceWarning,
  File "C:\Users\divis\AppData\Local\Programs\Python\Python37\lib\asyncio\base_subprocess.py", line 78, in __repr__
    info.append(f'stdout={stdout.pipe}')
  File "C:\Users\divis\AppData\Local\Programs\Python\Python37\lib\asyncio\proactor_events.py", line 57, in __repr__
    info.append(f'fd={self._sock.fileno()}')
  File "C:\Users\divis\AppData\Local\Programs\Python\Python37\lib\asyncio\windows_utils.py", line 102, in fileno
    raise ValueError("I/O operation on closed pipe")
ValueError: I/O operation on closed pipe

如果我删除 loop.close(),则进程不会出现错误而是挂起。在关闭循环之前,我正在正确地等待每个子进程,所以我不确定这里的问题是什么。

最佳答案

我知道这个问题不久前有人问过,但我遇到了同样的问题,我能够这样解决它:

try:
    process = asyncio.create_subprocess_exec(cmd)
    ...
    await process.wait()
finally:
    process._transport.close()

查看代码,这似乎关闭了子进程的管道文件句柄。我不知道为什么 asyncio 不将其作为返回的 Process 对象的一部分公开。

关于python-3.x - ValueError ("I/O operation on closed pipe") 将 asyncio 与子进程一起使用时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63905578/

相关文章:

python迭代循环遍历数据框的列

python - 在 for 循环中用 “key: value” 对打印字典

python - 异步: terminating all tasks when one of them throws exception

python - 如何将协程添加到正在运行的事件循环中?

python - 多个 aiohttp Application() 在同一个进程中运行?

python - 为什么我不能在协程调用的协程中发送 websocket?

python - 编写用于 AWS Lambda 的异步代码的正确方法是什么?

python - 使用 Python 3 计算 gf(2^8) 中的乘法逆的纯 Python 方法

python - TensorFlow 2.0 [条件 x == y 不满足元素方向 :]

python - Django2.1 : Queryset ModelChoice in a ModelForm then save two forms