Python 异步任务取消
这是我创建的一个测试脚本,用于更好地理解任务取消-Python 异步任务取消,python,python-asyncio,cancellation,Python,Python Asyncio,Cancellation,这是我创建的一个测试脚本,用于更好地理解任务取消- 导入异步IO 随机输入 输入信号 导入回溯 异步def关闭(signame,循环): 打印(“关闭”) tasks=[asyncio.task.all_tasks()中任务对应的任务] 对于任务中的任务: task.cancel() 尝试: 等待任务 除asyncio.Cancelled错误外: 打印(“任务已取消:%s”,任务) loop.stop() 异步定义另一个() 等待异步睡眠(2) 异步定义某些其他进程(): 等待异步睡眠(5) 返
导入异步IO
随机输入
输入信号
导入回溯
异步def关闭(signame,循环):
打印(“关闭”)
tasks=[asyncio.task.all_tasks()中任务对应的任务]
对于任务中的任务:
task.cancel()
尝试:
等待任务
除asyncio.Cancelled错误外:
打印(“任务已取消:%s”,任务)
loop.stop()
异步定义另一个()
等待异步睡眠(2)
异步定义某些其他进程():
等待异步睡眠(5)
返回“我”
异步def进程(作业、循环、i):
印刷品(一)
task=loop.create_任务(some_other_进程())
值=等待任务
如果i<1:
另一个任务=循环。创建任务(另一个()
等待另一项任务
#等待一些其他过程()
def拉力(回路):
i=0
尽管如此:
job=f“随机整数-{random.randint(01100)}”
尝试:
循环。运行_直到_完成(进程(作业、循环、i))
i+=1
除asyncio.Cancelled错误外,错误为e:
打印(“任务取消”)
打破
除例外情况外:
打印(traceback.format_exc())
#asyncio.get_event_loop().stop()
def main():
尝试:
loop=asyncio.get\u event\u loop()
对于['SIGINT']中的signame:
loop.add\u信号\u处理程序(
getattr(信号,符号名称),
lambda:asyncio.确保未来(关机(信号名,循环))
)
尝试:
拉(环)
除例外情况外:
打印(traceback.format_exc())
最后:
loop.close()
最后:
打印(“完成”)
如果名称=“\uuuuu main\uuuuuuuu”:
main()
我不明白为什么我看到-
任务已销毁,但它处于挂起状态!
任务:
这里使用asyncio。确保您为shutdown
corroutine创建了任务,但您不需要在任何地方等待该任务的完成。稍后,当您关闭事件循环时,它会警告您此任务处于挂起状态
Upd:
如果您想做一些提示,最好的地方就是在loop.close()之前,不管脚本结束的原因是什么(信号、异常等)
尝试以这种方式更改代码:
# ...
async def shutdown(loop): # remove `signal` arg
# ...
def main():
try:
loop = asyncio.get_event_loop()
try:
pull(loop)
except Exception:
print(traceback.format_exc())
finally:
loop.run_until_complete(shutdown(loop)) # just run until shutdown is done
loop.close()
finally:
print("Done")
# ...
Upd2:
如果您仍然需要信号处理程序,可能需要执行以下操作:
from functools import partial
loop.add_signal_handler(
getattr(signal, signame),
partial(cb, signame, loop)
)
def cb(signame, loop):
loop.stop()
loop.run_until_complete(shutdown(signame, loop))
我在哪里等待它?我需要做的是在sigint
的情况下取消任务,因此我需要信号处理器最新更改的两个问题-运行时错误:事件循环在将来完成之前停止。
和任务已销毁,但它处于挂起状态代码>用于coro=
from functools import partial
loop.add_signal_handler(
getattr(signal, signame),
partial(cb, signame, loop)
)
def cb(signame, loop):
loop.stop()
loop.run_until_complete(shutdown(signame, loop))