O bloqueio global de intérpretes (GIL) parece ser frequentemente citado como um dos principais motivos pelos quais a segmentação e afins é um pouco complicada no Python - o que levanta a questão "Por que isso foi feito em primeiro lugar?"
Não sendo um programador, não tenho idéia do porquê disso - qual era a lógica por trás da inserção do GIL?
python
multithreading
Fomite
fonte
fonte
Respostas:
Existem várias implementações de Python, por exemplo, CPython, IronPython, RPython, etc.
Alguns deles têm um GIL, outros não. Por exemplo, o CPython possui o GIL:
De http://en.wikipedia.org/wiki/Global_Interpreter_Lock
Os aplicativos escritos em linguagens de programação com um GIL podem ser projetados para usar processos separados para obter paralelismo total, pois cada processo tem seu próprio intérprete e, por sua vez, seu próprio GIL.
Benefícios do GIL
Por que Python (CPython e outros) usa o GIL
No CPython, o bloqueio global de intérpretes, ou GIL, é um mutex que impede que vários threads nativos executem bytecodes do Python de uma só vez. Esse bloqueio é necessário principalmente porque o gerenciamento de memória do CPython não é seguro para threads.
O GIL é controverso porque impede que os programas CPython multithread aproveitem ao máximo os sistemas multiprocessadores em determinadas situações. Observe que operações potencialmente bloqueadoras ou de execução demorada, como E / S, processamento de imagens e processamento de números NumPy, ocorrem fora do GIL. Portanto, é apenas em programas multithread que passam muito tempo dentro do GIL, interpretando o bytecode do CPython, que o GIL se torna um gargalo.
O Python possui um GIL em oposição ao bloqueio de baixa granularidade por vários motivos:
É mais rápido no caso de rosca única.
É mais rápido no caso multithread para programas vinculados de E / S.
É mais rápido no caso multithread para programas vinculados à CPU que fazem seu trabalho intensivo em computação nas bibliotecas C.
Isso facilita a escrita das extensões C: não haverá troca de threads do Python, exceto onde você permitir que isso aconteça (ou seja, entre as macros Py_BEGIN_ALLOW_THREADS e Py_END_ALLOW_THREADS).
Isso facilita a quebra de bibliotecas C. Você não precisa se preocupar com a segurança da linha. Se a biblioteca não for segura para threads, basta manter o GIL bloqueado enquanto você o chama.
O GIL pode ser liberado por extensões C. A biblioteca padrão do Python libera o GIL em torno de cada chamada de E / S de bloqueio. Portanto, o GIL não tem conseqüências para o desempenho de servidores vinculados de E / S. Assim, você pode criar servidores de rede em Python usando processos (bifurcação), threads ou E / S assíncrona, e o GIL não interferirá em seu caminho.
Bibliotecas numéricas em C ou Fortran também podem ser chamadas com o GIL liberado. Enquanto sua extensão C estiver aguardando a conclusão de uma FFT, o intérprete estará executando outros threads do Python. Um GIL é, portanto, mais fácil e rápido do que o bloqueio refinado neste caso também. Isso constitui a maior parte do trabalho numérico. A extensão NumPy libera o GIL sempre que possível.
Threads geralmente são uma maneira ruim de escrever a maioria dos programas de servidor. Se a carga for baixa, o garfo será mais fácil. Se a carga for alta, a E / S assíncrona e a programação orientada a eventos (por exemplo, usando a estrutura Twisted do Python) são melhores. A única desculpa para o uso de threads é a falta de os.fork no Windows.
O GIL é um problema se, e somente se, você estiver fazendo um trabalho intensivo de CPU em Python puro. Aqui você pode obter um design mais limpo usando processos e passagem de mensagens (por exemplo, mpi4py). Há também um módulo 'processing' na loja de queijos Python, que fornece aos processos a mesma interface que os threads (por exemplo, substitua threading.Thread por processing.Process).
Os encadeamentos podem ser usados para manter a capacidade de resposta de uma GUI, independentemente do GIL. Se o GIL prejudicar seu desempenho (consulte a discussão acima), você pode permitir que seu thread inicie um processo e aguarde o término.
fonte
s/RPython/PyPy/g
. @MichaelBorgwardt Dar razões pro GIL é o tipo de questão, não é? Embora eu concorde que parte do conteúdo desta resposta (ou seja, discussão de alternativas) não vem ao caso. E para o bem ou para o mal, agora é quase impossível se livrar da recontagem - está profundamente arraigado em toda a API e na base de código; é quase impossível se livrar dele sem reescrever metade do código e quebrar todo o código externo.multiprocessing
biblioteca - padrão desde 2.6. Seus pools de trabalhadores são uma abstração super-lisa para alguns tipos simples de paralelismo.Primeiro: Python não tem um GIL. Python é uma linguagem de programação. Uma linguagem de programação é um conjunto de regras e restrições matemáticas abstratas. Não há nada na especificação da linguagem Python que diga que deve haver um GIL.
Existem muitas implementações diferentes do Python. Alguns têm um GIL, outros não.
Uma explicação simples para ter um GIL é que escrever código simultâneo é difícil. Ao colocar um bloqueio gigante em torno do seu código, você o força a executar sempre em série. Problema resolvido!
No CPython, em particular, um objetivo importante é facilitar a extensão do intérprete com plug-ins escritos em C. Novamente, escrever código simultâneo é difícil, portanto, garantindo que não haverá simultaneidade, é mais fácil escrever extensões para o intérprete. Além disso, muitas dessas extensões são apenas invólucros finos em torno de bibliotecas existentes que podem não ter sido escritas com a simultaneidade em mente.
fonte
Qual é o objetivo de um GIL?
A documentação do CAPI tem a dizer sobre o assunto:
Em outras palavras, o GIL evita a corrupção do estado. Os programas Python nunca devem produzir uma falha de segmentação, porque apenas operações seguras à memória são permitidas. O GIL estende essa garantia a programas multithread.
Quais são as alternativas?
Se o objetivo do GIL é proteger o estado da corrupção, uma alternativa óbvia é bloquear um grão muito mais fino; talvez em um nível por objeto. O problema é que, embora tenha sido demonstrado que aumenta o desempenho de programas multithread, ele tem mais sobrecarga e os programas thread único sofrem como resultado.
fonte