GIL станет необязательным в Python 3.13
GIL (он же Global Interpreter Lock) может быть отключен в Python версии 3.13. Пока эта возможность является экспериментальной.
Кто такой этот GIL? Это механизм, используемый интерпретатором CPython для обеспечения выполнения байткода Python одновременно только одним потоком.
Экспериментальная функция
В Python 3.13 среди прочих нововведений привнесёт режим свободных потоков, который отключает глобальную блокировку интерпретатора, позволяя потокам работать параллельно.
Это экспериментальная функция, и если вы хотите попробовать ее, вы можете скачать бета-версию Python 3.13 здесь. А во время установки отметьте опцию «free threaded binaries(experimental)».
Отключение GIL в Python 3.13
GIL будет отключен, если сконфигурировать Python с параметром --disable-gil
. Это позволит опционально включать и отключать GIL с помощью переменной окружения PYTHON_GIL
, которая может быть установлена в значения 1 и 0 соответственно.
Также будет доступна опция командной строки -X gil
, которая может быть установлена в 0 (отключен) и 1 (включен).
# v3.13 # GI отключен python3 -X gil=0 sample.py # GIL включен python3 -X gil=1 sample.py
Проверить, активированы ли в текущем интерпретаторе свободные потоки (--disable-gil
) можно так:
import sysconfig print(sysconfig.get_config_var("Py_GIL_DISABLED"))
Мы получим либо 0 (GIL включен), либо 1 (GIL отключен).
GIL Vs No GIL
Давайте посмотрим, как повлияет на производительность многопоточных программ включение и отключение GIL.
Есть простой скрипт (gil.py
), который вычисляет факториал числа и сравнивает время выполнения в однопоточном, многопоточном и многопроцессорном режимах. Запустим этот скрипт сначала с GIL, а затем без GIL.
import sys import sysconfig import math import time import threading import multiprocessing def compute_factorial(n): return math.factorial(n) # Однопоточное исполнение def single_threaded_compute(n): for num in n: compute_factorial(num) print("Факториал вычислен в один поток.") # Многопоточное исполннение def multi_threaded_compute(n): threads = [] # Создаем 5 потоков for num in n: thread = threading.Thread(target=compute_factorial, args=(num,)) threads.append(thread) thread.start() # Ждём исполнения всех потоков for thread in threads: thread.join() print("Факториал вычислен в 5 потоков") # Мультипроцессорное исполнение def multi_processing_compute(n): processes = [] # Создаём процесс для каждого числа for num in n: process = multiprocessing.Process(target=compute_factorial, args=(num,)) processes.append(process) process.start() # Ожидаем исполнение всех процессов for process in processes: process.join() print("Факториал вычислен в мультипроцессорном режиме.") def main(): # Проверяем версию print(f"Версия Python: {sys.version}") # GIL Status status = sysconfig.get_config_var("Py_GIL_DISABLED") if status is None: print("GIL не может быть отключен") if status == 0: print("GIL включен") if status == 1: print("GIL отключен") numlist = [100000, 200000, 300000, 400000, 500000] # Однопоточное исполнение start = time.time() single_threaded_compute(numlist) end = time.time() - start print(f"Время исполнения в один поток: {end:.2f} секунд") # Многопоточное исполнение start = time.time() multi_threaded_compute(numlist) end = time.time() - start print(f"Многопоточное время исполнения: {end:.2f} секунд") # Мультипроцессорное исполнение start = time.time() multi_processing_compute(numlist) end = time.time() - start print(f"Мультипроцессорное время исполнения: {end:.2f} секунд") if __name__ == "__main__": main()
Running gil.py
with GIL
Версия Python: 3.13.0b3 experimental free-threading build (tags/v3.13.0b3:7b41395, Jun 27 2024, 16:17:17) [MSC v.1940 64 bit (AMD64)] GIL отключен Факториал вычислен в один поток. Время исполнения в один поток: 9.28 секунд Факториал вычислен в 5 потоков Многопоточное время исполнения: 4.86 секунд Факториал вычислен в мультипроцессорном режиме. Мультипроцессорное время исполнения: 6.14 секунд
Здесь у нас третья бета-версия Python 3.13 с активированными свободными потоками, и, как мы видим, GIL отключен.
Но самое главное - мы видим значительную разницу в производительности в многопоточных задачах, но при этом можно заметить некоторое снижение скорости в многопроцессорных и однопоточных задачах.
👉🏻Подписывайтесь на PythonTalk в Telegram 👈🏻
Источник: GeekPython