Eu sugiro strongmente que você dê uma olhada no paralelo GNU . Ele faz exatamente o que você quer e não depende de qualquer shell particular.
Se eu quiser processar um grande número de arquivos com o comando "do_something", que pode usar apenas um núcleo, qual é a melhor maneira de usar todos os núcleos disponíveis, presumindo que cada arquivo possa ser processado independentemente?
Neste momento, faço algo assim:
#!/bin/zsh
TASK_LIMIT=8
TASKS=0
for i in *(.)
{
do_something "$i"&
TASKS=$(($TASKS+1))
if [[ $TASKS -ge $TASK_LIMIT ]]; then
wait; TASKS=0; fi
}
wait
Obviamente, isso não é eficiente porque depois de atingir $ TASK_LIMIT, ele espera quando todos os "do_something" terminam. Por exemplo, no meu script real eu uso cerca de 500% do meu processador de 8 núcleos em vez de > 700%.
A execução sem $ TASK_LIMIT não é uma opção porque "do_something" pode consumir muita memória.
Idealmente, o script deve tentar manter o número de tarefas paralelas em $ TASK_LIMIT: por exemplo, se a tarefa 1 de 8 tiver terminado e houver pelo menos mais um arquivo para processar, o script deverá executar próximo "do_something" em vez de aguardar restantes 7 tarefas para terminar. Existe uma maneira de conseguir isso em zsh ou bash?
Eu sugiro strongmente que você dê uma olhada no paralelo GNU . Ele faz exatamente o que você quer e não depende de qualquer shell particular.
Lembre-se de quantos processos você iniciou. Quando um processo termina, diminua a contagem. Quando a contagem for menor que o máximo, inicie um novo processo.
O único problema é como sinalizar o final de um processo. Você pode, por exemplo crie um arquivo emty de um determinado nome em / tmp (composto por $$ e $ BASHPID).
Tags bash zsh multi-core shell-script