博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
深入Asyncio(六)Tasks and Futures
阅读量:5239 次
发布时间:2019-06-14

本文共 2153 字,大约阅读时间需要 7 分钟。

Tasks and Futures

大多数的工作只涉及到Task、create_task()方法,就像前面代码一样,Future是Task的父类,提供与loop交互的所有功能。

Future对象表示某个活动的未来完成状态,由loop管理,Task与之完全相同,但其活动特指coroutine。Future表示与loop交互的状态,Future对象描述的是完成状态的切换,其实例创建时状态是“尚未完成”,然后在稍后的一段时间后,实例状态为完成,Future的实例有一个done()方法用于检查状态。

>>> from asyncio import Future>>> f = Future()>>> f.done()False

Future实例可能:

  1. 有一个结果集(set_result(value)result());
  2. 可用cancel()取消(通过cancelled()检查);
  3. 拥有回调函数,并在完成时执行。

即使Task更普遍,但Future仍然无法避免,例如在executor中运行一个函数会返回一个Future对象而非Task。

>>> async def main(f: asyncio.Future):  # 1...     await asyncio.sleep(1)...     f.set_result('I have finished')    # 2>>> loop = asyncio.get_event_loop()>>> fut = asyncio.Future()  # 3>>> print(fut.done())   # 4False>>> loop.create_task(main(fut))    # 5
:1>>>>> loop.run_until_complete(fut) # 6'I have finished'>>> print(fut.done())True>>> print(fut.result()) # 7I have finished
  1. 创建一个简单的主函数;
  2. 为Future对象设置结果;
  3. 手动创建一个Future对象,该对象默认绑定在当前loop上,不能也不会属于任何coroutine;
  4. 在做任何事之前,先确认Future对象完成状态;
  5. 调度主程序,并将Future对象传递进去,主程序只是sleep,然后切换到Future对象,并且此时loop还未启动;
  6. 这里与以前不同的是,用Future对象而不是Task对象,现在loop开始运行;
  7. Future在设置结果时完成,然后可以访问结果。

绝大多数代码都不会像上面一样直接用Future对象,这里仅作学习用。

create_task还是ensure_future

后者很容易造成误解,从官方的函数docstring看:

asyncio.ensure_future(coro_or_future, *, loop=None)

Schedule the execution of a coroutine object: wrap it in a future. Return a Task object.
If the argument is a Future, it is returned directly.

清楚的解释一下:

1. 如果传入一个coroutine,它将返回一个Task(coroutine将会在loop中调度),这与直接调用create_task()没区别;
2. 如果传入一个Future,直接返回,完全没有改变地!

import asyncioasync def f():  # 1    passcoro = f()  # 2loop = asyncio.get_event_loop()    # 3task = loop.create_task(coro)   # 4assert isinstance(task, asyncio.Task)   # 5new_task = asyncio.ensure_future(coro)  # 6assert isinstance(new_task, asyncio.Task)mystery_meat = asyncio.ensure_future(task)  # 7assert mystery_meat is task    # 8
  1. 一个coroutine function;
  2. 获得coroutine;
  3. 获得loop;
  4. 通过create_task调度coroutine;
  5. 类型检查;
  6. 与create_task相同;
  7. Task是Future的子类,这里直接传入一个已经创建好的Task实例;
  8. 结果是True,完全没区别。

实际上,ensure_future()是提供给框架开发者处理两种参数用的。

在3.7中,asyncio提供了asyncio.create_task(coro)方法来为运行中的loop添加task,ensure_future()可以失业了。

转载于:https://www.cnblogs.com/ikct2017/p/9829002.html

你可能感兴趣的文章
使用maven创建web项目
查看>>
Spring mvc shiro 整合
查看>>
解决 maven 项目启动 提示 class not find
查看>>
weightpro自动蒙皮插件
查看>>
C++的性能优化实践【转】
查看>>
cartographer 最新版安装测试
查看>>
JavaScript使用方法
查看>>
Tomcat - ClassFormatException的解决方法
查看>>
Markdown - 如何给文本加下划线
查看>>
2018年11月17号 训练周记
查看>>
转博客园一位前辈关于.NET通过NCO3.0连接SAP的系列文章
查看>>
【NOIP2012模拟10.9】电费结算
查看>>
linux-----docker
查看>>
day04
查看>>
利用 ASP.NET 的内置功能抵御 Web 攻击 (1)
查看>>
系统任务管理器完美替代者System Explorer
查看>>
【凯立德】2012最新凯立德春季版导航C-Car系列 V3.0 地图编号2821J0A
查看>>
linux服务器网络连接timewait问题的解决方法
查看>>
如何操作使用Android 模拟器?
查看>>
洛谷P4363 [九省联考2018]一双木棋chess 【状压dp】
查看>>