当前位置: 首页 > news >正文

Asyncio是Python库,它允许我们使用async/await语法编写并发代码。学习如何使用此库编写异步代码。

大多数Python开发人员可能只接触过同步代码。但是,如果你是一名数据科学家,你可能使用multiprocessing库来并行运行一些计算。如果你是一名Web开发人员,你可能接触过线程中的并发。multiprocessing和threading都是Python中的高级概念,各自有特定的应用领域。

Asyncio 是 Python 库,用于编写使用 async 和 await 语法的并发代码。它主要用于 I/O 密集型任务,例如网页开发或从 API 中获取数据。

 除了多进程和多线程之外,Python的并发性家族中还有另一个新成员:asyncio。Asyncio是一个用于使用async/await语法编写并发代码的库。与线程类似,asyncio适用于在实践中非常常见的I/ o密集型任务。我将介绍asyncio的基础知识,并演示如何使用这个新库编写异步代码。

cpu密集型任务和I/ o密集型任务有什么区别?

在开始使用asyncio库之前,了解cpu密集型和I/ o密集型任务是很重要的,因为它们决定了应该使用哪个库来解决您的特定问题。

cpu密集型任务的大部分时间都用cpu进行繁重的计算。如果你是一名数据科学家,需要处理大量数据来训练机器学习模型,那么这是一项cpu密集型任务。在这种情况下,您应该使用多进程来并行运行作业,并充分利用cpu。

I/O密集型任务将大部分时间用于等待I/O响应,这些响应可以是来自网页、数据库或磁盘的响应。如果你正在开发一个网页,其中一个请求需要从api或数据库中获取数据,这是一个I/ o约束任务。对于I/O密集型任务,可以使用线程或asyncio实现并发,以最大限度地减少来自外部资源的等待时间

Asyncio与线程

现在您知道了线程和异步都适用于I/ o密集型任务,那么它们的区别是什么呢?

首先,线程使用多个线程,而asyncio只使用一个。线程更容易理解,因为线程轮流运行代码,从而实现并发性。但是如何用单个线程实现并发呢?

线程通过抢占式多任务实现并发,这意味着我们无法确定何时在哪个线程中运行哪个代码。是操作系统决定哪些代码应该在哪个线程中运行。操作系统可以在线程之间的任何点切换控制权。这就是为什么我们经常看到线程的随机结果。

另一方面,asyncio通过协作多任务实现并发。我们决定可以等待代码的哪一部分,然后切换控制以运行代码的其他部分。这些都是通过await命令在一个线程中完成的。稍后看到代码时,这一点会更清楚。

Asyncio中的协程?

这是asyncio中一个奇特的名字。要解释它是什么并不容易。许多教程根本不解释这个概念,只是用一些代码向您展示它是什么。然而,让我们试着去理解它是什么。我们将从回顾Python的定义开始。

“协程是一种更通用的子程序形式。子程序在一个点进入,在另一个点退出。协程可以在许多不同的地方进入、退出和恢复。”Glossary — Python 3.10.15 documentation

虽然这看起来仍然相当令人困惑,但一旦您对asyncio有了更多的经验,它就会变得更有意义。

在这个定义中,我们可以将子程序理解为函数,尽管两者之间存在差异。通常,函数只在调用时进入和退出一次。不过,Python中有一个特殊的函数generator,可以多次进入和退出。

协程的行为类似于生成器。在较旧版本的Python中,协程是由生成器定义的。这些协程被称为基于生成器的协程。然而,协程现在已经成为Python的原生功能,并且可以使用新的async def语法来定义。尽管基于生成器的协程现在已被弃用,但它们的历史和存在可以帮助我们理解什么是协程,以及如何在代码的不同部分之间切换或生成控制。

即使你不能马上理解所有的概念,也没关系。随着时间的推移,当你使用asyncio库编写和阅读越来越多的异步代码时,它们将变得更加清晰。

