设为首页 加入收藏

TOP

asyncio之Coroutines,Tasks and Future(一)
2019-02-12 18:08:02 】 浏览:153
Tags:asyncio Coroutines Tasks and Future

asyncio之Coroutines,Tasks and Future

Coroutines and Tasks属于High-level APIs,也就是高级层的api。

本节概述用于协程和任务的高级异步api。

Coroutines

Coroutines翻译过来意思是协程,
使用async/await语法声明的协程是编写asyncio应用程序的首选方法。

import asyncio async def main(): print("hello") await asyncio.sleep(1) print("world") if __name__ == '__main__': # asyncio.run(main()) # 3.7的用法 # 阻塞直到hello world()协程结束时返回 loop = asyncio.get_event_loop() loop.run_until_complete(main())

第一个异步函数是通过创建loop循环去调用,其他异步函数之间通过await进行调用。
像下面的一个例子

import asyncio import time async def say_after(delay, what): await asyncio.sleep(delay) print(what) async def main(): print(f"started at {time.strftime('%X')}") await say_after(1, 'hello') await say_after(2, 'world') print(f"finished at {time.strftime('%X')}") if __name__ == '__main__': loop = asyncio.get_event_loop() # 阻塞直到hello world()协程结束时返回 loop.run_until_complete(main()) loop.close()

或者我们可以通过asyncio.create_task()将协程say_after封装任务去调用就像下面这样。

async def main(): task1 = asyncio.create_task( say_after(1, 'hello')) task2 = asyncio.create_task( say_after(2, 'world')) print(f"started at {time.strftime('%X')}") # 等待两个子任务完成 await task1 await task2 print(f"finished at {time.strftime('%X')}")

Awaitables

我们说,如果一个对象可以用在await表达式中,那么它就是Awaitables的对象。
可等待对象主要有三种类型:coroutines, Tasks, and Futures.

Coroutines

 前面的代码中演示了协程的运作方式,这里主要强调两点。

  • 协程函数:asyc def定义的函数;
  • 协程对象:通过调用协程函数返回的对象。

    Tasks

    任务对协程进一步封装,其中包含任务的各种状态。
    协程对象不能直接运行,在注册事件循环的时候,其实是run_until_complete方法将协程包装成为了一个任务(task)对象。
import asyncio async def nested(): await asyncio.sleep(2) print("等待2s") async def main(): # 将协程包装成任务含有状态 # task = asyncio.create_task(nested()) task = asyncio.ensure_future(nested()) print(task) # "task" can now be used to cancel "nested()", or # can simply be awaited to wait until it is complete: await task print(task) print(task.done()) if __name__ == '__main__': loop = asyncio.get_event_loop() try: loop.run_until_complete(main()) except KeyboardInterrupt as e: for task in asyncio.Task.all_tasks(): print(task) task.cancel() print(task) loop.run_forever() # restart loop finally: loop.close() 

可以看到

<Task pending coro=<nested() running at /Users/chennan/pythonproject/asyncproject/asyncio-cn/1-2-1.py:9>> 等待2s <Task finished coro=<nested() done, defined at /Users/chennan/pythonproject/asyncproject/asyncio-cn/1-2-1.py:9> result=None> True

创建task后,task在加入事件循环之前是pending状态然后调用nested函数等待2s之后打印task为finished状态。asyncio.ensure_future(coroutine) 和 loop.create_task(coroutine)都可以创建一个task,python3.7增加了asyncio.create_task(coro)。其中task是Future的一个子类

Future

future:代表将来执行或没有执行的任务的结果。它和task上没有本质的区别
通常不需要在应用程序级别代码中创建Future对象。
future对象有几个状态:

  • Pending
  • Running
  • Done
  • Cancelled

通过上面的代码可以知道创建future的时候,task为pending,事件循环调用执行的时候是running,调用完毕自然就是done于是调用task.done()打印了true。

如果在命令行中运行上述代码,ctrl+c后会发现
输出以下内容

<Task pending coro=<nested() running at 1-2-1.py:9>> ^C<Task pending coro=<main() running at 1-2-1.py:21> wait_for=<Task pending coro=<nested() running at 1-2-1.py:10> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x10d342978>()]> cb=[<TaskWakeupMethWrapper object at 0x10d342918>()]>> <Task pend
首页 上一页 1 2 3 4 下一页 尾页 1/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇BLACKPYTHON学习(一) 下一篇Django用户认证系统(一)User对象

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目