Estou tentando criar um servidor web python usando Django e Waitress, mas gostaria de saber como o Waitress lida com solicitações simultâneas e quando o bloqueio pode ocorrer.
Embora a documentação do Waitress mencione que vários threads de trabalho estão disponíveis, ela não fornece muitas informações sobre como eles são implementados e como o GIL do python os afeta (ênfase minha):
Quando um canal determina que o cliente enviou pelo menos uma solicitação HTTP válida completa, ele agenda uma "tarefa" com um "despachante de encadeamentos". O distribuidor de encadeamentos mantém um conjunto fixo de encadeamentos de trabalho disponíveis para realizar o trabalho do cliente (por padrão, 4 encadeamentos). Se um segmento de trabalho estiver disponível quando uma tarefa for agendada, o segmento de trabalho executará a tarefa. A tarefa tem acesso ao canal e pode gravar de volta no buffer de saída do canal. Quando todos os segmentos de trabalho estiverem em uso , as tarefas agendadas aguardarão na fila para que um segmento de trabalho fique disponível.
Também não parece haver muita informação sobre o Stackoverflow. Da pergunta "O trabalhador assíncrono de Gunicorn é análogo a Garçonete?" :
A garçonete possui um encadeamento assíncrono mestre que armazena em buffer as solicitações e enfileira cada solicitação a um de seus encadeamentos de trabalho de sincronização quando a E / S da solicitação é concluída.
Essas declarações não abordam o GIL (pelo menos no meu entendimento) e seria ótimo se alguém pudesse elaborar mais sobre como os threads de trabalho funcionam para a Waitress. Obrigado!
Respostas:
Veja como os servidores assíncronos controlados por eventos geralmente funcionam:
Praticamente da mesma maneira que acabei de descrever acima. E para os trabalhadores, ele cria threads, não processos.
Garçonete usa threads para trabalhadores. Então, sim, eles são afetados pelo GIL, pois não são realmente concorrentes, embora pareçam ser. "Assíncrono" é o termo correto.
Os threads no Python são executados em um único processo, em um único núcleo da CPU e não são executados em paralelo. Um encadeamento adquire o GIL por um período muito pequeno e executa seu código e, em seguida, o GIL é adquirido por outro encadeamento.
Mas como o GIL é lançado na E / S de rede, o processo pai sempre o adquirirá sempre que houver um evento de rede (como uma solicitação de entrada) e, dessa forma, você pode ter certeza de que o GIL não afetará as operações ligadas à rede ( como receber solicitações ou enviar respostas).
Por outro lado, os processos Python são realmente concorrentes: eles podem ser executados em paralelo em vários núcleos. Mas a garçonete não usa processos.
Você deveria estar preocupado?
Se você está apenas executando pequenas tarefas de bloqueio, como leitura / gravação em banco de dados e atendendo apenas algumas centenas de usuários por segundo, o uso de threads não é tão ruim assim.
Para atender a um grande volume de usuários ou executar tarefas de bloqueio de longa execução, você pode usar filas de tarefas externas como o Aipo . Isso será muito melhor do que gerar e gerenciar processos você mesmo.
fonte