搜索
首页后端开发Python教程Python 无需 GIL 即可实现高性能多线程的门户

介绍

Python 长期以来以其易用性和多功能性而闻名,但在 Python 社区中引发大量讨论的一个话题是全局解释器锁 (GIL)。 GIL 既是 Python 并发模型的保障,也是瓶颈,尤其是对于 CPU 密集型任务,否则这些任务可以利用多个 CPU 核心。然而,随着 Python 3.13 的发布,Python 开发人员有了一个突破性的新选项:禁用 GIL 的能力。本博客将探讨 GIL 是什么、为什么它成为多线程性能的障碍,以及如何在 Python 3.13 中检测和禁用 GIL 以释放真正的多线程性能。

什么是全局解释器锁(GIL)

全局解释器锁 (GIL) 是一个互斥锁,用于保护对 Python 对象的访问,防止多个本机线程同时执行 Python 字节码。这保证了Python程序的线程安全,但代价是并发执行。 GIL 使 Python 线程对于 I/O 密集型任务更加高效,但限制了它们对于 CPU 密集型任务的性能。

为什么 GIL 是多线程的瓶颈

Python 的 GIL 只允许一个线程同时执行,即使在多线程程序中也是如此。虽然这对于程序等待输入/输出操作的 I/O 密集型任务来说很好,但它严重限制了 CPU 密集型任务(如数字运算、数据分析或图像处理)的性能。

Python 3.13:在禁用 GIL 的情况下解锁多线程

使用 Python 3.13,开发人员可以选择在 Python 构建过程中禁用 GIL。但是,在预构建的 Python 发行版中无法禁用 GIL。相反,您必须使用 --disable-gil 选项从源代码编译 Python 3.13。

这个新选项为 CPU 密集型多线程任务中的真正并行性打开了大门,允许线程跨多个内核并行执行。

使用不带 GIL 的 Python 3.13 的先决条件

  • Python 3.13 源代码: 标准预构建二进制文件中不支持禁用 GIL。您必须使用 --disable-gil 标志从源代码构建 Python 3.13。
  • 多核 CPU: 您需要多核 CPU 才能从真正的多线程中受益,因为线程现在将跨多个内核并行运行。

在禁用 GIL 的情况下编译 Python 3.13

要使用 -X gil=0 标志禁用 GIL,您需要在启用 --disable-gil 标志的情况下从源代码编译 Python。具体方法如下

一步一步

  • 下载Python 3.13源代码 您首先需要从 Python 官方网站下载 Python 3.13 源代码 tarball。这是因为预构建的二进制文件(例如直接从 python.org 下载的二进制文件)未编译为支持禁用 GIL。您可以使用网络浏览器或使用 wget 甚至在终端中使用 curl 下载它
wget https://www.python.org/ftp/python/3.13.0/Python-3.13.0.tgz
  • 提取来源:
tar -xf Python-3.13.0.tgz
cd Python-3.13.0
  • 使用 --disable-gil 配置构建 您需要使用 --disable-gil 配置 Python 以支持禁用 GIL 的选项。
./configure --disable-gil
  • 编译并安装Python:
make
sudo make altinstall 
  • 如果 altinstall 步骤失败,则使用 --prefix 重新运行配置命令
./configure --disable-gil --prefix=$HOME/python3.13
  • 在指定目录下运行make altinstall 然后,运行 make altinstall 命令
make altinstall

如何在 Python 3.13 中检测 GIL

在Python 3.13中,您可以使用sys._is_gil_enabled()函数检查GIL是否启用或禁用。

import sys

def check_gil_status():
    if sys.version_info >= (3, 13):
        status = sys._is_gil_enabled()
        if status:
            print("GIL is currently enabled.")
        else:
            print("GIL is currently disabled.")
    else:
        print("Python version does not support GIL status detection.")

check_gil_status()

实践:使用 GIL 的 Python 多线程与无 GIL 的比较

开发以下 Python 代码是为了评估在 Python 3.13 中禁用 GIL 时的性能增益。该脚本同时执行八个线程,每个线程的任务是计算大数的素因数。通过利用真正的并行性,代码突出了无需 GIL 即可实现的增强性能。

#!/usr/bin/env python3
import sys
import sysconfig
import time
from threading import Thread
from multiprocessing import Process


# Decorator to measure execution time of functions
def calculate_execution_time(func):
    def wrapper(*args, **kwargs):
        start_time = time.perf_counter()
        result = func(*args, **kwargs)
        end_time = time.perf_counter()
        execution_time = end_time - start_time
        print(f"{func.__name__} took {execution_time:.4f} seconds.")
        return result

    return wrapper


# Compute-intensive task: Iterative Fibonacci calculation
def compute_fibonacci(n):
    """Compute Fibonacci number for a given n iteratively."""
    a, b = 0, 1
    for _ in range(n):
        a, b = b, a + b
    return a


