O que é paralelismo na programação?
sobes.tech IA
Resposta da IA
O paralelismo na programação é a execução de várias tarefas simultaneamente ou a aparência de execução simultânea, o que permite melhorar o desempenho e a capacidade de resposta das aplicações.
Distinguem-se várias formas de paralelismo:
-
Multiprocessamento: Utiliza vários processos independentes, cada um com o seu próprio espaço de endereçamento. Isto evita a limitação do GIL (Global Interpreter Lock) no CPython e é adequado para tarefas que utilizam intensamente a CPU.
import multiprocessing import time def worker(num): """Algum trabalho""" time.sleep(1) print(f'Worker {num} terminado') if __name__ == '__main__': processes = [] for i in range(5): p = multiprocessing.Process(target=worker, args=(i,)) processes.append(p) p.start() for p in processes: p.join() print("Todos os workers terminaram") -
Multithreading: Utiliza vários threads dentro de um mesmo processo, partilhando o mesmo espaço de endereçamento. Devido ao GIL no CPython, os threads não são executados em paralelo em diferentes núcleos para tarefas CPU-bound, mas são eficientes para tarefas I/O-bound.
import threading import time def worker(num): """Algum trabalho""" time.sleep(1) # Simulação de operação I/O print(f'Thread {num} terminado') threads = [] for i in range(5): t = threading.Thread(target=worker, args=(i,)) threads.append(t) t.start() for t in threads: t.join() print("Todos os threads terminaram") -
Programação assíncrona (Asyncio): Utiliza um único thread e um ciclo de eventos (event loop) para gerir a execução de tarefas. Adequado para aplicações I/O-bound de alta carga e servidores web. Não bloqueia a execução enquanto espera por I/O.
import asyncio import time async def worker(num): """Algum trabalho assíncrono""" await asyncio.sleep(1) # Espera assíncrona de I/O print(f'Worker assíncrono {num} terminado') async def main(): tasks = [] for i in range(5): task = asyncio.create_task(worker(i)) tasks.append(task) await asyncio.gather(*tasks) print("Todos os workers assíncronos terminaram") if __name__ == '__main__': asyncio.run(main())
A escolha da abordagem depende da natureza da tarefa:
| Abordagem | Tarefas CPU-bound | Tarefas I/O-bound | GIL | Uso de memória |
|---|---|---|---|---|
| Multiprocessamento | Excelente | Bom | Contorna | Grande (seu próprio processo) |
| Multithreading | Mau (por causa do GIL) | Excelente | Bloqueia | Pequeno (processo comum) |
| Assíncrono | Mau | Excelente | Não bloqueia | Pequeno (um único thread) |
O paralelismo requer uma gestão cuidadosa de sincronização e recursos para evitar condições de corrida e deadlocks.