是否有一种非阻塞方式来检查 asyncio 子进程是否还活着?

maj*_*588 4 python subprocess python-3.x python-asyncio

当使用asyncio.create_subprocess_exec一个asyncio.subprocess.process被返回。该文档表明不存在pollis_alive类型方法。它似乎waitcommunicate提供了查看进程是否正在运行的唯一方法,但它们正在阻止调用,并且通信的 asyncio 版本没有超时选项。

有没有一种好方法来检查asyncio进程是否以非阻塞方式活着?

我能想到的最好的is_alive样式函数是:

import asyncio

async def is_alive(proc):
    try:
        await asyncio.wait_for(proc.wait(), 0.001)
    except asyncio.TimeoutError:
        return True
    else:
        return False
Run Code Online (Sandbox Code Playgroud)

虚拟用例:

async def foo():
    proc = await asyncio.create_subprocess_exec('sleep', '5')
    i = 0
    res = True
    while res:
        res = await is_alive(proc)
        print(f"[{i}] is_alive: {res}")
        # ... do foo stuff while we wait ...
        await asyncio.sleep(1)
        i += 1

loop = asyncio.get_event_loop()
loop.run_until_complete(foo())
Run Code Online (Sandbox Code Playgroud)

输出:

[0] is_alive: True
[1] is_alive: True
[2] is_alive: True
[3] is_alive: True
[4] is_alive: True
[5] is_alive: False
Run Code Online (Sandbox Code Playgroud)

Hac*_*ck5 5

您应该检查.returncode属性(https://docs.python.org/3/library/asyncio-subprocess.html#asyncio.asyncio.subprocess.Process.returncode),None如果进程正在运行(注意0表明它已退出,所以简单的真实性检查将不起作用)。

如果您可以创建一个未来,启动一个等待.wait()然后取消后台任务的任务,您应该避免轮询。