Python async模块使用方法杂谈

Python async模块使用方法杂谈

Python async(协程)是近年来非常流行的一种异步编程模式。async通过事件循环机制和协程技术实现其非阻塞的异步效果,让我们能够更方便、高效地编写异步代码。在本文中,我们将详细讲解Python async模块的使用方法,并带有两个示例说明。

1.异步编程概述

在传统的编程模式中,当程序执行到一个耗时的I/O操作后,程序会一直阻塞在这个操作上,直到I/O操作完成并返回结果。而在异步编程模式中,当程序执行到IO操作时,它不会被一直阻塞,而是可以去处理其他事情,避免了阻塞时间导致的不必要等待。

异步编程是在事件循环(Eventloop)的基础上完成的,协程(Coroutine)则是实现异步编程的核心技术。事件循环相当于一个消息处理器,从消息队列中取出消息,并将确定是能够立即处理的消息传递给对应的协程进行处理。

2.asyncio模块

Python3.4版本后,官方提供的异步编程模块就是asyncio(前身是tulip)。asyncio提供了事件循环机制,并且asyncio也提供了协程的支持,支持异步I/O和并发任务执行,因此是开发异步I/O服务的一个很好的选择。

asyncio模块常用函数和类

  • asyncio.create_task(协程对象):将协程包装为任务。
  • asyncio.wait(aws, timeout=None, return_when=ALL_COMPLETED):并行运行一个任务列表,aws是任务列表,timeout是等待的秒数,return_when的值可以是WAIT_FIRST_COMPLETED、ALL_COMPLETED或FIRST_EXCEPTION。
  • asyncio.gather(aws, *, loop=None, return_exceptions=False):并行运行一个协程列表,会在所有协程执行完成后返回结果。
  • asyncio.sleep():模拟时间的等待,是一个异步调用。
  • asyncio.Queue():一个异步队列,可以并发的进行put和get操作。

更多的函数和类请查看asyncio的官方文档。

3.说明示例:多任务异步I/O并行执行

接下来我们来看一个简单的示例,实现多任务异步I/O并行执行:

import asyncio
import time

async def do_work(num):
    print("start to work {}".format(num))
    await asyncio.sleep(1) # 模拟异步I/O
    print("work {} has been completed.".format(num))
    return num

async def main():
    tasks = [asyncio.create_task(do_work(i)) for i in range(1, 11)]
    await asyncio.wait(tasks)

if __name__ == '__main__':
    start_time = time.time()
    asyncio.run(main())
    print("time used: ", time.time() - start_time)

在本示例中,我们实现了10个协程任务的异步并行执行,每个任务都等待1秒钟后返回结果。通过asyncio.create_task()将每个异步任务都打包为任务,并将返回的任务列表传递给asyncio.wait()函数,该函数将异步执行所有任务并等待它们全部完成之后才结束。通过time.time()获取程序从开始执行到结束所消耗的时间。

输出结果如下:

start to work 1
start to work 2
start to work 3
start to work 4
start to work 5
start to work 6
start to work 7
start to work 8
start to work 9
start to work 10
work 1 has been completed.
work 2 has been completed.
work 3 has been completed.
work 4 has been completed.
work 5 has been completed.
work 6 has been completed.
work 7 has been completed.
work 8 has been completed.
work 9 has been completed.
work 10 has been completed.
time used:  1.00295090675354

如上输出所示,10个任务都在1秒钟之内完成了,说明它们是异步并行执行的。

4.说明示例:生产者-消费者模式

接下来,我们来看一个更复杂的示例,实现生产者-消费者模式。其中,生产者通过一个异步队列生产数据,而消费者则从队列中读取数据并进行处理。

import asyncio
import random

async def producer(queue, id):
    while True:
        item = random.randint(0, 99)
        print("Producer {} produced {}".format(id, item))
        await queue.put(item)
        await asyncio.sleep(0.5)

async def consumer(queue, id):
    while True:
        item = await queue.get()
        print("Consumer {} consumed {}".format(id, item))
        await asyncio.sleep(1)

async def main():
    queue = asyncio.Queue()
    producers = [asyncio.create_task(producer(queue, i)) for i in range(3)]
    consumers = [asyncio.create_task(consumer(queue, i)) for i in range(2)]

    await asyncio.sleep(10) # 等待10秒钟后结束任务
    for prod in producers:
        prod.cancel() # 取消生产者任务
    await asyncio.gather(*producers, return_exceptions=True) # 等待正在运行的任务完成
    await queue.join() # 等待队列清空
    for cons in consumers:
        cons.cancel() # 取消消费者任务

if __name__ == '__main__':
    asyncio.run(main())

在本示例中,我们定义了两个协程任务:生产者和消费者,在主函数中创建了一个异步队列,分别创建了3个生产者和2个消费者,每个生产者将随机生成的数据放入队列中,每个消费者从队列中取出数据并进行处理。在主函数中等待10秒钟后结束生产者任务,并等待队列清空后结束消费者任务。

