Processos Paralelos em Python: Paralelismo Verdadeiro

Processos paralelos executam código simultaneamente em múltiplos núcleos. Isso é chamado de true parallelism ou paralelismo verdadeiro. Primeiramente, cada processo tem seu próprio interpretador e memória. Por exemplo, 8 processos podem rodar em 8 núcleos de CPU ao mesmo tempo. Além disso, processos não compartilham o GIL (Global Interpreter Lock). A voz passiva é usada aqui: “o sistema operacional gerencia a distribuição entre núcleos”. Quando utilizar processos paralelos? Em tarefas com CPU intensiva. Por exemplo, processamento de imagens, simulações científicas ou machine learning. Também em qualquer tarefa que exija todo o poder da máquina. Python oferece o módulo multiprocessing e o concurrent.futures. Vamos explorar características, ganhos e limitações. Três subtítulos guiarão você pelo verdadeiro paralelismo. Ao final, você dominará a execução paralela em Python.

Multiprocessing vs. threading: a diferença crucial

Threads são leves, mas limitadas pelo GIL em CPU-bound. Processos são mais pesados, mas executam em paralelo verdadeiro. Quando escolher processos? Quando o gargalo é CPU, não I/O. A criação de um processo é mais cara que uma thread. No entanto, o ganho em paralelismo compensa para tarefas longas. A voz passiva é aplicada: “a memória é duplicada para cada processo”. Exemplo comparativo entre threads e processos para CPU-bound: Processos mostram aceleração próxima ao número de núcleos. Threads mostram aceleração próxima de 1.0 devido ao GIL. Essa é a diferença fundamental entre concorrência e paralelismo.

Comunicação e sincronização entre processos

Processos paralelos precisam se comunicar para trocar resultados. Diferente de threads, eles não compartilham memória automaticamente. Portanto, usamos filas (Queue), pipes ou memória compartilhada. A serialização (pickle) é necessária para enviar dados entre processos. Isso adiciona overhead, mas é inevitável para isolamento. Quando usar memória compartilhada? Para grandes arrays numéricos. A voz passiva é usada aqui: “os dados são copiados por valor entre processos”. Exemplo de comunicação com Queue entre processos paralelos: Queues são seguras e ideais para padrões produtor-consumidor. Arrays compartilhados são eficientes para dados numéricos. Sempre use locks ao modificar memória compartilhada.

Escalabilidade e lei de amdahl

O ganho com processos paralelos não é linear infinito. A lei de Amdahl descreve o limite teórico de aceleração. A fórmula é: \(S = \frac{1}{(1 – P) + \frac{P}{N}}\) Onde P é a fração paralelizável e N é o número de núcleos. Por exemplo, com 90% paralelizável e 8 núcleos, o ganho máximo é 4.7x. Portanto, nem todo código pode ser perfeitamente paralelizado. A voz passiva é aplicada: “partes sequenciais são executadas em apenas um núcleo”. Exemplo demonstrando a lei de Amdahl na prática: Observe que quanto maior a fração sequencial, menor o ganho. Portanto, identifique e otimize os gargalos sequenciais primeiro. Processos paralelos são ferramentas poderosas, mas não mágicas. Use-os com sabedoria e meça sempre o ganho real. Para muitos problemas, o paralelismo verdadeiro transforma horas em minutos. Experimente e veja seu código voar em múltiplos núcleos.

Deixe um comentário