如何使用Python中的asyncio?

栏目: IT技术 · 发布时间: 4年前

内容简介:【51CTO.com快译】Python的异步编程功能(简称async)让你可以编写不必等待独立任务完成就可以完成更多工作的程序。Python附带的asyncio库为你提供了使用async处理磁盘或网络I/O、无需其他方面等待的工具。asyncio提供了两种处理异步操作的API:高级和低级。高级API用途广泛,适用于各种应用程序。低级API功能强大,但也很复杂,使用频率较低。

如何使用 <a href='https://www.codercto.com/topics/20097.html'>Python</a> 中的asyncio?

【51CTO.com快译】Python的异步编程功能(简称async)让你可以编写不必等待独立任务完成就可以完成更多工作的程序。Python附带的asyncio库为你提供了使用async处理磁盘或网络I/O、无需其他方面等待的工具。

asyncio提供了两种处理异步操作的API:高级和低级。高级API用途广泛,适用于各种应用程序。低级API功能强大,但也很复杂,使用频率较低。

本文重点介绍高级API。我们会逐步介绍asyncio中常用的高级API,说明它们如何可用于涉及异步任务的常见操作。

如果你完全刚接触Python中的async,或者想了解其工作原理,不妨先看看本人介绍Python async的文章: https://www.infoworld.com/article/3454442/get-started-with-async-in-python.html ,之后再作深入研究。

在Python中运行协程和任务

很自然,asyncio最常见的用途是运行Python脚本的异步部分。这意味着学会使用协程和任务。

Python的异步组件(包括协程和任务)只能与其他异步组件一起使用,不能与常规的同步Python一起使用,因此需要asyncio来填补缺口。为此,你要使用asyncio.run函数:

import asyncio  
async def main():  
print ("Waiting 5 seconds. ")  
for _ in range(5):  
await asyncio.sleep(1)  
print (".")  
print ("Finished waiting.")  
asyncio.run(main()) 

这运行main(),连同main()触发的任何例程,等待结果返回。

通常而言,Python程序应只有一个.run()语句,就像Python程序应只有一个main()函数一样。 如果不小心使用,async可能会使程序的控制流难以阅读。程序的异步代码只有一个入口点可以避免情况变得繁复。

异步函数还可以调度安排成tasks,即包装协程并帮助运行协和的对象。

async def my_task():  
do_something()  
task = asyncio.create_task(my_task()) 

my_task()随后在事件循环中运行,结果存储在task中。

如果你只有一个任务想要获取结果,可以使用asyncio.wait_for(task)来等待任务完成,然后使用task.result()检索结果。但如果你安排了许多任务要执行,并想要等待所有任务完成,不妨使用asyncio.wait([task1, task2])收集结果。(注意,如果你不希望超过一定长度的时间后运行,可以设置操作的超时时间。)

在Python中管理异步事件循环

asyncio的另一个常见用途是管理异步事件循环。事件循环是运行异步函数和回调的对象。使用asyncio.run()时,它自动创建。你通常希望每个程序仅使用一个异步事件循环,同样以便管理。

如果你在编写服务器等更高级的软件,需要对事件循环拥有较低级别的访问权。为此,你可以“揭开面纱”,直接接触事件循环的内部机制。不过如果是简单的工作,不需要这么做。

在Python中使用streams读写数据

async的最佳使用场景是长时间运行的网络操作,其中应用程序可能阻止等待其他某个资源返回结果。为此,asyncio提供了streams,这是用于执行网络I/O的高级机制。这包括充当网络请求的服务器。

asyncio使用两个类StreamReader和StreamWriter,在高级层面进行网络读写。如果你要从网络读取,可以使用asyncio.open_connection()打开连接。该函数返回StreamReader对象和StreamWriter对象的元组,你要在每个对象上使用.read() 和.write()方法以便通信。

想接收来自远程主机的连接,使用asyncio.start_server()。asyncio.start_server()函数将回调函数client_connected_cb作为参数来接受,只要收到请求就调用该函数。该回调函数将StreamReader和StreamWriter的实例作为参数,那样你就能处理服务器的读/写逻辑。这个例子( https://gist.github.com/ethanfrey/75e58db27095936b9e5e )介绍了一个简单的HTTP服务器使用asyncio驱动的aiohttp库。

在Python中同步任务

异步任务往往独立运行,但有时你希望它们彼此通信。asyncio提供了队列和另外几种在任务之间进行同步的机制:

  • 队列:asyncio队列允许异步函数排列Python对象,以便供其他异步函数使用——比如说,基于行为在不同类型的函数之间分配工作负载。
  • 同步原语:asyncio中的锁、事件、条件和信号其工作方式类似常规的Python锁、事件、条件和信号。

关于所有这些方法要记住的一点是它们不是线程安全的。对于在同一事件循环中运行的异步任务来说这不是问题。但如果你试图与不同事件循环、操作系统线程或进程中的任务共享信息,就需要使用threading模块及其对象来执行此操作。

此外,如果你想跨线程边界启动协程,请使用asyncio.run_coroutine_threadsafe()函数,然后将与它结合使用的事件循环作为参数传递。

在Python中暂停协程

asyncio的另一个常见、但很少讨论的用途是在协程内部等待任意时长。为此你不能使用time.sleep(),否则会阻塞整个程序。而是应使用asyncio.sleep(),它允许其他协程继续运行。

在Python中使用较低级别的async

最后,如果你认为构建的应用程序可能需要asyncio的较低级组件,在开始编程之前先考虑一番:很可能有人已经构建了可以满足你需求的基于async的Python库。

比如说,如果你需要异步DNS查询,不妨查看aiodns库;若是异步SSH会话,则有asyncSSH。通过关键字“async”(以及其他与任务相关的关键字)搜索PyPI,或查看人工筛选的Awesome Asyncio列表( https://github.com/timofurrer/awesome-asyncio ),以获取灵感。

原文标题:How to use asyncio in Python,作者:Serdar Yegulalp

【51CTO译稿,合作站点转载请注明原文译者和出处为51CTO.com】

【责任编辑:庞桂玉 TEL:(010)68476606】


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Web Designer's Idea Book

The Web Designer's Idea Book

Patrick Mcneil / How / 2008-10-6 / USD 25.00

The Web Designer's Idea Book includes more than 700 websites arranged thematically, so you can find inspiration for layout, color, style and more. Author Patrick McNeil has cataloged more than 5,000 s......一起来看看 《The Web Designer's Idea Book》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

html转js在线工具
html转js在线工具

html转js在线工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试