什么是 asyncio
?
asyncio
是 Python 的一个异步 I/O 框架,用于编写并发代码,使用协程、任务和事件循环等概念。它允许你编写非阻塞的 I/O 操作,从而提高程序的性能。
为什么需要 asyncio
?
在处理 I/O 密集型任务时,传统的同步代码会因为等待 I/O 操作而阻塞,导致资源浪费。asyncio
通过异步编程模型,使得多个任务可以并发执行,提高程序的效率和响应速度。
基本概念
1. **协程 (Coroutine)**:协程是一种特殊的函数,可以暂停执行并在稍后恢复。在 Python 中,协程是通过 async def
定义的。
2. **事件循环 (Event Loop)**:事件循环是 asyncio
的核心,负责管理和调度任务。你可以通过 asyncio.run()
启动事件循环。
3. **任务 (Task)**:任务是 asyncio
中的可等待对象,代表一个正在运行的协程。任务可以被挂起和恢复。
示例 1:简单的协程
import asyncio
async def say_hello():
print("Hello, world!")
# 启动事件循环并运行协程
asyncio.run(say_hello())
输出结果:
Hello, world!
示例 2:并发执行多个协程
import asyncio
async def count(number):
print(f"Counting {number}")
await asyncio.sleep(1) # 模拟 I/O 操作
print(f"Finished counting {number}")
async def main():
tasks = [count(i) for i in range(5)]
await asyncio.gather(*tasks) # 并发执行所有任务
asyncio.run(main())
输出结果:
Counting 0
Counting 1
Counting 2
Counting 3
Counting 4
Finished counting 0
Finished counting 1
Finished counting 2
Finished counting 3
Finished counting 4
示例 3:使用 async with
和 async for
import asyncio
class AsyncCounter:
def __init__(self, limit):
self.limit = limit
async def __aenter__(self):
print("Starting counter")
return self
async def __aexit__(self, exc_type, exc_val, exc_tb):
print("Stopping counter")
async def __aiter__(self):
self.n = 0
return self
async def __anext__(self):
if self.n < self.limit:
current = self.n
self.n += 1
await asyncio.sleep(0.5) # 模拟 I/O 操作
return current
else:
raise StopAsyncIteration
async def main():
async with AsyncCounter(3) as counter:
async for num in counter:
print(f"Counting: {num}")
asyncio.run(main())
输出结果:
Starting counter
Counting: 0
Counting: 1
Counting: 2
Stopping counter
高级概念
1. 取消任务
import asyncio
async def long_running_task():
try:
while True:
print("Task is running")
await asyncio.sleep(1)
except asyncio.CancelledError:
print("Task was cancelled")
async def main():
task = asyncio.create_task(long_running_task())
await asyncio.sleep(3)
task.cancel()
try:
await task
except asyncio.CancelledError:
print("Task was cancelled")
asyncio.run(main())
输出结果:
Task is running
Task is running
Task is running
Task was cancelled
Task was cancelled
2. 超时
import asyncio
async def long_running_task():
await asyncio.sleep(10)
print("Task completed")
async def main():
try:
await asyncio.wait_for(long_running_task(), timeout=5)
except asyncio.TimeoutError:
print("Task timed out")
asyncio.run(main())
输出结果:
Task timed out
实战案例:并发请求多个网页
假设我们需要同时请求多个网页,可以使用 aiohttp
库来实现。
import asyncio
import aiohttp
async def fetch(session, url):
async with session.get(url) as response:
return await response.text()
async def main():
urls = [
"https://example.com",
"https://python.org",
"https://github.com"
]
async with aiohttp.ClientSession() as session:
tasks = [fetch(session, url) for url in urls]
results = await asyncio.gather(*tasks)
for i, result in enumerate(results):
print(f"Response from {urls[i]}: {len(result)} bytes")
asyncio.run(main())
输出结果(示例):
Response from https://example.com: 1256 bytes
Response from https://python.org: 45678 bytes
Response from https://github.com: 34567 bytes
总结
本文介绍了 Python 中的 asyncio
模块,包括基本概念、简单示例、高级概念以及一个实战案例。
好了,今天的分享就到这里了,我们下期见。如果本文对你有帮助,请动动你可爱的小手指点赞、转发、在看吧!
付费合集推荐
文末福利
公众号消息窗口回复“编程资料”,获取Python编程、人工智能、爬虫等100+本精品电子书。