CodeGym /Cursos /Python SELF PT /Contornando o GIL

Contornando o GIL

Python SELF PT
Nível 26 , Lição 4
Disponível

11.1 Global Interpreter Lock

Global Interpreter Lock (GIL) — é um mecanismo no interpretador CPython que garante que apenas um thread está executando bytecode Python a qualquer momento. GIL impede a execução paralela de threads, o que pode impactar negativamente o desempenho de programas multithread, especialmente em processadores multicore.

Razões para a existência do GIL

Simplificação do gerenciamento de memória: GIL simplifica o gerenciamento de memória e a coleta de lixo, tornando o Python mais fácil de implementar.

Segurança de threads: GIL previne condições de corrida, tornando a execução do código segura para threads sem a necessidade de usar locks.

Problemas causados pelo GIL

Desempenho limitado: Programas multithread que executam tarefas intensivas em computação não conseguem aproveitar completamente as vantagens dos processadores multicore devido às limitações do GIL.

Distorsão de desempenho: Programas que usam threads intensivamente para executar tarefas podem enfrentar degradação de desempenho devido à troca de contexto entre threads.

Atualmente, existem 4 principais maneiras de "contornar o GIL":

11.2 Uso de Multiprocessamento (multiprocessing)

Módulo multiprocessing permite criar processos que são executados em paralelo e não estão limitados pelo GIL, já que cada processo tem seu próprio interpretador Python e memória.

Exemplo:


import multiprocessing

def worker(num):
    print(f'Worker: {num}')
            
def main():
    processes = []
    for i in range(5):
        p = multiprocessing.Process(target=worker, args=(i,))
        processes.append(p)
        p.start()
            
    for p in processes:
        p.join()
            
main()

11.3 Programação Assíncrona

Programação assíncrona usando asyncio permite executar tarefas em paralelo sem bloquear o thread principal. Embora isso não contorne o GIL diretamente, permite usar eficientemente o tempo de espera para executar outras tarefas.

Exemplo:


import asyncio

async def main():
    await asyncio.sleep(1)
    print('Hello')
            
asyncio.run(main())

11.4 Uso de Bibliotecas com Gestão Própria de Threads

Algumas bibliotecas, como NumPy e SciPy, são escritas em C e usam seus próprios mecanismos de gestão de threads, o que permite contornar o GIL e usar eficientemente processadores multicore para cálculos.

Na verdade, essa é uma das principais razões para o sucesso do Python, por mais lento que ele possa ser. Todos os cálculos complexos são reescritos em linguagens C/C++ e executados em todos os núcleos do processador ou até mesmo diretamente nos núcleos da placa de vídeo. E nas placas de vídeo modernas, há milhares de núcleos.

Assim, não importa mais quão rápido ou lento é a linguagem, se todos os cálculos que demandam muitos recursos são realizados por bibliotecas externas ou até mesmo transferidos para data centers remotos.

11.5 Execução de Cálculos Fora do Interpretador Python

Uso de extensões em C/C++ ou outras linguagens que podem executar cálculos fora do interpretador Python e depois retornar o resultado. Isso permite evitar o bloqueio do GIL durante a execução de cálculos intensivos.

Exemplo de uso com Cython:


# example.pyx

def compute(int n):
    cdef int i, result = 0
    for i in range(n):
        result += i
    return result

Compilação e uso:


cythonize -i example.pyx

import example
print(example.compute(1000000))
1
Pesquisa/teste
Assincronicidade, nível 26, lição 4
Indisponível
Assincronicidade
Assincronicidade
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION