Python 异步编程——使用 asyncio 处理并发任务

Python 异步编程——使用 asyncio 处理并发任务

目录

Python 异步编程——使用 asyncio 处理并发任务

1. 异步编程概述

2. 什么是 asyncio?

2.1 事件循环

2.2 协程

3. 编写和运行异步任务

3.1 创建异步任务

3.2 并发执行多个任务

4. 异常处理

5. 使用 asyncio 处理 I/O 操作

5.1 异步文件读写

6. 总结



1. 异步编程概述

异步编程是一种处理并发任务的编程方式,它允许程序在等待某些操作完成时继续执行其他任务。与传统的同步编程不同,异步编程能够提高程序的效率,特别是在处理 I/O 操作(如网络请求、文件读写)时。

2. 什么是 asyncio

asyncio 是 Python 的一个标准库模块,用于编写并发代码。它提供了事件循环机制、协程(coroutines)和任务(tasks)的支持,使得异步编程变得简单和高效。

2.1 事件循环

事件循环是异步编程的核心,它负责调度和管理异步任务。事件循环会不断检查是否有任务完成或准备好执行,并依次执行这些任务。

2.2 协程

协程是一种特殊类型的函数,能够在执行过程中暂停和恢复。使用 async 关键字定义协程函数,协程函数返回一个 coroutine 对象,而不是直接执行。

示例:

 

python

import asyncio

async def say_hello():
    print("Hello")
    await asyncio.sleep(1)
    print("World")

在这个示例中,say_hello 是一个协程函数,它首先打印 "Hello",然后暂停 1 秒,最后打印 "World"

3. 编写和运行异步任务

3.1 创建异步任务

使用 asyncio.create_task 函数可以将协程函数封装成任务(tasks),并提交给事件循环执行。

示例:

 

python

import asyncio

async def say_hello():
    print("Hello")
    await asyncio.sleep(1)
    print("World")

async def main():
    # 创建并运行异步任务
    task = asyncio.create_task(say_hello())
    await task

# 运行事件循环
asyncio.run(main())

python

在这个示例中,main 函数创建了一个异步任务 task,并等待它完成。asyncio.run(main()) 用于运行事件循环并执行 main 协程。

3.2 并发执行多个任务

使用 asyncio.gather 可以并发执行多个异步任务,并等待它们全部完成。

示例:

 

python

import asyncio

async def task(name, delay):
    print(f"Task {name} started")
    await asyncio.sleep(delay)
    print(f"Task {name} finished")

async def main():
    # 并发执行多个任务
    await asyncio.gather(
        task("A", 2),
        task("B", 1),
        task("C", 3)
    )

# 运行事件循环
asyncio.run(main())

python

在这个示例中,asyncio.gather 并发执行三个任务,每个任务都有不同的延迟时间。所有任务完成后,main 协程才会结束。

4. 异常处理

在异步编程中,异常处理与同步编程类似,但需要在协程中捕获异常。

示例:

 

python

import asyncio

async def may_fail():
    await asyncio.sleep(1)
    raise ValueError("An error occurred")

async def main():
    try:
        await may_fail()
    except ValueError as e:
        print(f"Caught an exception: {e}")

# 运行事件循环
asyncio.run(main())

python

在这个示例中,may_fail 协程会抛出一个 ValueError 异常,main 协程捕获并处理这个异常。

5. 使用 asyncio 处理 I/O 操作

异步编程在处理 I/O 操作时尤其有用。可以使用异步 I/O 操作来提高程序的性能。

5.1 异步文件读写

示例:

 

python

import aiofiles
import asyncio

async def read_file(file_path):
    async with aiofiles.open(file_path, 'r') as file:
        content = await file.read()
        print(content)

async def main():
    await read_file('example.txt')

# 运行事件循环
asyncio.run(main())

python

在这个示例中,使用 aiofiles 库进行异步文件读写操作。async withawait 关键字使得文件操作变得异步。

安装 aiofiles

 

bash

pip install aiofiles

6. 总结

在这篇文章中,我们介绍了 Python 的异步编程基础,包括 asyncio 模块的使用、协程的定义和执行、异步任务的管理、异常处理以及异步 I/O 操作。掌握异步编程能够显著提高程序的效率,特别是在处理 I/O 密集型任务时。接下来,我们将探讨 Python 的网络编程,了解如何使用 Python 进行网络通信和数据交换。敬请期待下一篇文章!

### Python `asyncio` 异步编程教程 #### 三、定义协程函数 在Python中,可以通过`async def`语句来定义一个协程函数。当调用这样的函数时,它并不会立即执行而是返回一个可以被等待完成的协程对象。 ```python async def my_coroutine(): await asyncio.sleep(1) print("Coroutine executed") ``` 此段代码展示了如何创建简单的协程函数[^4]。 #### 四、使用事件循环运行单个协程 为了启动并运行协程直到其结束,在最基础的情况下可以直接利用`asyncio.run()`方法传递要执行的任务给默认事件循环处理: ```python import asyncio async def say_after(delay, what): await asyncio.sleep(delay) print(what) async def main(): print(f"started at {time.strftime('%X')}") await say_after(1, 'hello') await say_after(2, 'world') print(f"finished at {time.strftime('%X')}") # This line runs the event loop and waits until completion of all coroutines. asyncio.run(main()) ``` 这段程序会依次打印时间戳以及'hello'和'world'[^1]。 #### 五、并发执行多个协程 如果希望同时发起几个独立的操作而不需要等到前一个完成后才开始下一个,则应该考虑采用更高级的方式如通过`gather()`收集所有待办事项作为一组任务一起提交给事件循环去调度它们之间的执行顺序: ```python import asyncio async def factorial(name, number): f = 1 for i in range(2, number + 1): print(f"Task {name}: Compute factorial({i})...") await asyncio.sleep(1) f *= i print(f"Task {name}: factorial({number}) = {f}") async def main(): # Schedule three calls *concurrently*: await asyncio.gather( factorial("A", 2), factorial("B", 3), factorial("C", 4), ) await main() ``` 上述例子说明了怎样让不同名称的任务并行计算阶乘值[^3]。 #### 六、设置超时期限 有时候可能需要限制某个操作的最大允许持续时间;这时就可以借助于`timeout()`辅助工具来做这件事儿——一旦超过指定的时间就会抛出异常终止该过程,并且还可以尝试调整已设定好的时限长度而不必重建整个环境配置. ```python import asyncio async def coroutine1(): await asyncio.sleep(5) print('coroutine1 finished') async def main(): try: async with asyncio.timeout(1): await coroutine1() except TimeoutError as e: print(e) asyncio.run(main()) ``` 这里展示了一个带有超时机制的例子,其中任何未能及时完成的工作都会被捕获为特定类型的错误实例[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值