【问题标题】:How to know asynchronously detect if async subprocess has terminated如何知道异步检测异步子进程是否已终止
【发布时间】:2020-06-03 05:35:38
【问题描述】:

我正在尝试使用asyncio.create_subprocess_exec 来启动一个长时间运行的进程(一种守护进程)。

但是我不能等待它知道进程是否成功/失败。我必须异步检测进程是否失败并在那时处理它。否则,我让子进程守护程序运行并通过 TCP/IP 与其通信。

我可以在 SIGCHLD 上使用信号处理程序,但是 asyncio 是否具有一些内置功能来为子进程创建处理程序?

import asyncio
import subprocess

async def main():
    command = ["./some-long-running-daemon"]
    process = await asyncio.create_subprocess_exec(*command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    print(process.returncode) # this is None

if __name__ == "__main__":
    asyncio.run(main())

我发现 async create subprocess 在SIGCHILD 上的表现似乎并不好(处理程序甚至没有运行)。而subprocess.Popen 可以。 Popen 也有一个 poll() 方法,而异步子进程没有。看来Popen 是正确的使用方法。

【问题讨论】:

  • 由于您使用管道,您将不得不执行类似await process.communicate(b'some input') 的操作。如果你不这样做,你可能会死锁你的子进程。但是一旦返回,您就知道该过程已完成。

标签: python python-asyncio


【解决方案1】:

如果您乐于编写信号处理程序,为什么不创建一个等待进程完成的新任务呢?然后你可以让你的主要任务继续做它想做的任何事情。

import asyncio
import subprocess

async def child_done(proc):
    stdout, stderr = await proc.communicate()
    print('child done. output:', stdout, '-- return code was:', proc.returncode)

async def main():
    proc = await asyncio.create_subprocess_exec('ls', stdout=subprocess.PIPE)
    asyncio.create_task(child_done(proc))
    # do other stuff
    await asyncio.sleep(1)
    print('main done')

if __name__ == '__main__':
    asyncio.run(main())

这会给你这样的输出:

child done. output: b'asyncio-test.py\n' -- return code was: 0
main done

【讨论】:

    猜你喜欢
    • 2016-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-20
    • 1970-01-01
    相关资源
    最近更新 更多