面试题答案
一键面试线程执行
- 同一时刻单线程执行:GIL 使得在 CPython 解释器中,同一时刻只有一个线程能执行 Python 字节码。即便在多核 CPU 环境下,多个线程也无法真正并行执行,只能交替执行。例如,假设有两个线程
thread1
和thread2
,thread1
获得 GIL 开始执行,执行过程中如果没有遇到 I/O 操作或主动释放 GIL 的情况,thread2
只能等待thread1
释放 GIL 后才有机会获取并执行。 - 线程调度:GIL 的存在影响线程调度。Python 解释器会定期检查线程执行的字节码指令数量,当达到一定数量(可通过
sys.getcheckinterval()
获取和设置)后,当前持有 GIL 的线程会释放 GIL,让其他线程有机会竞争获取 GIL 来执行。
资源利用
- CPU 资源:在 CPU 密集型任务中,由于 GIL 的限制,多线程无法充分利用多核 CPU 的优势,导致 CPU 资源不能被完全利用。比如进行复杂的数学运算、科学计算等任务,即使开启多个线程,也只能单线程执行,多核 CPU 的其他核心处于空闲状态。
- I/O 资源:在 I/O 密集型任务中,GIL 对资源利用影响较小。因为当线程执行 I/O 操作(如文件读写、网络请求等)时,会主动释放 GIL,其他线程可以趁机获取 GIL 并执行,所以在 I/O 密集型场景下,多线程能有效利用 I/O 资源,提高程序整体的并发性能。
程序性能
- CPU 密集型任务:性能提升不明显甚至可能下降。由于 GIL 限制了多线程并行执行,多个线程竞争 GIL 会带来额外的开销,包括线程切换、锁竞争等。例如,一个计算斐波那契数列的程序,如果使用多线程,因为 GIL 的存在,相比单线程可能不会有性能提升,反而因为线程调度等开销导致性能降低。
- I/O 密集型任务:性能通常会有显著提升。多线程可以在一个线程进行 I/O 操作时,让其他线程继续执行,从而提高程序的整体效率。例如,在一个需要同时下载多个文件的程序中,使用多线程可以在一个线程等待网络响应时,其他线程继续发起下载请求,加快整体下载速度。