python3 asyncio库学习(一)—— coroutine, task , future的区别

本文详细解析了Python中协程的实现方式,包括async/await语法、生成器和@asyncio.coroutine装饰器的使用,以及如何通过future和task进行调度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

18.5.3.1. Coroutines¶
Coroutines used with asyncio may be implemented using the async def statement, or by using generators. The async def type of coroutine was added in Python 3.5, and is recommended if there is no need to support older Python versions.
Generator-based coroutines should be decorated with @asyncio.coroutine, although this is not strictly enforced. The decorator enables compatibility with async def coroutines, and also serves as documentation. Generator-based coroutines use the yield from syntax introduced in PEP 380, instead of the original yield syntax.
The word “coroutine”, like the word “generator”, is used for two different (though related) concepts:
The function that defines a coroutine (a function definition using async def or decorated with @asyncio.coroutine). If disambiguation is needed we will call this a coroutine function (iscoroutinefunction() returns True).
The object obtained by calling a coroutine function. This object represents a computation or an I/O operation (usually a combination) that will complete eventually. If disambiguation is needed we will call it a coroutine object (iscoroutine() returns True).
Things a coroutine can do:
result = await future or result = yield from future – suspends the coroutine until the future is done, then returns the future’s result, or raises an exception, which will be propagated. (If the future is cancelled, it will raise a CancelledError exception.) Note that tasks are futures, and everything said about futures also applies to tasks.
result = await coroutine or result = yield from coroutine – wait for another coroutine to produce a result (or raise an exception, which will be propagated). The coroutine expression must be a call to another coroutine.
return expression – produce a result to the coroutine that is waiting for this one using await or yield from.
raise exception – raise an exception in the coroutine that is waiting for this one using await or yield from.
Calling a coroutine does not start its code running – the coroutine object returned by the call doesn’t do anything until you schedule its execution. There are two basic ways to start it running: call await coroutine or yield from coroutinefrom another coroutine (assuming the other coroutine is already running!), or schedule its execution using the ensure_future() function or the AbstractEventLoop.create_task() method.
Coroutines (and tasks) can only run when the event loop is running.
@asyncio.coroutine
Decorator to mark generator-based coroutines. This enables the generator use yield from to call async def coroutines, and also enables the generator to be called by async def coroutines, for instance using an await expression.
There is no need to decorate async def coroutines themselves.
If the generator is not yielded from before it is destroyed, an error message is logged. See Detect coroutines never scheduled.
Note

In this documentation, some methods are documented as coroutines, even if they are plain Python functions returning a Future. This is intentional to have a freedom of tweaking the implementation of these functions in the future. If such a function is needed to be used in a callback-style code, wrap its result with ensure_future().

简单点说:
coroutine是协程
future包裹了协程,为协程添加了回调模式,可以指定结果成功和失败时的回调函数
task负责调度协程,一个task来负责一个coroutine在时间片上的具体执行,包裹了协程,是future的子类

### Python `asyncio` 信息及其使用案例 #### 什么是 `asyncio` `asyncio` 是用于编写并发代码的应用程序接口,利用异步 I/O、事件循环、协程和任务来实现单线程中的并行操作[^1]。 #### 基本概念 - **协程 (Coroutines)**: 协程是种特殊的函数,在执行过程中可以暂停并在稍后从中断处继续执行。定义协程的方式是在其前面加上关键字 `async def`。 - **事件循环 (Event Loop)**: 这是 `asyncio` 的核心组件之,负责管理与调度协程的任务队列。所有的异步任务都在这个循环里运行。 - **任务 (Tasks)**: 将协程封装成个可被挂起的对象以便于管理和调度。可以通过调用 `asyncio.create_task()` 来创建任务实例。 - **Future**: 表示可能还没有完成的操作的结果;通常由内部创建,并通过回调机制通知结果的到来。 #### 使用例子 下面是个简单的例子展示如何使用 `asyncio` 创建两个等待不同时间长度的协程: ```python import asyncio async def say_after(delay, what): await asyncio.sleep(delay) print(what) async def main(): task1 = asyncio.create_task(say_after(1, 'hello')) task2 = asyncio.create_task(say_after(2, 'world')) # Wait until both tasks are completed (should take around 2 seconds.) await task1 await task2 # Run the event loop to execute the coroutine. asyncio.run(main()) ``` 这段代码展示了基本的 `asyncio` 结构——定义了两个带有延迟打印消息的简单协程,并在个主函数中启动它们作为独立的任务。最后,使用 `asyncio.run()` 启动整个流程。 #### 并发执行多个任务 如果想要更高效地处理大量相似性质的工作项,则可以考虑如下方式批量提交给事件循环: ```python import asyncio async def worker(name, queue): while True: sleep_for = await queue.get() await asyncio.sleep(sleep_for) print(f'{name} has slept for {sleep_for} seconds') queue.task_done() async def main(): num_workers = 2 q = asyncio.Queue() workers = [] for i in range(num_workers): w = asyncio.create_task(worker(f'worker-{i}', q)) workers.append(w) work_items = [5, 1, 8, 3] for item in work_items: await q.put(item) await q.join() # Block until all items have been processed. # Cancel our worker tasks after processing is complete. for w in workers: w.cancel() await main() ``` 此脚本模拟了个生产者消费者模型,其中有两个工作者不断从队列取出工作项目直到所有都完成了才结束进程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值