禁用GIL,牛刀小试多线程性能

欢迎访问Python3分钟系列。花3分钟时间,学习或温习一个Python知识点。

大家好,我是小K。

国庆终于通关了黑马猴,然后躺了好几天再开机准备第二轮回时发现系统崩了。

图片

遂开始重装系统和一些常用的应用。

图片

当我安装Python3.13时,发现……

图片

“翻译下:下载自由线程二进制文件(实验性的)

这是????什么是自由线程????莫非 GIL真的被解了???

我赶紧去官网看了下Python3.13的文档,确实可以禁用GIL了!!

图片

测试多线程性能

我找了一段测多线程的代码:

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

# Define a decorator to measure function execution time
def time_taken(func):
    """
    A decorator to measure the execution time of a function.
    
    Args:
        func: The target function.
    
    Returns:
        A wrapper function that measures and prints the execution time.
    """
    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"Function {func.__name__!r} took {execution_time:.4f} seconds to execute.")
        return result
    return wrapper

# Define a compute-intensive task function
def compute_intensive_task(num):
    """
    A compute-intensive task that calculates the factorial of a number.
    
    Args:
        num: The input number.
    
    Returns:
        The factorial of the input number.
    """
    #return math.sqrt(num)  # This line is commented out to focus on threading
    return math.factorial(num)

# Define single-threaded task function
@time_taken
def single_threaded_task(nums):
    """
    A single-threaded task that performs compute-intensive tasks sequentially.
    
    Args:
        nums: A list of input numbers.
    """
    for num in nums:
        compute_intensive_task(num)

# Define multi-threaded task function
@time_taken
def multi_threaded_task(nums):
    """
    A multi-threaded task that creates and runs a thread pool to perform 
    compute-intensive tasks concurrently.
    
    Args:
        nums: A list of input numbers.
    """
    threads = []

    # Create len(nums) threads
    for num in nums:
        thread = Thread(target=compute_intensive_task, args=(num,))
        threads.append(thread)
        thread.start()

    # Wait for all threads to complete
    for thread in threads:
        thread.join()

# Define multi-processing task function
@time_taken
def multi_processing_task(nums):
    """
    A multi-processing task that creates and runs a process pool to perform 
    compute-intensive tasks concurrently.
    
    Args:
        nums: A list of input numbers.
    """
    processes = []

    # Create len(nums) processes
    for num in nums:
        process = Process(target=compute_intensive_task, args=(num,))
        processes.append(process)
        process.start()

    # Wait for all processes to complete
    for process in processes:
        process.join()

# Define the main function
def main():
    """
    The main entry point of the program.
    
    It prints the Python version and checks if the GIL is enabled or not.
    Then, it runs single-threaded, multi-threaded, and multi-processing tasks.
    """
    print(f"Python Version: {sys.version}")

    # Check GIL status
    py_version = float(".".join(sys.version.split()[0].split(".")[0: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 version <= 3.12")
    if status == 0:
        print("GIL is currently disabled")
    if status == 1:
        print("GIL is currently active")

    nums = [300001, 300001, 300001, 300001, 300001, 300001]

    # Run single-threaded task
    single_threaded_task(nums)

    # Run multi-threaded task
    multi_threaded_task(nums)

    # Run multi-processing task
    multi_processing_task(nums)

# Call the main function
if __name__ == "__main__":
    main()

我先用Python3.12跑一次看看结果:

E:\Code\Sandbox>python312 demo.py
Python Version: 3.12.4 (tags/v3.12.4:8e8a4ba, Jun  6 2024, 19:30:16) [MSC v.1940 64 bit (AMD64)]
GIL cannot be disabled for Python version <= 3.12
Function 'single_threaded_task' took 4.9194 seconds to execute.
Function 'multi_threaded_task' took 4.6396 seconds to execute.
Function 'multi_processing_task' took 1.0545 seconds to execute.

再用Python3.13普通版跑一次:

E:\Code\Sandbox>python demo.py
Python Version: 3.13.0 (tags/v3.13.0:60403a5, Oct  7 2024, 09:38:07) [MSC v.1941 64 bit (AMD64)]
GIL is currently active
Function 'single_threaded_task' took 4.8312 seconds to execute.
Function 'multi_threaded_task' took 4.6173 seconds to execute.
Function 'multi_processing_task' took 1.0040 seconds to execute.

“从上面的输出,我们看到此时GIL此时并没有被禁用,而还是ACTIVE的状态。运行的结果和Python3.12也是差不多的。图片

最后用禁用GIL版本的Python3.13再试试:

我们需要用到一个新的解释器:python3.13t.exe

图片
E:\Code\Sandbox>python3.13t demo.py
Python Version: 3.13.0 experimental free-threading build (tags/v3.13.0:60403a5, Oct  7 2024, 09:53:29) [MSC v.1941 64 bit (AMD64)]
GIL is currently disabled
Function 'single_threaded_task' took 4.7108 seconds to execute.
Function 'multi_threaded_task' took 0.8713 seconds to execute.
Function 'multi_processing_task' took 0.9935 seconds to execute.

“需要配置Python3.13的安装路径进环境变量。图片

此刻GIL已经被禁用了,多线程的运行速度比之前5倍!!

原文链接:https://www.zsiss.com/9353.html,转载请注明出处。
0

评论0

请先
文章软件下载知识付费网站模板zs31603
文章软件下载知识付费网站模板zs31603
3分钟前 有人购买 去瞅瞅看

社交账号快速登录