Skip to main content

Thread | Python

  • Thread | Python

Criando e executando Threads

import threading
import time

def tarefa(nome):
for i in range(5):
print(f"Tarefa {nome} está executando...")
time.sleep(1)

# Criando threads
thread1 = threading.Thread(target=tarefa, args=("A",))
thread2 = threading.Thread(target=tarefa, args=("B",))

# Iniciando threads
thread1.start()
thread2.start()

# Aguardando as threads terminarem
thread1.join()
thread2.join()

print("Todas as threads foram concluídas.")

Event Loop | Python

🔁 Programação Assíncrona - Event Loop (Laço de Eventos)

O Event Loop (Laço de Eventos) roda em uma única thread (geralmente a principal) e executa todas as tarefas (corrotinas) nessa thread.
Enquanto uma tarefa está em execução dentro do laço de eventos, nenhuma outra tarefa pode rodar na mesma thread ao mesmo tempo.

Quando uma tarefa executa uma instrução await, ela é suspensa e colocada na fila de tarefas (Task Queue).
O Event Loop então busca a próxima tarefa que está pronta para ser executada.


⚙️ Como Funciona:

  1. Agendar (Schedule):
    As tarefas (corrotinas) são agendadas e adicionadas ao laço de eventos.

  2. Executar (Run):
    O laço de eventos verifica continuamente quais tarefas estão prontas para serem executadas.

  3. Executar a Tarefa (Execute):
    Ele escolhe a tarefa, a executa, e se ela estiver esperando por I/O (entrada/saída), passa para a próxima.

  4. Repetir (Repeat):
    O processo continua até que todas as tarefas sejam finalizadas.

Global Interceptor Lock (GIL)

alt text

O Global Interpreter Lock (GIL) é um mecanismo utilizado em algumas implementações do Python, como o CPython, para gerenciar o acesso a objetos compartilhados na memória por múltiplas threads. Ele garante que apenas uma thread execute código Python por vez, mesmo em sistemas com múltiplos núcleos de CPU.

Características do GIL:

  1. Sincronização: O GIL simplifica a implementação do interpretador, garantindo que operações em objetos Python sejam thread-safe.
  2. Limitação de Concurrency: Apesar de permitir múltiplas threads, o GIL impede que elas executem código Python simultaneamente, limitando o desempenho em programas que dependem de paralelismo.
  3. I/O Bound vs CPU Bound: O GIL é menos problemático em aplicações que realizam operações de I/O (como leitura de arquivos ou chamadas de rede), pois o bloqueio é liberado durante essas operações. No entanto, ele é uma limitação significativa para aplicações que realizam computação intensiva (CPU-bound).

Alternativas:

  • Para contornar o GIL em tarefas CPU-bound, pode-se usar multiprocessing, que cria processos separados em vez de threads.
  • Outras implementações do Python, como Jython ou IronPython, não possuem GIL, mas têm suas próprias limitações.

O GIL é frequentemente criticado por limitar o desempenho em sistemas multicore, mas continua sendo parte do CPython devido à sua simplicidade e impacto mínimo em aplicações I/O-bound.

Threading x Async x Multiprocessing

Quando usar cada modelo

Threading:

  • Use para tarefas limitadas por I/O, como operações de rede, leitura/gravação de arquivos e interação com o usuário.

Multiprocessing:

  • Use para tarefas limitadas por CPU, como processamento de dados, cálculos matemáticos e processamento de imagens.

Programação Assíncrona:

  • Use para tarefas altamente concorrentes limitadas por I/O e para maximizar a eficiência de recursos, lidando com requisições como solicitações de clientes, operações de banco de dados e requisições de recursos.