如何在使用循环run_in_executor时使用CTRL-C优雅地结束异步程序



下面的代码需要按下3次CTRL-C才能结束,我如何才能让它只以一次结束?(所以它在Docker中运行得很好(

import asyncio
import time

def sleep_blocking():
print("Sleep blocking")
time.sleep(1000)

async def main():
loop = asyncio.get_event_loop()
await loop.run_in_executor(None, sleep_blocking)

try:
asyncio.run(main())
except KeyboardInterrupt:
print("Nicely shutting down ...")

我读过很多与异步相关的问题和答案,但还没弄清楚这一个。第一个CTRL-C什么也不做;很好地关闭了"然后挂起。第三个CTRL-C打印了一个丑陋的错误。

我使用的是Python 3.9.10和Linux。

(编辑:每个评论更新代码@mkrieger1(

从这里我们知道,实际上不可能杀死线程执行器中运行的任务。如果我用ProcessPoolExecutor替换默认的线程执行器,我就会得到您想要的行为。这是代码:

import concurrent.futures
import asyncio
import time

def sleep_blocking():
print("Sleep blocking")
time.sleep(1000)

async def main():
loop = asyncio.get_event_loop()
x = concurrent.futures.ProcessPoolExecutor()
await loop.run_in_executor(x, sleep_blocking)

try:
asyncio.run(main())
except KeyboardInterrupt:
print("Nicely shutting down ...")

结果是:

$ python asynctest.py
Sleep blocking
^CNicely shutting down ...

从Python程序中立即无条件退出的方法是调用os_exit((。如果你的后台线程正在做一些重要的事情,这可能是不明智的。但是,以下程序会按照您的要求执行(python 3.10,Windows10(:

import asyncio
import time
import os

def sleep_blocking():
print("Sleep blocking")
time.sleep(1000)

async def main():
loop = asyncio.get_event_loop()
loop.run_until_complete(loop.run_in_executor(None, sleep_blocking))

try:
asyncio.run(main())
except KeyboardInterrupt:
print("Nicely shutting down ...")
os._exit(42)

相关内容

  • 没有找到相关文章

最新更新