协程,单线程的,事件循环 (Event Loop):asyncio 内部有一个死循环。它不断检查任务列表
- “煮饭协程还在等吗?” —— 是的,还在等。
- “洗菜协程准备好了吗?” —— 准备好了。
- “OK,那我现在把 CPU 给洗菜协程。”
async、await 关键字
async def:定义一个“协程函数”。调用它不会立即执行,而是返回一个“协程对象”。
await:告诉程序:“这里有 IO 等待,你可以先去忙别的,等这里有结果了再切回来”。
asyncio.run():启动指挥中心(事件循环),运行最外层的协程。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| import asyncio import time
async def task(name, duration): print(f"任务 {name} 开始...") await asyncio.sleep(duration) print(f"任务 {name} 完成!")
async def main(): await asyncio.gather( task("煮饭", 2), task("洗菜", 1) )
if __name__ == "__main__": start = time.time() asyncio.run(main()) print(f"总耗时: {time.time() - start:.2f}s")
|
示例:异步实现高性能扫描器 aiohttp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| import asyncio import aiohttp import time
async def check_site_async(session, url): """ 具体的异步请求逻辑 """ print(f"[*] 正在异步请求: {url}") try: async with session.get(url, timeout=5) as response: status = response.status print(f"[+] {url} 状态码: {status}") return status except Exception as e: return f"Error: {e}"
async def main(): urls = [ "https://www.google.com", "https://www.github.com", "https://www.baidu.com" ]
async with aiohttp.ClientSession() as session: tasks = [] for url in urls: tasks.append(check_site_async(session, url)) await asyncio.gather(*tasks)
if __name__ == "__main__": start = time.time() asyncio.run(main()) print(f"\n[异步模式] 总耗时: {time.time() - start:.2f}秒")
|