如何在Asyncio中定义协程函数

现在已经介绍了基本概念,我们可以编写我们的第一个协程函数:

async def coro_func():print("hello")coro_obj = coro_func()
print(type(coro_obj))

coro_func()是一个协程函数,当它被调用时,它将返回一个协程对象,并输出 “coroutine”

As you may have noticed, when the coroutine function is called, the print function isn’t called. If you have worked with generators, you won’t be surprised because it behaves similarly to generator functions:

def gen_func():yield "hello,generator"generator = gen_func()
print(type(generator))
print(next(generator))

为了在生成器中运行代码,你需要迭代它。你可以使用next函数来迭代它

类似地,要运行在协程函数中定义的代码,你需要等待它。然而,你不能像迭代生成器那样等待它。一个协程只能在另一个由async def语法定义的协程中等待:

import asyncioasync def coro_func():print('hello world')async def main():print('In the entrypoint coroutine')await coro_func()a = main()
print(type(a))
asyncio.run(main())

 在底层,它是由事件循环处理的。然而,使用现代Python,你不需要担心这些细节。

如何在Asyncio的协程函数中返回值

import asyncioasync def coro_func():print("Hello, asyncio!")return "123"async def main():print("In the entrypoint coroutine.")s = await coro_func()print(s)asyncio.run(main())

如何在Asyncio中并发运行多个协程

import asyncio
from datetime import datetimeasync def async_sleep(num):print(f"Sleeping {num} seconds.")await asyncio.sleep(num)async def main():start = datetime.now()coro_objs = []for i in range(1, 4):coro_objs.append(async_sleep(i))await asyncio.gather(*coro_objs)duration = datetime.now() - startprint(f"Took {duration.total_seconds():.2f} seconds.")asyncio.run(main())

Asyncio中的Async和Aiohttp示例 python3.10

import asyncio
import aiohttpasync def scrape_page(session, url):print(f"Scraping {url}")async with session.get(url) as resp:return len(await resp.text())async def main():urls = ["http://www.baidu.com","http://www.baidu.com","http://www.baidu.com"]tasks = []async with aiohttp.ClientSession() as session:for url in urls:task = asyncio.create_task(scrape_page(session, url))tasks.append(task)results = await asyncio.gather(*tasks)for url, length in zip(urls, results):print(f"{url} -> {length}")asyncio.run(main())


http://www.mrgr.cn/news/69420.html

相关文章:

  • 使用Python的Pyecharts 绘制地图
  • 实用且免费的 IP 地域查询 API 接口推荐
  • 搜维尔科技:Haption力触觉交互,虚拟机械装配验证
  • Scala入门基础(17.1)Set集习题
  • C语言的内存函数
  • 初次体验Tauri和Sycamore(1)
  • 探索10款音频剪辑软件,让你轻松编辑声音。
  • 链表类算法【leetcode】
  • 记录一次性能优化流程
  • Controlnet作者新作IC-light V2:基于FLUX训练,支持处理风格化图像,细节远高于SD1.5
  • 【1】虚拟机安装
  • AI 写作(五)核心技术之文本摘要:分类与应用(5/10)
  • 从0开始学习机器学习--Day20--优化算法的思路
  • Sequelize+Sqlite3使用示例
  • “2048”游戏网页版html+css+js
  • 2024系统分析师---微服务架构(淘宝押题)
  • 万字长文解读深度学习——GPT、BERT、T5
  • FFmpeg存放压缩后的音视频数据的结构体:AVPacket简介,结构体,函数
  • C++入门(下)
  • 关于c语言内存越界及防范措施
  • C#-密封类、密封方法
  • 发顶会首选:大模型+时间序列!掌握这3大切入点,小白也能轻松上手!
  • 终端会话工具byobu
  • 增强现实技术在零售业中的应用
  • 程序员应该有什么职业素养?
  • 每日一题之二叉树