Multiprocessing em Python: guia prático de paralelismo

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

O módulo multiprocessing em Python oferece um conjunto poderoso de ferramentas para criar programas paralelos que aproveitam ao máximo processadores multi-core. Diferente do multithreading tradicional, que é limitado pelo Global Interpreter Lock (GIL), o multiprocessing permite executar vários processos simultaneamente, cada um com sua própria memória e execução independente.

Princípios básicos do multiprocessing

O multiprocessamento em Python cria processos separados que podem rodar em paralelo em diferentes núcleos da CPU. Cada processo opera em um espaço de memória isolado, eliminando problemas com dados compartilhados comuns no multithreading.

Os principais componentes do módulo multiprocessing incluem:

  • Process — classe para criar e gerenciar processos individuais
  • Pool — pool de processos para executar várias tarefas de forma eficiente
  • Queue — filas para transferência segura de dados entre processos
  • Lock — mecanismos de sincronização para controlar acesso a recursos
  • Manager — objetos para gerenciar dados compartilhados

Quando usar multiprocessing

O multiprocessing é mais eficaz nos seguintes casos:

Tarefas intensivas em CPU: cálculos matemáticos, processamento de imagens, análise de dados, simulações científicas. Essas tarefas se beneficiam da execução paralela em diferentes núcleos.

Processamento de grandes volumes de dados: quando é necessário aplicar a mesma função a muitos elementos, o multiprocessing pode acelerar significativamente a execução.

Tarefas independentes: operações que não exigem troca frequente de dados entre processos.

Para tarefas intensivas em I/O (arquivos, requisições de rede), é melhor usar programação assíncrona (asyncio) ou multithreading.

Criando e gerenciando processos

Exemplo básico com a classe Process

import multiprocessing
import time

def worker_task(name, duration):
    """Função executada em um processo separado"""
    print(f"Processo {name} iniciou")
    time.sleep(duration)
    print(f"Processo {name} finalizou")

if __name__ == "__main__":
    # Criando processos
    process1 = multiprocessing.Process(target=worker_task, args=("Worker-1", 3))
    process2 = multiprocessing.Process(target=worker_task, args=("Worker-2", 2))
    
    # Iniciando processos
    start_time = time.time()
    process1.start()
    process2.start()
    
    # Aguardando conclusão
    process1.join()
    process2.join()
    
    end_time = time.time()
    print(f"Tempo total de execução: {end_time - start_time:.2f} segundos")

Herdando da classe Process

import multiprocessing
import os

class CustomProcess(multiprocessing.Process):
    def __init__(self, name, work_count):
        super().__init__()
        self.name = name
        self.work_count = work_count
    
    def run(self):
        """Método executado no processo"""
        print(f"Processo {self.name} (PID: {os.getpid()}) iniciou")
        
        for i in range(self.work_count):
            print(f"{self.name}: executando tarefa {i+1}")
            time.sleep(1)
        
        print(f"Processo {self.name} finalizou")

if __name__ == "__main__":
    processes = []
    
    # Criando vários processos
    for i in range(3):
        p = CustomProcess(f"Process-{i+1}", 3)
        processes.append(p)
        p.start()
    
    # Aguardando todos os processos
    for p in processes:
        p.join()

Trabalhando com pool de processos

O Pool oferece uma interface conveniente para gerenciar

Blogs

Book Recommendations