面试题答案
一键面试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 中导入使用。