Pular para o conteúdo

Processos

O único caminho para mais de um núcleo no CPython — o que atravessa, o que custa, e o pool que paga a partida uma vez.

Duas threads do CPython nunca executam código Python ao mesmo tempo — o GIL alterna entre elas. Para conta pesada, threads não ajudam: 8 blocos de CPU em 10 núcleos levaram 1607 ms em série e 1654 ms em threads. Em processos, 466 ms: 3,45× mais rápido.

dataforge
adopt Arcane.Concurrent as P

action pesado(n):
    total := 0
    cycle i from 1 to n:
        total += i * i
    yield total

resultados := P.map_processos(pesado, [1000, 2000, 3000])
assert resultados[0] is 333833500                  // na ordem da entrada

O que atravessa#

Um processo não vê a memória do outro. O que vai é a declaração da ação — a árvore, os parâmetros, os records e blueprints que ela usa — e os dados, copiados. Uma conexão de banco ou um arquivo aberto não atravessam: abra do lado de lá.

UseQuando
P.maptrabalho que espera (rede, disco): threads bastam
P.map_processosconta pesada, uma vez
P.pool_processos()conta pesada repetida: a partida (~100 ms) é paga uma vez
nada dissotrabalho pequeno: a partida de um processo custa mais que a conta

O detalhe completo — o que é copiado, a nota de erro que diz que ele aconteceu no outro processo, o forkserver — está em Paralelismo.