← Назад к вопросам

Что знаешь про gil?

2.0 Middle🔥 171 комментариев
#Python

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое GIL (Global Interpreter Lock)

GIL — это механизм в CPython (основной реализации Python), который позволяет только одному потоку выполнять Python bytecode одновременно. Даже на многоядерных системах, когда у вас несколько потоков, только один может выполняться в момент времени.

Почему GIL существует?

GIL был введён для упрощения управления памятью в CPython. Вместо дорогостоящей синхронизации каждого объекта, используется один глобальный lock. Это делает реализацию CPython проще и быстрее для однопоточных программ.

Влияние на многопоточность

import threading
import time

def cpu_bound_task():
    count = 0
    for i in range(100_000_000):
        count += 1
    return count

start = time.time()
cpu_bound_task()
cpu_bound_task()
print(f"Single thread: {time.time() - start:.2f}s")

start = time.time()
threads = [threading.Thread(target=cpu_bound_task) for _ in range(2)]
for t in threads:
    t.start()
for t in threads:
    t.join()
print(f"Multi thread: {time.time() - start:.2f}s")

Где GIL НЕ помеха

I/O операции (сетевые запросы, работа с файлами, БД) — потоки могут выполняться параллельно, потому что GIL отпускается во время ввода-вывода:

import requests
import threading

def fetch_data(url):
    response = requests.get(url)
    return response.status_code

threads = [threading.Thread(target=fetch_data, args=(url,)) for url in urls]
for t in threads:
    t.start()
for t in threads:
    t.join()

Решения для CPU-bound задач

1. Multiprocessing — отдельные процессы, каждый со своим GIL:

from multiprocessing import Pool

def cpu_bound_task(n):
    count = 0
    for i in range(n):
        count += 1
    return count

if __name__ == "__main__":
    with Pool(4) as pool:
        results = pool.map(cpu_bound_task, [100_000_000] * 4)

2. asyncio — асинхронный подход для I/O операций:

import asyncio
import aiohttp

async def fetch(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            return await response.json()

async def main():
    tasks = [fetch(url) for url in urls]
    results = await asyncio.gather(*tasks)

asyncio.run(main())

3. Cython или Rust extensions — для критичного по производительности кода.

4. Другие реализации — PyPy, Jython, IronPython.

Практический совет для Data Engineer

Для работы с данными в Data Pipeline используй multiprocessing для распараллеливания обработки больших объёмов данных, asyncio для работы с множественными источниками данных, и помни, что Pandas/NumPy уже оптимизированы и работают с C.

Что знаешь про gil? | PrepBro