J'ai un tas d'images PNG sur un répertoire. J'ai une application appelée pngout que j'exécute pour compresser ces images. Cette application est appelée par un script que j'ai fait. Le problème est que ce script en fait un à la fois, quelque chose comme ceci :
FILES=(./*.png)
for f in "${FILES[@]}"
do
echo "Processing $f file..."
# take action on each file. $f store current file name
./pngout -s0 $f R${f/.//}
done
Traiter un seul dossier à la fois prend beaucoup de temps. Après avoir exécuté cette application, je vois que le CPU n'est qu'à 10%. J'ai donc découvert que je pouvais diviser ces fichiers en 4 lots, placer chaque lot dans un répertoire et déclencher 4, à partir de quatre fenêtres de terminal, quatre processus, donc j'ai quatre instances de mon script, en même temps, traitant ces images et le le travail prend 1/4 du temps.
Le deuxième problème est que j'ai perdu du temps à diviser les images et les lots et à copier le script dans quatre répertoires, à ouvrir 4 fenêtres de terminal, bla bla…
Comment faire cela avec un seul script, sans avoir à diviser quoi que ce soit ?
Je veux dire deux choses :d'abord, comment puis-je, à partir d'un script bash, lancer un processus en arrière-plan ? (il suffit d'ajouter &à la fin ?) Deuxièmement :comment arrêter d'envoyer des tâches en arrière-plan après avoir envoyé la quatrième tâche et mettre le script en attente jusqu'à la fin des tâches ? Je veux dire, simplement envoyer une nouvelle tâche en arrière-plan à la fin d'une tâche, en gardant toujours 4 tâches en parallèle? si je ne le fais pas, la boucle déclenchera des millions de tâches en arrière-plan et le processeur se bloquera.
Réponse acceptée :
Si vous avez une copie de xargs
qui prend en charge l'exécution parallèle avec -P
, vous pouvez simplement faire
printf '%s