Preciso executar muitos comandos semelhantes no menor tempo possível e usando todos os recursos disponíveis.
Por exemplo meu caso é processar imagens, quando utilizo o seguinte comando:
for INPUT in *.jpg do; some_command; done
o comando é executado um por um e não utiliza todos os recursos disponíveis.
Mas, por outro lado, a execução for INPUT in *.jpg do; some_command &; done
faz com que a máquina fique sem recursos em muito pouco tempo.
Eu sei sobre o comando at
do batch
, mas não tenho certeza se posso usá-lo no meu caso. Corrija-me se eu estiver enganado.
Então eu estava pensando em colocar os comandos em algum tipo de fila e executar apenas uma parte deles de uma vez. Não sei fazer isso de forma rápida e esse é o problema. Tenho certeza de que alguém teve um problema semelhante antes.
Por favor, avise.
Responder1
GNU Parallel é feito exatamente para isso:
parallel some_command {} ::: *.jpg
O padrão é um trabalho por núcleo da CPU. No seu caso, você pode querer executar mais um trabalho do que os núcleos:
parallel -j+1 some_command {} ::: *.jpg
GNU Parallel é um paralelizador geral e facilita a execução de trabalhos em paralelo na mesma máquina ou em várias máquinas às quais você tem acesso ssh.
Se você tiver 32 jobs diferentes que deseja executar em 4 CPUs, uma maneira simples de paralelizar é executar 8 jobs em cada CPU:
Em vez disso, o GNU Parallel gera um novo processo quando um deles termina - mantendo as CPUs ativas e economizando tempo:
Instalação
Por razões de segurança você deve instalar o GNU Parallel com seu gerenciador de pacotes, mas se o GNU Parallel não estiver empacotado para sua distribuição, você pode fazer uma instalação pessoal, que não requer acesso root. Isso pode ser feito em 10 segundos fazendo o seguinte:
(wget -O - pi.dk/3 || curl pi.dk/3/ || fetch -o - http://pi.dk/3) | bash
Para outras opções de instalação consultehttp://git.savannah.gnu.org/cgit/parallel.git/tree/README
Saber mais
Veja mais exemplos:http://www.gnu.org/software/parallel/man.html
Assista aos vídeos de introdução:https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1
Percorra o tutorial:http://www.gnu.org/software/parallel/parallel_tutorial.html
Inscreva-se na lista de e-mail para obter suporte:https://lists.gnu.org/mailman/listinfo/parallel
Responder2
Você pode usar o GNU make com a --jobs
opção de executar coisas em paralelo, mas limitado ao número especificado de trabalhos. Você pode adaptar esse número para algo que não mate sua máquina.
Aqui está um exemplo de Makefile que usa alvos ah (estes podem ser seus arquivos de saída, por exemplo) e executa um conjunto (fictício) de comandos para cada alvo:
all: a b c d e f g h
a b c d e f g h:
echo $@; sleep 10
NB O recuo do comandodeveser um caractere TAB. Veja oDocumentação de criação do GNUpara obter detalhes da sintaxe dos Makefiles.
Você pode invocar make with make --jobs 4
e obter a seguinte saída (usei time make --jobs 4
abaixo para mostrar o tempo decorrido):
echo a; sleep 10
echo b; sleep 10
echo c; sleep 10
echo d; sleep 10
b
a
c
d
echo e; sleep 10
echo f; sleep 10
echo g; sleep 10
e
f
echo h; sleep 10
g
h
real 0m20.009s
user 0m0.010s
sys 0m0.011s
Os quatro primeiros foram executados em paralelo, depois os quatro seguintes, portanto o tempo total decorrido é de 20 segundos.