Python 的线程是怎么实现的?并发差在哪里?

线程是虚拟的还是调用系统 api,进入 os 调度队列的?

都说 python 并发差,全局解释锁什么的,multiprocessing 库是否调用了系统 API,进程有木有进入 os 调度队列?到底差在哪里?


Python 的线程是怎么实现的?并发差在哪里?
6 回复

GIL 是保证每一个时间内 CPython 只有一个线程在运行,你看 Java 需要关心集合什么的是不是线程安全的,用 CPython 基本可以不管,因为 CPython 同时运行的线程只有一个。

所以 CPython 的线程没有真正的并行执行,例如要用 4 个 CPU 执行计算任务,用 CPython 的线程是不可能的。

最近翻的一本书有一节讲了 GIL 的瓶颈: http://python-parallel-programmning-cookbook.readthedocs.io/zh_CN/latest/chapter2/13_Evaluating_the_performance_of_multithread_applications.html


Python的线程是通过操作系统原生线程(POSIX线程或Windows线程)实现的,但受全局解释器锁(GIL)限制,导致CPU密集型任务并发效果差。

实现原理
Python调用操作系统线程API创建线程,所有线程共享同一进程内存空间。但由于GIL的存在,任意时刻只有一个线程能执行Python字节码。

并发差的根本原因
GIL是线程安全的代价。CPU密集型任务中,线程会频繁争抢GIL,导致多线程实际上串行执行,无法利用多核优势。I/O密集型任务受影响较小,因为I/O等待期间会释放GIL。

简单示例

import threading
import time

def cpu_task():
    sum = 0
    for i in range(10000000):
        sum += i

# 单线程执行
start = time.time()
cpu_task()
cpu_task()
print(f"单线程耗时: {time.time()-start:.2f}s")

# 多线程执行
start = time.time()
t1 = threading.Thread(target=cpu_task)
t2 = threading.Thread(target=cpu_task)
t1.start(); t2.start()
t1.join(); t2.join()
print(f"双线程耗时: {time.time()-start:.2f}s")  # 可能比单线程更慢

替代方案

  • CPU密集型:用multiprocessing模块绕过GIL
  • 高并发I/O:用asyncio协程
  • 混合场景:结合进程池+线程池/协程

总结:GIL让Python线程在CPU任务中成了“伪并发”。

#1
第一段的“ GIL 在解释器层面组织了真正的并行运行”,“组织”应为“阻止”吧

是的 谢谢

谢谢!看了下 python 的线程应该是模拟的,threadmodule.c 中没有调用系统线程接口。书不错

不要瞎说

回到顶部