时间:2021-05-23
coroutine 与 Future 的关系
看起来两者是一样的,因为都可以用以下的语法来异步获取结果,
实际上,coroutine 是生成器函数,它既可以从外部接受参数,也可以产生结果。使用 coroutine 的好处是,我们可以暂停一个函数,然后稍后恢复执行。比如在涉及到网路操作的情况下,能够停下函数直到响应到来。在停下的这段时间内,我们可以切换到其他任务继续执行。
而 Future 更像是 Javascript 中的 Promise 对象。它是一个占位符,其值会在将来被计算出来。在上述的例子中,当我们在等待网络 IO 函数完成时,函数会给我们一个容器,Promise 会在完成时填充该容器。填充完毕后,我们可以用回调函数来获取实际结果。
Task 对象是 Future 的子类,它将 coroutine 和 Future 联系在一起,将 coroutine 封装成一个 Future 对象。
一般会看到两种任务启动方法,
和
ensure_future 可以将 coroutine 封装成 Task。asyncio.gather 将一些 Future 和 coroutine 封装成一个 Future。
asyncio.wait 则本身就是 coroutine。
run_until_complete 既可以接收 Future 对象,也可以是 coroutine 对象,
Task 任务的正确退出方式
在 asyncio 的任务循环中,如果使用 CTRL-C 退出的话,即使捕获了异常,Event Loop 中的任务会报错,出现如下的错误,
Task was destroyed but it is pending!
task: <Task pending coro=<kill_me() done, defined at test.py:5> wait_for=<Future pending cb=[Task._wakeup()]>>
根据官方文档,Task 对象只有在以下几种情况,会认为是退出,
a result / exception are available, or that the future was cancelled
Task 对象的 cancel 和其父类 Future 略有不同。当调用 Task.cancel() 后,对应 coroutine 会在事件循环的下一轮中抛出 CancelledError 异常。使用 Future.cancelled() 并不能立即返回 True(用来表示任务结束),只有在上述异常被处理任务结束后才算是 cancelled。
故结束任务可以用
这种方法将所有任务找出并 cancel。
但 CTRL-C 也会将事件循环停止,所以有必要重启事件循环,
try: loop.run_until_complete(tasks)except KeyboardInterrupt as e: for task in asyncio.Task.all_tasks(): task.cancel() loop.run_forever() # restart loopfinally: loop.close()在每个 Task 中捕获异常是必要的,如果不确定,可以使用
asyncio.gather(..., return_exceptions=True)
将异常转换为正常的结果返回。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
javascript中setTimeout使用指南/*//方法1functionslows(){alert("15S后弹出!");}setTimeout("sl
这里我们使用dnsmasq对应的docker版本docker-dnsmasq。使用指南下载镜像dockerpulldocker-dnsmasq创建最简单的配置/
Docker-clientforpython使用指南:客户端初始化的三种方法importdockerdocker.api()docker.APIClient()
MYSQL初学者使用指南与介绍一、连接MYSQL。格式:mysql-h主机地址-u用户名-p用户密码1、例1:连接到本机上的MYSQL。首先在打开DOS窗口,然
本文实例讲述了JavaScript面向对象核心知识与概念。分享给大家供大家参考,具体如下:一、面向对象1.1概念面向对象就是使用对象。面向对象开发就是使用对象开