asyncio 模块。asyncio
模块具有优秀的特性,允许我们编写更高效的 Python 异步应用。我们将探讨如何在 Python 中管理异步事件循环。在深入探讨这个主题之前,让我们先了解一下什么是异步编程。
什么是异步编程?
在同步编程中,方法被编写成一次执行一个任务。如果一个函数依赖于另一个函数的输出,它必须等待该函数的执行完成。程序实际上是停止的,直到函数完成它的执行。这意味着一次可以执行一个程序。
这降低了程序的速度,因为它被迫停止并等待一些事情完成。系统中有许多进程器可用,因此做其他任务而不是理想的 sit 是对资源的浪费。
为了克服这一点,异步编程概念开始发挥作用。它的行为不同;它也需要一次执行一次。但是系统可能不会等到执行完毕再继续下一步。
这意味着,如果程序将执行另一项任务,而前一项任务尚未完成并仍在其他地方运行,则处理器并不理想。
在本教程中,我们将解释为什么我们需要这样一种类型的编程。
什么是异步输入输出?
asyncio 是一个 Python 库,用于使用异步/等待运行并发代码。它是 Python 异步框架的基础,提供连接库、网络和 web 服务器、数据库分布式任务队列、高性能等。
该模块提供了围绕事件循环工作的框架,并且还处理输入/输出和系统事件等事情。
协同工作和任务
asyncio 是一个 Python 库,用于使用异步/等待运行并发代码。它是 Python 异步框架的基础,提供连接库、网络、网络服务器、数据库分布式任务队列、高性能等。
该模块提供了围绕事件循环工作的框架,并处理输入/输出和系统事件等事务。
示例- 1
import asyncio
async def main():
print ("Waiting 5 seconds. ")
for _ in range(5):
await asyncio.sleep(1)
print ("Hello")
print ("Finished waiting.")
asyncio.run(main())
输出:
Waiting 5 seconds.
Hello
Hello
Hello
Hello
Hello
Finished waiting.
解释-
在上面的代码中-
- 我们已经导入了
asyncio
模块来访问 Python 异步功能。 - 然后创建一个 primary() 函数,并在前面写 async 关键字。这将允许程序异步运行任务。
- 我们使用
for
循环并调用sleep()方法,这迫使我们等待 1 秒钟。 - 程序一秒钟后打印“你好”。
- 程序应该有一个。运行()功能以及一个。main() 功能。
我们还可以安排任务或对象来绑定协程并帮助它们运行。让我们理解下面的例子。
示例- 2
import asyncio
import time
async def execute(delay, value):
await asyncio.sleep(delay)
print(value)
async def main():
print(f"started at {time.strftime('%X')}")
await execute(1, 'hello')
await execute(2, 'world')
print(f"finished at {time.strftime('%X')}")
asyncio.run(main())
输出:
started at 11:11:54
hello
world
finished at 11:11:57
解释-
在上面的代码中,
- 我们已经导入了 asyncio 和时间模块。
- 然后我们用延迟和值参数定义了 execute() 函数。它使用睡眠()方法打印延迟时间。
- 在 main() 函数中,我们传递了两个参数:第一个是延迟时间,第二个是要打印的值。
- 程序开始执行并打印准确的执行时间,打印“你好”,然后等待两秒钟,打印“世界”并停止。
现在,让我们对上面的代码进行一些更改,并查看结果。
示例- 3 创建任务
async def execute(delay, value):
await asyncio.sleep(delay)
print(value)
async def main():
# Using asyncio.create_task() method to run coroutines concurrently as asyncio
task1 = asyncio.create_task(
execute(1, 'hello'))
task2 = asyncio.create_task(
execute(2, 'world'))
print(f"started at {time.strftime('%X')}")
# Wait until both tasks are completed (should take
# around 2 seconds.)
await task1
await task2
print(f"finished at {time.strftime('%X')}")
asyncio.run(main())
输出:
started at 15:43:30
hello
world
finished at 15:43:32
我们可以看到它比前一个程序快 1 秒。 create.task() 方法将在事件循环中运行,并将结果放入任务中。我们已经安排了这两个任务,并使用等待返回它们。
用 Python 管理异步事件循环
Asyncio 还用于管理异步事件循环。事件循环是运行异步函数和回调的对象。当我们想要执行协程时,当我们运行 asyncio.run() 方法时,事件对于异步函数来说是至关重要的;自动创建事件循环对象。为了实现更高级的服务器,我们需要对事件循环的低级访问。我们需要直接处理事件循环的内部。
事件循环具有以下特征。
- 它可以注册、执行和取消延迟调用(异步函数)
- 它可以为通信创建客户机和服务器传输
- 它可以为与另一个程序的通信创建子过程和传输。
- 将函数调用委托给线程池。
让我们看看下面的例子。
示例-
import asyncio
async def speech_async():
print('This is a asynchronicity!')
loop = asyncio.get_event_loop()
loop.run_until_complete(speech_async())
loop.close()
输出:
This is a asynchronicity!
事件循环从获取 asyncio.get_event_loop() 开始,调度并运行异步任务,当我们完成运行时关闭事件循环。
用 Python 中的流读写数据
asyncio
模块提供流,用于执行高级网络输入/输出。它可以充当网络请求的服务器。它最适合于长时间运行的网络操作,其中应用阻塞等待一些其他资源返回结果。
asyncio 有两个类,StreamReader 和 StreamWriter 。这些类用于高级别的网络读写。
要从网络读取,我们需要使用asyncio . open _ connection()打开网络。我们将使用流读取器和流写入器对象函数返回元组。阅读()和。将()方法写入每个连接。
asyncio.start_server ()方法用于接收来自远程主机的连接。该函数以回调函数 client_connected_cb 为参数。每当函数收到请求时都会调用它。
Python 中的同步任务
我们之前已经讨论过,异步程序是分开运行的,但是有时我们会希望相互通信。asyncio
模块为我们提供了一个队列和各种其他方法来建立任务之间的同步。
下面我们来了解一下下面的实现方法。
- 队列- 异步队列便于异步函数排列 Python 对象,以供其他异步函数使用。例如——工作负载分布在行为上的函数之间。
- 同步原语-asyncio 的特性锁、事件、条件和信号量充当了传统 Python 的对应物。
这里有一点要时刻记住,这些方法不是线程安全的。对于在同一事件循环中运行的异步任务,这不是问题。但是我们需要使用线程模块在任务之间共享信息。
什么时候使用异步编程?
在下面的场景中,我们可以使用异步编程。
- 当我们想要快速完成工作时。
- 延迟包括等待输入/输出(磁盘或网络)操作,而不是计算。
- 当许多输入/输出操作同时发生时。
asyncio
模块允许我们并行执行多个任务,并高效地迭代它们,而不会阻塞应用的其余部分。
下面给出了一些任务,它们可以很好地与 asyncio 配合使用。
- 刮网。
- 网络服务(网络服务器和框架)
- 同步数据库
Asyncio 中的几个重要函数
下面是异步编程时使用的一些基本方法。
运行异步程序
- asyncio.run(coro,* debug = False)-*此功能用于阻止 执行延迟*** 秒。它挂起当前任务,并允许另一个任务运行。延迟是一个显示秒数的参数。
示例-
async def main():
await asyncio.sleep(1)
print('hello')
asyncio.run(main())
创建任务
- *create_task(coro, name = None)-该功能将 Coroutines 包装成一个 task,安排**执行。它返回任务对象。
示例-
async def coro():
...
# In Python 3.7+
task = asyncio.create_task(coro())
...
task = asyncio.ensure_future(coro())
睡眠
- *睡眠(延迟,结果=无,循环=无)- 此功能用于阻止执行延迟执行**秒。它挂起当前任务,并允许其他任务运行。延迟是一个显示秒数的参数。
示例-
import asyncio
async def main():
for _ in range(3):
await asyncio.sleep(1)
print ("Hello")
asyncio.run(main())
超时设定
- *协同工作等待(aw,超时,循环=无)- 该功能用于等待 aw(协同工作自动安排为任务)唤醒超时完成。
示例-
async def myfunc():
# Sleep for ten minutes
await asyncio.sleep(600)
print('hello!')
async def main():
# Wait for at most 1 second
try:
await asyncio.wait_for(myfunc(), timeout=1.0)
except asyncio.TimeoutError:
print('timeout!')
asyncio.run(main())
结论
本教程包括使用 Python asyncio
模块进行异步编程的概念。当我们使用上下文切换时,asyncio 为我们提供了对何时上下文的编程控制。这意味着我们可以处理线程编程中出现的许多复杂问题。
它是一个强大而有价值的工具,但仅适用于异步类型编程。我们已经用它们各自的例子讨论了协程和任务。我们还讨论了在 Python 中管理事件循环和用流读写数据。它还包括必要的方法。