MST

星途 面试题库

面试题:Python中GIL对多线程编程的影响

请简要阐述Python的GIL(全局解释器锁)是什么,以及它如何影响多线程编程,在多线程环境下,如果要进行CPU密集型任务,你会如何解决GIL带来的限制?
27.6万 热度难度
编程语言Python

知识考点

AI 面试

面试题答案

一键面试

1. GIL 是什么

  • 定义:GIL(Global Interpreter Lock)即全局解释器锁,是 CPython 解释器中的一个互斥锁。它确保在任何时刻,只有一个线程能在解释器中执行 Python 字节码。这意味着,即使在多核 CPU 环境下,Python 多线程也无法真正利用多核优势并行执行多个线程的字节码。

2. GIL 对多线程编程的影响

  • CPU 密集型任务:对于 CPU 密集型任务,由于 GIL 的存在,多线程并不能有效提升性能,因为线程间频繁切换会带来额外开销,且同一时间只有一个线程能执行 CPU 操作,无法利用多核并行计算,整体效率可能反而不如单线程。
  • I/O 密集型任务:在 I/O 密集型任务中,线程在等待 I/O 操作完成时会释放 GIL,其他线程可以获取 GIL 并执行,因此多线程能有效利用等待 I/O 的时间,提升程序整体效率。

3. 解决 GIL 限制的方法(针对 CPU 密集型任务)

  • 多进程:使用 multiprocessing 模块创建多个进程。每个进程有自己独立的 Python 解释器和内存空间,不存在 GIL 限制,能充分利用多核 CPU 资源。例如:
import multiprocessing


def cpu_bound_task():
    result = 0
    for i in range(100000000):
        result += i
    return result


if __name__ == '__main__':
    with multiprocessing.Pool(processes=multiprocessing.cpu_count()) as pool:
        results = pool.map(cpu_bound_task, range(4))
    print(results)
  • C 扩展:将 CPU 密集型部分代码用 C 语言编写,并通过 Cython 或 SWIG 等工具集成到 Python 中。C 代码不受 GIL 限制,可在多核上并行执行。例如使用 Cython 时,先编写 .pyx 文件实现功能,再编写 setup.py 用于编译生成 C 扩展模块。
# example.pyx
def cpu_bound_function():
    cdef int i, result = 0
    for i in range(100000000):
        result += i
    return result
# setup.py
from setuptools import setup
from Cython.Build import cythonize


setup(
    ext_modules = cythonize("example.pyx")
)

然后通过 python setup.py build_ext --inplace 编译,就可以在 Python 中导入使用。