web-dev-qa-db-fra.com

Une meilleure trouvaille Unix avec un traitement parallèle?

L'utilitaire unix find(1) est très utile me permettant d'effectuer une action sur de nombreux fichiers qui correspondent à certaines spécifications, par ex.

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

Ce qui précède peut exécuter un script ou un outil sur chaque fichier XML dans un répertoire particulier.

Disons que mon script/programme prend beaucoup de temps CPU et j'ai 8 processeurs. Ce serait bien de traiter jusqu'à 8 fichiers à la fois.

GNU make permet un traitement parallèle des tâches avec le -j flag mais find ne semble pas avoir une telle fonctionnalité. Existe-t-il une autre méthode générique de planification des travaux pour aborder cela?

45
PP.

xargs avec le -P option (nombre de processus). Disons que je voulais compresser tous les fichiers journaux d'un répertoire sur une machine à 4 processeurs:

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

Vous pouvez également dire -n <number> pour le nombre maximum d'unités de travail par processus. Alors disons que j'avais 2500 fichiers et j'ai dit:

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

Cela commencerait 4 bzip2 processus, chacun avec 500 fichiers, puis lorsque le premier en a terminé un autre, les 500 derniers fichiers sont démarrés.

Vous ne savez pas pourquoi la réponse précédente utilise xargsetmake, vous avez deux moteurs parallèles là-bas!

66
Gaius

parallèle GN peut aussi aider.

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

Notez que sans le -j8 argument, parallel par défaut le nombre de cœurs sur votre machine :-)

36
ephemient

Pas besoin de "réparer" find - utilisez make lui-même pour gérer le parallélisme.

Demandez à votre processus de créer un fichier journal ou un autre fichier de sortie, puis utilisez un Makefile comme celui-ci:

.SUFFIXES:  .xml .out

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

et invoqué ainsi:

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

Mieux encore, si vous vous assurez que le fichier de sortie n'est créé qu'à l'issue du processus Java Java, vous pouvez profiter de la gestion des dépendances de make pour vous assurer que la prochaine fois, il ne sera traité que les fichiers se font.

6
Alnitak

Find a une option parallèle que vous pouvez utiliser directement en utilisant le symbole "+"; aucun xargs requis. En le combinant avec grep, il peut déchirer votre arbre rapidement à la recherche d'allumettes. par exemple, si je recherche tous les fichiers de mon répertoire sources contenant la chaîne 'foo', je peux invoquer
find sources -type f -exec grep -H foo {} +

3
Mark Evans