Um melhor unix encontra com processamento paralelo?

36

O utilitário unix find(1) é muito útil, permitindo que eu execute uma ação em muitos arquivos que correspondam a determinadas especificações, por exemplo

find /dump -type f -name '*.xml' -exec java -jar ProcessFile.jar {} \;

O exemplo acima pode executar um script ou ferramenta sobre cada arquivo XML em um diretório específico.

Digamos que meu script / programa consuma muito tempo de CPU e eu tenha 8 processadores. Seria bom processar até 8 arquivos por vez.

O GNU make permite o processamento de tarefas paralelas com o -j flag, mas find não parece ter essa funcionalidade. Existe um método genérico alternativo de agendamento de trabalho para abordar isso?

    
por PP. 21.10.2010 / 11:07

4 respostas

51

xargs com a opção -P (número de processos). Digamos que eu quisesse compactar todos os arquivos de log em um diretório em uma máquina de 4 cpu:

find . -name '*.log' -mtime +3 -print0 | xargs -0 -P 4 bzip2

Você também pode dizer -n <number> para o número máximo de unidades de trabalho por processo. Então digamos que eu tenha 2500 arquivos e eu falei:

find . -name '*.log' -mtime +3 -print0 | xargs -0 -n 500 -P 4 bzip2

Isso iniciaria 4% debzip2 processos, cada um com 500 arquivos e, em seguida, quando o primeiro terminasse, outros seriam iniciados nos últimos 500 arquivos.

Não sei por que a resposta anterior usa xargs e make , você tem dois mecanismos paralelos lá!

    
por 23.10.2010 / 18:33
28

O paralelo GNU também pode ajudar.

find /dump -type f -name '*.xml' | parallel -j8 java -jar ProcessFile.jar {}

Observe que sem o argumento -j8 , parallel é padronizado para o número de núcleos em sua máquina: -)

    
por 24.10.2010 / 00:07
5

Não é necessário "corrigir" find - use o make para lidar com o paralelismo.

Faça seu processo criar um arquivo de log ou algum outro arquivo de saída e, em seguida, use um Makefile assim:

.SUFFIXES:  .xml .out

.xml.out:
        java -jar ProcessFile.jar $< 1> $@

e invocado assim:

find /dump -type f -name '*.xml' | sed -e 's/\.xml$/.out/' | xargs make -j8

Melhor ainda, se você garantir que o arquivo de saída só será criado após a conclusão bem-sucedida do processo Java, poderá aproveitar o tratamento de dependência de make para garantir que, da próxima vez, apenas arquivos não processados sejam concluídos.

    
por 21.10.2010 / 11:24
2

O Find tem uma opção paralela que você pode usar diretamente usando o símbolo "+"; nenhum xargs requerido. Combinando-o com o grep, ele pode rasgar sua árvore rapidamente procurando por correspondências. por exemplo, se eu estiver procurando por todos os arquivos no meu diretório de fontes que contenham a string 'foo', eu posso invocar o find sources -type f -exec grep -H foo {} +

    
por 30.05.2015 / 11:15