Pular para o conteúdo

Padrões de concorrência

Produtor-consumidor, pool de trabalhadores, espalhar e juntar — montados com as peças da biblioteca.

Pool de trabalhadores#

N trabalhadores tirando tarefas de um canal: o número de trabalhadores limita quantas rodam ao mesmo tempo — o que protege o serviço externo que eles chamam.

dataforge
adopt Arcane.Concurrent as P

fila := P.canal()
resultados := P.ator(lambda acc, r: acc + [r], [])

action trabalhador():
    persist yes:
        t := fila.receber()
        given t is void:
            halt
        resultados.enviar(t * t)

action alimentar():
    cycle i from 1 to 6:
        fila.enviar(i)
    fila.fechar()

parallel:
    alimentar()
    trabalhador()
    trabalhador()
    trabalhador()
assert sorted(resultados.parar()) is [1, 4, 9, 16, 25, 36]

Espalhar e juntar#

Muitas chamadas independentes ao mesmo tempo, e o resultado de todas na ordem da entrada — P.map faz os dois, com um teto de trabalhadores:

dataforge
adopt Arcane.Concurrent as P

action buscar_preco(item):
    sleep(10)                         // a rede
    yield len(item) * 10

precos := P.map(buscar_preco, ["café", "chá", "açúcar"], 3)
assert precos is [40, 30, 60]         // na ordem da entrada, não da chegada
PadrãoPeças
produtor-consumidorP.canal(n) — a capacidade é a contrapressão
pool de trabalhadorescanal + N threads + um ator para os resultados
espalhar e juntarP.map(acao, itens, trabalhadores)
estado disputadoP.ator
várias escritas que andam juntasArcane.Stm