Python 异步: 创建和运行异步任务(7)

简介: 您可以从 asyncio 程序中的协程创建任务对象。任务提供独立调度和运行的协程的句柄,并允许查询、取消任务,以及稍后检索结果和异常。异步事件循环管理任务。因此,所有协程都成为事件循环中的任务并作为任务进行管理。

让我们仔细看看 asyncio 任务。

1. 什么是异步任务

异步任务是一个调度并独立运行 asyncio 协程的对象。它提供了一个调度协程的句柄,asyncio 程序可以查询并使用它来与协程交互。

任务是从协程创建的。它需要一个协程对象,包装协程,安排它执行,并提供与之交互的方法。任务独立执行。这意味着它被安排在 asyncio 事件循环中,并且无论创建它的协程中发生了什么,它都会执行。这与直接执行协程不同,后者调用者必须等待它完成。

asyncio.Task 类扩展了 asyncio.Future 类,一个实例是可等待的。Future 是一个较低级别的类,代表最终会到达的结果。扩展 Future 类的类通常被称为 Future-like。

因为异步任务是可等待的,这意味着协程可以使用 await 表达式等待任务完成。

...
# wait for a task to be done
await task

现在我们知道什么是 asyncio 任务,让我们看看如何创建一个。

2. 如何创建任务

使用提供的协程实例创建任务。回想一下协程是使用 async def 表达式定义的,看起来像一个函数。

# define a coroutine
async def task_coroutine():
    # ...

任务只能在协程中创建和调度。创建和调度任务有两种主要方式,它们是:

  1. 使用高级 API 创建任务(首选)
  2. 使用低级 API 创建任务

2.1. 高级 API

可以使用 asyncio.create_task() 函数创建任务。asyncio.create_task() 函数接受一个协程实例和一个可选的任务名称,并返回一个 asyncio.Task 实例。

...
# create a coroutine
coro = task_coroutine()
# create a task from a coroutine
task = asyncio.create_task(coro)

这可以通过在一行中使用复合语句来实现。

...
# create a task from a coroutine
task = asyncio.create_task(task_coroutine())

这将做几件事:

  1. 将协程包装在异步任务实例中。
  2. 安排任务在当前事件循环中执行。
  3. 返回一个任务实例

任务实例可以被丢弃,通过方法与之交互,并由协程等待。这是从 asyncio 程序中的协程创建任务的首选方法。

2.2. 低级 API

也可以使用较低级别的 asyncio API 从协程创建任务。

第一种方法是使用 asyncio.ensure_future() 函数。此函数采用任务、未来或类似未来的对象,例如协程,以及可选的用于调度它的循环。如果没有提供循环,它将被安排在当前事件循环中。

如果为这个函数提供了协程,它会为我们包装在一个实例中,然后返回。

...
# create and schedule the task
task = asyncio.ensure_future(task_coroutine())

我们可以用来创建和调度任务的另一个低级函数是 loop.create_task() 方法。此函数需要访问特定的事件循环,在该事件循环中将协程作为任务执行。

我们可以通过 asyncio.get_event_loop() 函数获取 asyncio 程序中当前事件循环的实例。然后可以使用它来调用 create_task() 方法来创建一个 Task 实例并安排它执行。

...
# get the current event loop
loop = asyncio.get_event_loop()
# create and schedule the task
task = loop.create_task(task_coroutine())

3. 任务何时运行?

创建任务后的一个常见问题是它什么时候运行?

虽然我们可以通过 create_task() 函数调度协程作为任务独立运行,但它可能不会立即运行。事实上,直到事件循环有机会运行,任务才会执行。

直到所有其他协程都没有运行并且轮到任务运行时才会发生这种情况。

例如,如果我们有一个 asyncio 程序,其中有一个创建和调度任务的协程,则调度的任务将不会运行,直到创建任务的调用协程被挂起。

如果调用协程选择休眠,选择等待另一个协程或任务,或者选择等待已安排的新任务,则可能会发生这种情况。

...
# create a task from a coroutine
task = asyncio.create_task(task_coroutine())
# await the task, allowing it to run
await task

现在我们知道什么是任务以及如何安排它们。

相关文章
|
2天前
|
存储 NoSQL Redis
在Python Web开发过程中,为什么Redis运行速度快
【5月更文挑战第15天】Redis在Python Web开发中运行速度快,原因包括:1) 丰富数据类型满足多样化需求;2) 简单数据模型提升查询效率;3) 单线程模型结合非阻塞I/O实现高效处理;4) 持久化机制保证数据安全;5) 二进制协议与管道技术优化网络通信。这些因素共同确保Redis能处理大量请求并保持高性能。
24 1
|
2天前
|
SQL 数据采集 数据挖掘
构建高效的Python数据处理流水线:使用Pandas和NumPy优化数据分析任务
在数据科学和分析领域,Python一直是最受欢迎的编程语言之一。本文将介绍如何通过使用Pandas和NumPy库构建高效的数据处理流水线,从而加速数据分析任务的执行。我们将讨论如何优化数据加载、清洗、转换和分析的过程,以及如何利用这些库中的强大功能来提高代码的性能和可维护性。
|
2天前
|
数据采集 Web App开发 数据处理
Lua vs. Python:哪个更适合构建稳定可靠的长期运行爬虫?
Lua vs. Python:哪个更适合构建稳定可靠的长期运行爬虫?
|
2天前
|
缓存 Shell 开发工具
[oeasy]python0016_在vim中直接运行python程序
在 Vim 编辑器中,可以通过`:!`命令来执行外部程序,例如`:!python3 oeasy.py`来运行Python程序。如果想在不退出Vim的情况下运行当前编辑的Python文件,可以使用`%`符号代表当前文件名,所以`:!python3 %`同样能运行程序。此外,可以使用`|`符号连续执行命令,例如`:w|!python3 %`会先保存文件(`w`)然后运行Python程序。这样,就可以在不离开Vim的情况下完成编辑、保存和运行Python程序的流程。
19 0
|
2天前
|
API UED Python
使用Python进行异步HTTP请求的实践指南
使用Python进行异步HTTP请求的实践指南
20 4
|
2天前
|
SQL DataWorks 安全
DataWorks产品使用合集之DataWorks资源里python运行时候,查看中途打印日志如何解决
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
26 0
|
2天前
|
并行计算 数据处理 开发者
Python并发编程:解析异步IO与多线程
本文探讨了Python中的并发编程技术,着重比较了异步IO和多线程两种常见的并发模型。通过详细分析它们的特点、优劣势以及适用场景,帮助读者更好地理解并选择适合自己项目需求的并发编程方式。
|
2天前
|
测试技术 Python
python运行集成测试
【4月更文挑战第22天】
11 1
|
2天前
|
运维 监控 Serverless
Serverless 应用引擎产品使用之阿里函数计算中在自定义环境下用debian10运行django,用官方层的python3.9,配置好环境变量后发现自定义层的django找不到了如何解决
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
22 3