python中的asyncio模块

1. 引言

asyncio 是 Python3.4 引入的一个标准库,用于编写异步代码。它提供了一种协程(coroutine)的方式,可以在单线程下实现多任务,避免了多线程代码中常见的锁、线程切换等问题,从而提高了程序的执行效率。在本文中,我们将深入探讨 asyncio 模块的使用和原理。

2. 协程与异步

2.1 协程

协程是一种轻量级的线程,也称为用户态线程。它可以在一个线程中实现多任务并发处理,而不需要进行线程上下文的切换。在 Python 中,使用 async def 定义一个协程函数,同时使用 await 关键字来挂起当前协程的执行,等待另一个协程的执行完成后再继续执行。

2.2 异步

在计算机中,异步通常指的是不等待某个操作的完成,而是在操作完成之前返回,继续执行其他操作,以提高程序的响应速度。在 asyncio 中,我们使用异步的方式来执行协程,通常使用 async/await 关键字来实现。

3. asyncio 的基本用法

3.1 定义协程函数

在 asyncio 中,我们使用 async def 关键字来定义协程函数。协程函数的执行顺序和普通函数不同,它需要使用 await 关键字等待另一个协程函数的执行结果,才能继续执行下去。

import asyncio

async def hello():

print("Hello, world!")

await hello()

上述代码定义了一个协程函数 hello,并使用 await 关键字来等待它的执行结果。在 Python 3.7 及以上版本中,可以直接使用 asyncio.run() 函数来执行一个协程函数。

import asyncio

async def hello():

print("Hello, world!")

asyncio.run(hello())

3.2 运行事件循环

在 asyncio 中,事件循环是非常重要的一个概念,它用于管理协程的执行顺序。我们可以使用 asyncio.get_event_loop() 函数来获取默认的事件循环,使用 loop.run_until_complete() 函数来运行协程,直到协程全部执行完成才停止。

import asyncio

async def hello():

print("Hello, world!")

loop = asyncio.get_event_loop()

loop.run_until_complete(hello())

4. asyncio 的高级用法

4.1 asyncio.sleep()

asyncio.sleep() 函数用于等待一段时间后再继续执行协程。在等待期间,事件循环会挂起当前协程的执行,并开始执行其他协程。

import asyncio

async def hello():

print("Start")

await asyncio.sleep(1)

print("End")

loop = asyncio.get_event_loop()

loop.run_until_complete(hello())

4.2 asyncio.create_task()

asyncio.create_task() 函数用于创建一个协程任务,将其添加到事件循环中。相比于直接使用 run_until_complete() 函数执行协程,这种方式更加灵活,可以同时运行多个协程。

import asyncio

async def foo():

print("Foo")

async def bar():

print("Bar")

loop = asyncio.get_event_loop()

task1 = loop.create_task(foo())

task2 = loop.create_task(bar())

loop.run_until_complete(asyncio.wait([task1, task2]))

4.3 asyncio.wait()

asyncio.wait() 函数用于等待多个协程任务全部执行完毕。

import asyncio

async def foo():

print("Foo")

async def bar():

print("Bar")

loop = asyncio.get_event_loop()

tasks = [loop.create_task(foo()), loop.create_task(bar())]

loop.run_until_complete(asyncio.wait(tasks))

4.4 asyncio.gather()

asyncio.gather() 函数用于并行执行多个协程任务,并将它们的执行结果集合在一起返回。

import asyncio

async def my_sum():

total = 0

for i in range(10):

total += i

await asyncio.sleep(0.1)

return total

async def my_product():

product = 1

for i in range(1, 6):

product *= i

await asyncio.sleep(0.2)

return product

loop = asyncio.get_event_loop()

results = loop.run_until_complete(asyncio.gather(my_sum(), my_product()))

print(results)

4.5 asyncio.Lock()

asyncio.Lock() 函数用于创建一个锁对象,来控制多个协程之间的互斥访问。在一个协程获取了锁对象之后,其他协程就不能再获取该锁对象,直到该协程释放锁。

import asyncio

async def task(lock):

print("start")

async with lock:

print("get lock")

await asyncio.sleep(0.5)

print("end")

loop = asyncio.get_event_loop()

lock = asyncio.Lock()

tasks = [task(lock) for i in range(10)]

loop.run_until_complete(asyncio.wait(tasks))

5. 总结

本文介绍了 asyncio 模块的基本用法和高级用法,包括协程函数的定义、事件循环的运行、休眠、任务创建、任务等待、任务并行执行和锁对象等内容。了解这些内容对于编写高效的异步代码非常重要。希望本文可以帮助大家更好地理解和使用 asyncio 模块。

后端开发标签