python - 异步子进程上下文管理器
问题描述
我想要一个异步上下文管理器,以确保托管进程在通过正常或强制终止退出之前完成,而不管取消如何。例如,
async def sleep(duration):
proc = await asyncio.create_subprocess_exec('sleep', str(duration))
async with manage_process(proc):
...
# proc either finished, was terminated, or killed.
到目前为止,我得到的最好的结果是:
@asynccontextmanager
async def manage_process(
proc: asyncio.subprocess.Process,
timeout: Optional[float] = None,
) -> AsyncIterator[asyncio.subprocess.Process]:
if timeout is None:
timeout = 1.0
try:
yield proc
finally:
try:
proc.terminate()
except ProcessLookupError:
pass
else:
try:
await asyncio.shield(asyncio.wait_for(proc.wait(), timeout))
except asyncio.CancelledError:
is_done = False
is_cancelled = True
except asyncio.TimeoutError:
is_done = False
is_cancelled = False
else:
is_done = True
is_cancelled = False
if not is_done:
try:
proc.kill()
except ProcessLookupError:
pass
else:
await asyncio.shield(proc.wait())
if is_cancelled:
raise asyncio.CancelledError()
我不确定我是否正确处理了取消。我没用过asyncio.shield()
,我不确定我做得对。
解决方案
推荐阅读
- excel - 在 VBA 中复制整行时是否可以排除某些列?
- flutter - listview onTap 动画所有按钮问题:Flutter
- c# - 在 .Net Core (c#) 应用程序中设置外部依赖项
- django - 迁移后django静态文件404错误
- vue.js - 了解 NUXT 中的上下文和应用程序方法
- python - 在行级别向熊猫数据框添加列表元素
- laravel - 在 laravel 分页和 firebase-jwt-token 中发送 Token 和页面
- python - PythonAnywhere cx_Oracle DPI-1047:找不到 64 位 Oracle 客户端库:“libclntsh.so:
- django - Django为什么只有基于字符串的字段不能有null = true?
- python - 如何在 selenium python 中更改集成测试的优先级