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