您的位置:首页 >Ubuntu Python异步编程入门
发布于2026-05-02 阅读(0)
扫一扫,手机访问

想在 Ubuntu 上玩转异步编程,首先得把环境搭好。这里有几个关键步骤:
sudo apt update && sudo apt install -y python3 python3-pipsudo add-apt-repository ppa:deadsnakes/ppasudo apt install -y python3.10 python3.10-venvpython3.10 -m venv .venvsource .venv/bin/activatepip install aiohttp httpx简单说明一下:asyncio 模块从 Python 3.4 开始引入,而我们现在熟悉的 async/await 语法则在 3.5 版本稳定下来。之所以推荐 3.7+,是因为从这个版本开始,提供了像 asyncio.run() 这样更简洁、更友好的程序入口,对新手来说门槛低了不少。
理解了下面几个概念,异步编程的大门就算推开一半了。
async def 定义的函数,它的妙处在于能在等待时主动“让出”控制权。import asyncio
async def say_delay(name, sec):
print(f\"[{name}] start\")
await asyncio.sleep(sec)
print(f\"[{name}] done\")
async def main():
await say_delay(“A”, 1)
await say_delay(“B”, 2)
if __name__ == “__main__”:
asyncio.run(main())
asyncio.create_task 将协程包装成任务,让它们并发跑起来。这样,总耗时就取决于最慢的那个任务,大约2秒。
import asyncio
async def say_delay(name, sec):
print(f\"[{name}] start\")
await asyncio.sleep(sec)
print(f\"[{name}] done\")
async def main():
t1 = asyncio.create_task(say_delay(“A”, 1))
t2 = asyncio.create_task(say_delay(“B”, 2))
await t1; await t2
if __name__ == “__main__”:
asyncio.run(main())
asyncio.run(main()) 作为程序入口;在协程内部,用 await 来等待其他可等待对象;想实现并发,就用 create_task 把协程调度成任务。理论懂了,来点实际的。异步编程最常见的场景之一就是并发处理网络请求。
import asyncio, aiohttp
async def download_site(url, session):
async with session.get(url) as resp:
print(f\"{url} -> {resp.status}\")
async def main():
urls = [“https://example.com”, “https://example.org”]
async with aiohttp.ClientSession() as session:
tasks = [download_site(u, session) for u in urls]
await asyncio.gather(*tasks)
if __name__ == “__main__”:
asyncio.run(main())
pip install httpximport asyncio, httpx
async def fetch(url):
async with httpx.AsyncClient() as client:
r = await client.get(url)
return r.status_code
async def main():
urls = [“https://www.example.com”, “https://www.python.org”, “https://www.github.com”]
results = await asyncio.gather(*[fetch(u) for u in urls])
for u, s in zip(urls, results):
print(u, s)
if __name__ == “__main__”:
asyncio.run(main())
掌握了基本操作,还得了解哪些坑要避开,以及如何写出更健壮的代码。
time.sleep、requests.get 这类会阻塞整个线程的 API。正确的做法是换成 await asyncio.sleep() 和异步 HTTP 客户端(比如 aiohttp 或 httpx)。asyncio.Semaphore 信号量就是你的限流神器。
import asyncio
async def worker(i, sem):
async with sem:
print(f\"worker-{i} working\")
await asyncio.sleep(1)
async def main():
sem = asyncio.Semaphore(5) # 最多同时 5 个
await asyncio.gather(*[worker(i, sem) for i in range(20)])
asyncio.run(main())
asyncio.wait_for 设置超时,并妥善捕获异常。
import asyncio
async def job():
await asyncio.sleep(5)
return “ok”
async def main():
try:
r = await asyncio.wait_for(job(), timeout=2)
print(r)
except asyncio.TimeoutError:
print(“timeout”)
asyncio.run(main())
create_task 创建任务后,务必记得通过 await 或者在 gather 中等待它完成。否则,主协程一旦提前退出,那些还没跑完的任务就会被无情取消。multiprocessing 或者 concurrent.futures.ProcessPoolExecutor。当然,也可以在事件循环里用 run_in_executor,把阻塞函数丢到线程池或进程池里去执行。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
9