Eu me deparei com um comportamento estranho ao usar o comando wait para executar jobs paralelos em um script bash. Para simplificar, reduzi o problema ao seguinte script bash:
#!/bin/bash
test_func() {
echo "$(date +%M:%S:%N): start $1"
sleep $1
echo "$(date +%M:%S:%N): end $1"
}
i=0
for j in {5..9}; do
test_func $j &
((i++))
sleep 3
done
echo "$(date +%M:%S:%N): No new processes, waiting for all to finish"
while [ $(pgrep -c -P$$) -ge 1 ]; do
echo "$(date +%M:%S:%N): $(pgrep -P$$ -d' ')"
wait -n $(pgrep -P$$ -d' ')
echo "$(date +%M:%S:%N): next $i"
((i++))
done
O script acima gera 5 execuções paralelas da test_func
função, cada uma esperando por j
segundos. Adicionei carimbos de tempo a cada saída para mostrar os tempos. A saída da execução deste script é a seguinte:
03:53:854843895: start 5
03:56:855729952: start 6
03:58:856136029: end 5
03:59:856388725: start 7
04:02:857016376: end 6
04:02:857508665: start 8
04:05:857895265: start 9
04:06:857738397: end 7
04:08:858666941: No new processes, waiting for all to finish
04:08:864528182: 3837265 3837297
04:08:875479745: next 5
04:08:881049792: 3837265 3837297
04:08:892058494: next 6
04:08:899310728: 3837265 3837297
04:08:910466324: next 7
04:08:916130505: 3837265 3837297
04:10:858746305: end 8
04:10:859380011: next 8
04:10:864975972: 3837297
04:14:859172632: end 9
04:14:859818377: next 9
Como pode ser visto na saída acima, o script gera todos os 5 processos, dos quais 3 terminam antes do fim do loop for (devido ao sleep 3
). Neste ponto, há 2 processos ainda em execução, que são fornecidos corretamente pelo pgrep
comando com IDs 3837265 e 3837297. No entanto, o wait
comando no loop while retorna imediatamente (< 0,1 segundos) para as próximas três chamadas, sem que nenhum outro processo termine (mostrado com o pgrep
comando), mesmo apesar de fornecer a ele os IDs de processo para esperar.
Até onde eu posso dizer (e por alguma experimentação) o wait
comando está retornando imediatamente para cada uma das test_func
chamadas que terminaram antes de ser chamado pela primeira vez (que neste caso são três vezes), antes de realmente esperar. O que eu não entendo é por que isso acontece, especialmente porque eu forneço os IDs de processo para esperar.
Estou usando o Ubuntu 20.04.6 e o GNU bash, versão 5.0.17(1) para contexto.