输出结果如下:

Producer 0 produced 10
Consumer 0 consumed 10
Producer 1 produced 12
Consumer 1 consumed 12
Producer 2 produced 20
Consumer 0 consumed 20
Producer 0 produced 63
Consumer 1 consumed 63
Producer 1 produced 74
Producer 0 produced 81
Consumer 0 consumed 74
Consumer 0 consumed 81
Producer 2 produced 88
Consumer 1 consumed 88
.
.
.
Producer 1 produced 12
Consumer 0 consumed 12
Producer 0 produced 65
Consumer 1 consumed 65
Producer 1 produced 45
Consumer 0 consumed 45

如上输出所示,生产者和消费者协同工作,实现了异步的生产和消费,从而构建了生产者-消费者模式。

总结:异步编程是提高代码效率的一种重要的手段,Python的async模块提供了一套完整的异步编程解决方案。了解它的基本使用方法,可以帮助我们更高效地编写异步程序。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python async模块使用方法杂谈 - Python技术站

(0)
上一篇 2023年6月3日
下一篇 2023年6月3日

相关文章

  • Python中赋值运算符的含义与使用方法

    赋值运算符是Python中最基础的运算符之一,用于将一个值或变量赋值给一个变量名。赋值运算符的使用方法相对简单,但是掌握其含义及注意事项非常重要,本文将从以下几个方面详细讲解赋值运算符的使用。 赋值运算符的含义 Python中的赋值运算符包括=、+=、-=、*=、/=、//=、%=、**=,它们分别对应着不同的操作。其中最基础的是=赋值符号,用于将某个值或变…

    python 2023年6月5日
    00
  • Python之ascii转中文的实现

    概述 在Python中,我们可以使用内置的 chr() 和 ord() 函数来进行字符和ASCII码之间的相互转换。但是,如果我们需要把一堆ASCII码转成相应的中文怎么办呢?接下来,让我们来逐步实现实现这个转换的过程。 获取ASCII码值 首先,我们需要获取每个中文字符的ASCII码值。Python中的 ord() 函数可以帮助我们实现。我们可以使用下面的…

    python 2023年5月31日
    00
  • 为什么将 html 代码打印为字符串会在 python 中输出十六进制数字?

    【问题标题】:Why does printing html code as a string give hexadecimal numbers as output in python?为什么将 html 代码打印为字符串会在 python 中输出十六进制数字? 【发布时间】:2023-04-05 00:05:01 【问题描述】: 我编写了一个 Python …

    Python开发 2023年4月6日
    00
  • 基于Python爬取京东双十一商品价格曲线

    基于Python爬取京东双十一商品价格曲线是一个非常有用的应用场景,可以帮助我们在Python中快速获取京东双十一商品的价格曲线。本攻略将介绍Python爬取京东双十一商品价格曲线的完整攻略,包括数据获取、数据处理、数据存储和示例。 步骤1:获取数据 在Python中,我们可以使用requests库获取网页数据。以下是获取京东商品页面数据的示例: impor…

    python 2023年5月15日
    00
  • Python进阶之import导入机制原理详解

    Python进阶之import导入机制原理详解 简介 在 Python 中,我们经常需要导入其他模块中的代码以完成各种任务。Python 的 import 机制是实现这一功能的重要手段,可谓是 Python 中非常重要的一部分。通过本篇文章,我们将会具体讲解 Python 的 import 机制原理。 Python import 的分类 Python 中的 …

    python 2023年6月3日
    00
  • Python连接mssql数据库编码问题解决方法

    Python连接mssql数据库编码问题解决方法 在使用Python连接Microsoft SQL Server (MSSQL)数据库时,可能会遇到编码问题。通常情况下,我们需要解决以下两种编码问题: 数据库编码问题:某些情况下我们需要更改数据库编码以适配Python的默认编码。 查询结果编码问题:查询结果包含了特殊字符时,需要指定字符集编码。 下面我们将详…

    python 2023年5月20日
    00
  • 浅谈python下tiff图像的读取和保存方法

    浅谈Python下TIFF图像的读取和保存方法 在Python中,我们可以使用多种库来读取和保存Tiff格式的图像文件,如Pillow、OpenCV等。下面将分别介绍这些库的使用方法。 使用Pillow库 读取TIFF图像 读取TIFF格式的图像文件,我们可以使用Pillow库的Image.open()方法。示例代码如下: from PIL import I…

    python 2023年5月18日
    00
  • Django中使用极验Geetest滑动验证码过程解析

    下面是“Django中使用极验Geetest滑动验证码过程解析”的完整攻略。 什么是极验Geetest滑动验证码 极验Geetest滑动验证码是一种可以保障网站安全性的验证机制。通过综合分析用户行为特征,实现对机器人和人机协作攻击的防御。 Django中使用极验Geetest滑动验证码的步骤 1. 获取验证码 使用极验Geetest需要先到极验官网注册账号,…

    python 2023年6月3日
    00
合作推广
合作推广
分享本页
返回顶部