Python 并发编程入门:线程、asyncio 与适用场景

举报
yd_269685704 发表于 2026/10/30 10:13:50 2026/10/30
【摘要】 为什么需要并发 写爬虫、批量请求接口、读写文件时,程序常常不是在计算,而是在“等”。等网络响应、等磁盘读写。单线程顺序执行时,这些等待时间都被白白浪费。并发就是让程序在等待的时候去做别的事,从而缩短总耗时。Python 里最常用的两种并发方式是 threading(线程)和 asyncio(异步),它们各有适用场景。线程:适合 I/O 密集任务threading 让多个线程在同一个进程里交替...

为什么需要并发

 写爬虫、批量请求接口、读写文件时,程序常常不是在计算,而是在“等”。等网络响应、等磁盘读写。单线程顺序执行时,这些等待时间都被白白浪费。并发就是让程序在等待的时候去做别的事,从而缩短总耗时。Python 里最常用的两种并发方式是 threading(线程)和 asyncio(异步),它们各有适用场景。

线程:适合 I/O 密集任务

threading 让多个线程在同一个进程里交替运行。遇到网络请求这类 I/O 操作时,线程会主动让出执行权,另一个线程继续干活。下面是一个用线程并发下载的示意:

import threading
import requests

urls = ["https://example.com/a", "https://example.com/b", "https://example.com/c"]

def fetch(url):
    r = requests.get(url, timeout=10)
    print(url, r.status_code)

threads = [threading.Thread(target=fetch, args=(u,)) for u in urls]
for t in threads:
    t.start()
for t in threads:
    t.join()

线程的优点是写法直观,和同步代码几乎一样;缺点是线程切换有开销,线程数上千后就不划算,而且多个线程共享内存时要小心竞态条件,必要时用 Lock 保护共享数据。

asyncio:单线程里的协作式并发

asyncio 用一个事件循环驱动多个协程。协程在 await 处主动挂起,事件循环趁机运行别的协程,全程只有一个线程,没有线程切换开销,也没有数据竞争。适合高并发 I/O 场景:

import asyncio
import aiohttp

async def fetch(session, url):
    async with session.get(url, timeout=10) as resp:
        return url, resp.status

async def main():
    urls = ["https://example.com/a", "https://example.com/b", "https://example.com/c"]
    async with aiohttp.ClientSession() as session:
        results = await asyncio.gather(*(fetch(session, u) for u in urls))
    print(results)

asyncio.run(main())

怎么选

可以按下面这张表做初步判断:

  • 任务量不大、代码简单:threading,上手成本最低。
  • 成百上千个并发 I/O:asyncio,资源占用更小。
  • CPU 密集计算:两者都不合适,考虑 multiprocessing,或者把计算部分交给扩展库。
  • 已有大量同步代码要改造:先用线程池(concurrent.futures)过渡,再逐步迁移。

几个常见坑

第一,GIL 的存在意味着同一时刻只有一个线程在执行 Python 字节码,线程并不能让纯计算加速。第二,不要在 asyncio 协程里调用 time.sleep、requests 这类阻塞函数,它们会卡住整个事件循环,应该用 asyncio.sleep 和支持异步的库。第三,并发数不是越多越好,对方服务器和本地带宽都有上限,配合信号量(asyncio.Semaphore)做限流更稳妥。

小结

并发不是银弹,先分清任务是 I/O 密集还是 CPU 密集,再选工具。I/O 密集的小规模任务用 threading,大规模 I/O 用 asyncio,计算密集用多进程。理解了这层取舍,写并发代码时就很少会选错方向。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。