gil导致cpu密集型任务无法并行,应使用multiprocessing、numpy等绕过gil;共享变量需加锁或用线程安全结构;asyncio中禁用阻塞调用,须用异步替代或run_in_executor;协程必须正确await;资源须用with或finally清理。

全局解释器锁(GIL)导致 CPU 密集型任务无法真正并行
CPython 解释器的 GIL 保证同一时刻只有一个线程执行 Python 字节码,这对 I/O 密集型任务影响不大,但会让多线程在 CPU 密集型场景下几乎不提速,甚至因线程切换开销而变慢。
解决方法:
- 用 multiprocessing 替代 threading:每个进程有独立 GIL 和内存空间,适合计算密集型任务
- 对可并行的数值计算,优先使用 NumPy、Numba 或 Cython,它们底层绕过 GIL
- 混合场景(如部分计算 + 部分 I/O)可考虑 concurrent.futures.ProcessPoolExecutor + ThreadPoolExecutor 组合使用
共享状态未加锁引发竞态条件
多个线程同时读写同一变量(如字典、列表、计数器),不加同步机制会导致数据错乱。例如,counter += 1 实际包含读取、计算、写入三步,非原子操作。
解决方法:
酷纬企业网站管理系统Kuwebs是酷纬信息开发的为企业网站提供解决方案而开发的营销型网站系统。在线留言模块、常见问题模块、友情链接模块。前台采用DIV+CSS,遵循SEO标准。 1.支持中文、英文两种版本,后台可以在不同的环境下编辑中英文。 3.程序和界面分离,提供通用的PHP标准语法字段供前台调用,可以为不同的页面设置不同的风格。 5.支持google地图生成、自定义标题、自定义关键词、自定义描
立即学习“Python免费学习笔记(深入)”;
- 对简单变量用 threading.Lock 或 threading.RLock 显式加锁
- 优先使用线程安全的数据结构:如 queue.Queue(内置锁)、threading.local()(为每个线程提供独立副本)
- 避免跨线程直接共享可变对象;改用消息传递(如通过 Queue 传递不可变数据)
异步代码中混用阻塞调用导致事件循环卡死
在 asyncio 环境中,调用 time.sleep()、requests.get()、open() 等同步阻塞函数会挂起整个事件循环,使其他协程无法运行。
解决方法:
立即学习“Python免费学习笔记(深入)”;
- 用 asyncio.sleep() 替代
time.sleep() - 网络请求改用 aiohttp、httpx.AsyncClient 等异步库
- 必须调用同步函数时,用 loop.run_in_executor() 将其提交到线程池/进程池执行,不阻塞主循环
忘记 await 或错误地 await 非协程对象
常见错误包括:调用协程函数但没加 await(返回协程对象而非结果)、对普通函数或 None 使用 await(抛出 TypeError)、在非 async 函数里直接 await。
解决方法:
立即学习“Python免费学习笔记(深入)”;
- 明确区分协程函数(
async def定义)与普通函数;调用协程函数必须await - 用 asyncio.create_task() 或 asyncio.gather() 并发调度多个协程,而非逐个 await(避免串行等待)
- 启用类型检查工具(如 mypy +
asyncio插件)或 IDE 提示,提前发现 await 使用错误
资源未正确清理:线程/进程/连接泄漏
忘记关闭线程池、数据库连接、HTTP 会话或异步客户端,可能导致句柄耗尽、内存持续增长或服务端拒绝连接。
解决方法:
立即学习“Python免费学习笔记(深入)”;
- 用 with 语句管理上下文资源:如
with ThreadPoolExecutor() as pool:、async with aiohttp.ClientSession() as session: - 在
try/finally或async with中确保 close()、shutdown()、cancel() 被调用 - 对长期运行的服务,定期检查活跃线程/任务数量(
threading.enumerate()、asyncio.all_tasks()),及时排查泄漏点