# Single-threaded task execution
@calculate_execution_time
def run_single_threaded(nums):
    for num in nums:
        compute_fibonacci(num)


# Multi-threaded task execution
@calculate_execution_time
def run_multi_threaded(nums):
    threads = [Thread(target=compute_fibonacci, args=(num,)) for num in nums]
    for thread in threads:
        thread.start()
    for thread in threads:
        thread.join()


# Multi-processing task execution
@calculate_execution_time
def run_multi_processing(nums):
    processes = [Process(target=compute_fibonacci, args=(num,)) for num in nums]
    for process in processes:
        process.start()
    for process in processes:
        process.join()


# Main execution function
def main():
    # Check Python version and GIL status for Python 3.13+
    print(f"Python Version: {sys.version}")

    py_version = float(".".join(sys.version.split()[0].split(".")[:2]))
    status = sysconfig.get_config_var("Py_GIL_DISABLED")

    if py_version >= 3.13:
        status = sys._is_gil_enabled()

    if status is None:
        print("GIL cannot be disabled for Python 



<h2>
  
  
  分析:
</h2>



<pre class="brush:php;toolbar:false">## Python 3.13 with GIL Disabled
Python Version: 3.13.0 experimental free-threading build (main, Oct 14 2024, 17:09:28) [Clang 14.0.0 (clang-1400.0.29.202)]
GIL is currently disabled

Running Single-Threaded Task:
run_single_threaded took 8.6587 seconds.

Running Multi-Threaded Task:
run_multi_threaded took 1.3885 seconds.

Running Multi-Processing Task:
run_multi_processing took 1.5953 seconds.

## Python 3.13 with GIL Enabled
Python Version: 3.13.0 experimental free-threading build (main, Oct 14 2024, 17:09:28) [Clang 14.0.0 (clang-1400.0.29.202)]
GIL is currently active

Running Single-Threaded Task:
run_single_threaded took 8.7108 seconds.

Running Multi-Threaded Task:
run_multi_threaded took 8.6645 seconds.

Running Multi-Processing Task:
run_multi_processing took 1.4530 seconds.

## Python 3.12 
Python Version: 3.12.6 (main, Sep  7 2024, 19:30:10) [Clang 14.0.0 (clang-1400.0.29.202)]
GIL cannot be disabled for Python 



<p><strong>多线程性能:</strong>禁用 GIL 的真正好处在多线程场景中是显而易见的:</p>

<p>禁用 GIL (3.13) 时,执行时间为 1.5703 秒。<br>
启用 GIL 后(3.13),执行时间为 8.5901 秒。<br>
结果:禁用 GIL 使多线程任务的性能提高了约 81.7%。</p>

<p><img src="/static/imghwm/default1.png" data-src="https://img.php.cn/upload/article/000/000/000/173615392355601.jpg?x-oss-process=image/resize,p_40" class="lazy" alt="Python The Gateway to High-Performance Multithreading Without GIL"></p>

<p><img src="/static/imghwm/default1.png" data-src="https://img.php.cn/upload/article/000/000/000/173615392486147.jpg?x-oss-process=image/resize,p_40" class="lazy" alt="Python The Gateway to High-Performance Multithreading Without GIL"></p>

<p>该图表清楚地表明,在 Python 3.13 中禁用 GIL 可以显着提升多线程 CPU 密集型任务的性能,从而使 Python 能够高效地并行利用多个 CPU 核心。虽然单线程和多处理性能基本上不受影响,但多线程性能显示出显着改进,使 Python 3.13 成为依赖多线程的 CPU 密集型应用程序的游戏规则改变者。</p><p>但是,3.13之前的Python版本不支持禁用GIL,这也解释了为什么它们的多线程性能仍然与启用GIL的Python 3.13相似。早期版本中的这一限制继续限制 Python 充分利用多线程处理 CPU 密集型任务的能力。</p>

<h2>
  
  
  禁用 GIL 之前的主要注意事项
</h2>

<p>在 Python 3.13 中禁用全局解释器锁 (GIL) 可以显着提高多线程 CPU 密集型任务的性能。但是,在此之前需要考虑几个重要因素:</p>

  • 线程安全:如果没有 GIL,您必须使用锁或其他同步机制手动处理线程安全,以防止代码中的竞争条件。

  • 潜在的性能下降:细粒度锁定可能会引入争用,这可能会降低以前受益于 GIL 的单线程或 I/O 密集型任务的性能。

  • 与第三方库的兼容性:许多 C 扩展和库假设存在 GIL 以保证线程安全。禁用 GIL 可能需要更新这些库,以确保它们在多线程环境中正常工作。

  • 复杂的内存管理:禁用 GIL 会增加内存管理的复杂性,需要线程安全的内存处理,这会增加错误和错误的风险。

  • I/O 密集型任务: 禁用 GIL 为 I/O 密集型任务带来的好处有限,在这些任务中,像 asyncio 这样的非阻塞 I/O 机制可能更有效。

  • 调试困难:如果没有 GIL,由于竞争条件和死锁的可能性增加,调试多线程应用程序可能会变得更具挑战性。

  • 更高的内存使用量: 在没有 GIL 的情况下使用锁和管理线程状态会增加内存消耗,特别是在多线程应用程序中。

  • 嵌入式系统:禁用 GIL 可能会使 Python 与嵌入式系统中的多线程环境的集成变得复杂,需要付出更多努力才能有效集成。

  • 锁争用:在某些情况下,禁用 GIL 可能会导致线程之间出现锁争用,这可能会降低预期的性能改进。

GitHub 存储库

您可以在我的 GitHub 上找到此博客中示例的完整源代码:

Python GIL 性能分析

免责声明:

这是一个个人博客。本文表达的观点和意见仅代表作者的观点和意见,并不代表与作者有关​​联的任何组织或个人的专业或个人观点。

以上是Python 无需 GIL 即可实现高性能多线程的门户的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
python中两个列表的串联替代方案是什么?python中两个列表的串联替代方案是什么?May 09, 2025 am 12:16 AM

可以使用多种方法在Python中连接两个列表:1.使用 操作符,简单但在大列表中效率低;2.使用extend方法,效率高但会修改原列表;3.使用 =操作符,兼具效率和可读性;4.使用itertools.chain函数,内存效率高但需额外导入;5.使用列表解析,优雅但可能过于复杂。选择方法应根据代码上下文和需求。

Python:合并两个列表的有效方法Python:合并两个列表的有效方法May 09, 2025 am 12:15 AM

有多种方法可以合并Python列表:1.使用 操作符,简单但对大列表不内存高效;2.使用extend方法,内存高效但会修改原列表;3.使用itertools.chain,适用于大数据集;4.使用*操作符,一行代码合并小到中型列表;5.使用numpy.concatenate,适用于大数据集和性能要求高的场景;6.使用append方法,适用于小列表但效率低。选择方法时需考虑列表大小和应用场景。

编译的与解释的语言:优点和缺点编译的与解释的语言:优点和缺点May 09, 2025 am 12:06 AM

CompiledLanguagesOffersPeedAndSecurity,而interneterpretledlanguages provideeaseafuseanDoctability.1)commiledlanguageslikec arefasterandSecureButhOnderDevevelmendeclementCyclesclesclesclesclesclesclesclesclesclesclesclesclesclesclesclesclesclesandentency.2)cransportedeplatectentysenty

