最新版Python 3.13: 尝试解锁GIL限制,迈向真正的多线程并发!

文摘   2024-11-27 11:02   湖南  

最新Python 3.13带来了令人兴奋的突破:实验性的无GIL版本,让我们一窥Python并发编程的新未来!


什么是GIL?为什么它限制了Python的多线程性能?

全局解释器锁(GIL)是CPython解释器中的一种机制,它确保在任何时候只有一个线程能够持有控制权并执行Python字节码。这意味着即使在多核处理器上,多线程Python程序也无法真正实现并行执行,只有一个线程能够在CPU核心上运行,其他线程必须等待。这限制了Python在多线程场景下的性能提升,尤其是在CPU密集型任务中。

Python 3.13的无GIL构建:开启并发新篇章

Python 3.13引入了实验性的“free-threaded”构建,它允许禁用GIL。这意味着多个线程可以同时在多个CPU核心上执行Python字节码,从而充分利用多核处理器的优势。这对于CPU密集型任务来说是一个巨大的进步,可以显著提高程序的运行速度。

如何启用和使用无GIL的Python?

启用无GIL的Python需要一些额外的步骤:

  • • 特殊构建: 你需要下载一个特殊的Python 3.13二进制文件,通常命名为python3.13tpython3.13t.exe。Windows和macOS的官方安装程序中包含了这个选项,或者你可以从源码编译,使用--disable-gil选项。

  • • 运行时选项: 你可以通过环境变量PYTHON_GIL或命令行选项-X gil=0来禁用或启用GIL。-X gil=1则表示启用GIL。

  • • 检查支持: 运行python -VV 或检查 sys.version 是否包含 "experimental free-threading build" 来确认你的解释器是否支持无GIL模式。可以使用 sys._is_gil_enabled() 函数来检查GIL是否已禁用。

  • • C扩展模块兼容性: 如果你的程序使用了C扩展模块,则这些模块需要进行修改以支持无GIL模式。这需要使用 Py_mod_gil slot 或 PyUnstable_Module_SetGIL() 函数。使用pip 24.1 或更新的版本安装包。

示例:对比有GIL和无GIL的性能差异

让我们用一个简单的例子来演示GIL的影响。以下代码计算前100000个数字的平方和,分别使用单线程、多线程(有GIL)和多线程(无GIL)三种方式实现:

import threading
import time
import sys
import os

defsquare_sum(start, end, result_list):
    total =0
for i inrange(start, end):
        total += i * i
    result_list.append(total)

if __name__ =="__main__":
    num_threads =4
    chunk_size =100000// num_threads
    results =[]
    threads =[]

# Single-threaded
    start_time = time.time()
    single_total =0
for i inrange(100000):
      single_total += i*i
    end_time = time.time()
print(f"Single-threaded time: {end_time - start_time:.4f} seconds")

# Multi-threaded with GIL
    start_time = time.time()
for i inrange(num_threads):
        start = i * chunk_size
        end =(i +1)* chunk_size
        thread = threading.Thread(target=square_sum, args=(start, end, results))
        threads.append(thread)
        thread.start()
for thread in threads:
        thread.join()
    end_time = time.time()
print(f"Multi-threaded (with GIL) time: {end_time - start_time:.4f} seconds")
print(f"Sum (with GIL): {sum(results)}")


if sys._is_gil_enabled():
print("GIL is enabled.")
else:
print("GIL is disabled.")

在多核处理器上运行,你会发现无GIL的多线程版本比有GIL的多线程版本显著更快,接近于单线程的4倍。当然,实际的性能提升会受到很多因素的影响,例如任务的类型、硬件配置等等。

已知限制及未来展望

虽然无GIL的Python带来了性能提升的可能性,但目前它仍然是一个实验性功能,存在一些已知的限制:

  • • 单线程性能下降: 禁用GIL会带来一定的单线程性能开销。

  • • 内存使用增加: 为了避免竞争,一些对象会被“immortalize”(永生化),导致内存使用增加。

  • • 线程安全问题: 需要小心处理线程安全问题,例如共享迭代器。

  • • C扩展兼容性: 需要修改C扩展模块以支持无GIL模式。

Python社区正在积极努力改进无GIL的Python,未来的版本有望解决这些限制,带来更稳定和高效的并发编程体验。

结论

Python 3.13的无GIL构建是Python并发编程领域的一项重大进展。虽然目前还处于实验阶段,但它为Python开发者提供了充分利用多核处理器性能的可能性,为未来Python在高性能计算领域的应用开辟了新的道路。让我们拭目以待,见证Python在并发编程领域的飞跃!


小白这样学Python
专注Python编程开发知识分享!
 最新文章