Python中什么时候可以干掉GIL?CPU和IO密集场景下多线程如何利用多核

null
Python中什么时候可以干掉GIL?CPU和IO密集场景下多线程如何利用多核

9 回复

开个 30 的线程池,开销估计都抵不上一个进程


GIL(全局解释器锁)是CPython解释器的历史遗留问题,它确实限制了多线程在CPU密集型任务中的并行能力。不过,在特定场景下,我们可以绕过GIL的限制:

CPU密集型场景: 直接用多线程跑CPU任务确实会被GIL卡住,这时候得换思路:

  • multiprocessing模块创建多个进程,每个进程有自己的Python解释器和内存空间,完全避开GIL
  • 或者用concurrent.futures.ProcessPoolExecutor,用起来更简单
from multiprocessing import Pool
import math

def compute(n):
    return sum(math.sqrt(i) for i in range(n))

if __name__ == '__main__':
    with Pool(processes=4) as pool:
        results = pool.map(compute, [1000000] * 8)
    print(f"Results: {results}")

IO密集型场景: 这种时候多线程其实挺好用的,因为线程在等待IO(网络请求、文件读写)时会释放GIL:

  • 标准库的threading模块就够用了
  • 或者用concurrent.futures.ThreadPoolExecutor,写起来更简洁
  • 现在更推荐用asyncio做异步IO,性能更好
import concurrent.futures
import requests

def fetch_url(url):
    resp = requests.get(url)
    return len(resp.content)

urls = ['http://example.com'] * 10

with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
    results = list(executor.map(fetch_url, urls))
print(f"Fetched {len(results)} pages")

关于干掉GIL: Python核心团队确实在推进无GIL的CPython(PEP 703),3.13已经提供了实验性的无GIL构建选项。但这玩意要默认开启还得等几年,主要是兼容性问题太头疼。现阶段生产环境还是用多进程处理CPU任务更靠谱。

简单说:CPU用多进程,IO用多线程或异步。

有 CPU 密集建议写到 c 里或者换语言
python 太慢不适合

gogogo

多进程走起

多进程啊
要不就换语言呗

www.python.org/dev/peps/pep-0554 参考下这个 PEP 的进度,3.9 会支持多 runtime 的基础模式,按照这个进度,应该是 2-3 个版本可以实现一个进程内的多 runtime 并行执行,也就达到充分利用多核的目的了

www.youtube.com/watch?v=7RlqbHCCVyc

有些 pandas 做的数据分析的脚本,但是里面读库,在 pandas 操作,我如果开多进程的话,占内存,应为 python 多进程不能共享 DataFrame 对象,Manager 不支持 pandas 对象,所以进程不能多开,如果没有 GIL 的话,我开 30 的线程池,不占内存,有快

为啥非得用一种语言解决

回到顶部