Python:对于循环,最完整的指南Python:对于循环,最完整的指南May 09, 2025 am 12:05 AM

Python中,for循环用于遍历可迭代对象,while循环用于条件满足时重复执行操作。1)for循环示例:遍历列表并打印元素。2)while循环示例:猜数字游戏,直到猜对为止。掌握循环原理和优化技巧可提高代码效率和可靠性。

python concatenate列表到一个字符串中python concatenate列表到一个字符串中May 09, 2025 am 12:02 AM

要将列表连接成字符串,Python中使用join()方法是最佳选择。1)使用join()方法将列表元素连接成字符串,如''.join(my_list)。2)对于包含数字的列表,先用map(str,numbers)转换为字符串再连接。3)可以使用生成器表达式进行复杂格式化,如','.join(f'({fruit})'forfruitinfruits)。4)处理混合数据类型时,使用map(str,mixed_list)确保所有元素可转换为字符串。5)对于大型列表,使用''.join(large_li

Python的混合方法:编译和解释合并Python的混合方法:编译和解释合并May 08, 2025 am 12:16 AM

pythonuseshybridapprace,ComminingCompilationTobyTecoDeAndInterpretation.1)codeiscompiledtoplatform-Indepententbybytecode.2)bytecodeisisterpretedbybythepbybythepythonvirtualmachine,增强效率和通用性。

了解python的' for”和' then”循环之间的差异了解python的' for”和' then”循环之间的差异May 08, 2025 am 12:11 AM

theKeyDifferencesBetnewpython's“ for”和“ for”和“ loopsare:1)” for“ loopsareIdealForiteringSequenceSquencesSorkNowniterations,而2)”,而“ loopsareBetterforConterContinuingUntilacTientInditionIntionismetismetistismetistwithOutpredefinedInedIterations.un

Python串联列表与重复Python串联列表与重复May 08, 2025 am 12:09 AM

在Python中,可以通过多种方法连接列表并管理重复元素:1)使用 运算符或extend()方法可以保留所有重复元素;2)转换为集合再转回列表可以去除所有重复元素,但会丢失原有顺序;3)使用循环或列表推导式结合集合可以去除重复元素并保持原有顺序。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

MinGW - 适用于 Windows 的极简 GNU

MinGW - 适用于 Windows 的极简 GNU

这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

WebStorm Mac版

WebStorm Mac版

好用的JavaScript开发工具