我正在尝试使用asyncio.subprocess添加超时功能。我启动一个子流程来执行一些命令,如果花费太长时间,我想使其失败并终止该流程。在官方文档方面,我使用asyncio.wait_for来实现它。这是示例代码:
async def ping():
cmd = 'ping localhost'
proc = await asyncio.create_subprocess_shell(cmd,
stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE)
try:
stdout, _ = await asyncio.wait_for(proc.communicate(), 3)
except asyncio.TimeoutError:
print('Timeout')
return 'Cancelled'
finally:
proc.terminate()
return stdout.decode().strip()
def main():
loop = asyncio.get_event_loop() #on windows, use another event loop to support subprocess
task = asyncio.ensure_future(ping())
result = loop.run_until_complete(task)
print(f'the result is {result}')
loop.close()
if __name__ == '__main__':
main()
无论结果成功还是超时,我总是可以得到结果。但是在运行控制台时出现错误。
在macOS上,它喜欢:
Exception ignored when trying to write to the signal wakeup fd:
BrokenPipeError: [Errno 32] Broken pipe
在Windows上,它像:事件循环已关闭,任务已销毁,但仍在处理中。抱歉,我记不清楚了,我正在Mac上进行测试。
我检查了一些答案,并参考文档wait_for引发TimeoutError并取消包装的协程。但是因为任务没有立即取消,所以它将在下一个循环中被取消。但是到那时,事件循环已在我的程序中关闭。
所以我的问题是处理此类问题的正确方法是什么。我应该关心这个错误吗?因为我总是可以得到想要的结果。