web-dev-qa-db-fra.com

Exécution de programmes en parallèle avec xargs

J'ai actuellement le script actuel.

#!/bin/bash
# script.sh

for i in {0..99}; do
   script-to-run.sh input/ output/ $i
done

Je souhaite le lancer en parallèle en utilisant xargs. j'ai essayé

script.sh | xargs -P8

Mais faire ce qui précède n’est exécuté qu’une fois à la fois. Pas de chance avec -n8 aussi. Ajouter & à la fin de la ligne à exécuter dans le script de boucle essaierait d’exécuter le script 99 fois à la fois. Comment puis-je exécuter la boucle que 8 à la fois, jusqu'à 100 au total.

62
Olivier

De la page de manuel xargs:

Cette page de manuel décrit la GNU de xargs. Xargs lit les éléments de l’entrée standard, délimités par des blancs (pouvant être protégés par des guillemets simples ou doubles ou par une barre oblique inverse) ou une nouvelle ligne, puis exécute le commande (la valeur par défaut est/bin/echo) une ou plusieurs fois avec les arguments initiaux suivis des éléments lus à partir de l'entrée standard.Les lignes vides de l'entrée standard sont ignorées.

Ce qui signifie que pour votre exemple, xargs attend et collecte toutes les sorties de votre script, puis exécute echo <that output>. Pas vraiment utile ni ce que tu voulais.

Le -n argument est le nombre d'éléments de l'entrée à utiliser avec chaque commande exécutée (rien, seul, sur le parallélisme ici).

Pour faire ce que vous voulez avec xargs, vous devez faire quelque chose de plus semblable à ceci (non testé):

printf %s\\n {0..99} | xargs -n 1 -P 8 script-to-run.sh input/ output/

Ce qui tombe en panne comme ça.

  • printf %s\\n {0..99} - Imprime un numéro par ligne à partir de 0 à 99.
  • Exécutez xargs
    • en prenant au plus un argument par ligne de commande
    • et lancez jusqu'à huit processus à la fois
92
Etan Reisner

Avec GNU en parallèle, vous feriez:

parallel script-to-run.sh input/ output/ {} ::: {0..99}

Ajouter à -P8 si vous faites pas voulez exécuter un travail par cœur de processeur.

Ci-contre xargs il fera The Right Thing, même si l’entrée contient de l’espace, 'ou "(ce qui n’est pas le cas ici). Cela permet également de ne pas mélanger les sorties de différents travaux, vous utilisez la sortie qui vous garantit que vous ne recevrez pas une demi-ligne de deux emplois différents.

GNU Parallel est un paralléliseur général. Il est facile d’exécuter des tâches en parallèle sur la même machine ou sur plusieurs machines auxquelles vous avez accès ssh.

Si vous souhaitez exécuter 32 tâches différentes sur 4 processeurs, un moyen simple de paralléliser consiste à exécuter 8 tâches sur chaque processeur:

Simple scheduling

Au lieu de cela, GNU Parallel génère un nouveau processus, ce qui permet de garder les processeurs actifs et de gagner du temps:

GNU Parallel scheduling

Installation

Si GNU Parallel n'est pas empaqueté pour votre distribution, vous pouvez faire une installation personnelle, qui ne nécessite pas d'accès root. Cela peut être fait en 10 secondes en procédant comme suit:

$ (wget -O - pi.dk/3 || lynx -source pi.dk/3 || curl pi.dk/3/ || \
   fetch -o - http://pi.dk/3 ) > install.sh
$ sha1sum install.sh | grep 3374ec53bacb199b245af2dda86df6c9
12345678 3374ec53 bacb199b 245af2dd a86df6c9
$ md5sum install.sh | grep 029a9ac06e8b5bc6052eac57b2c3c9ca
029a9ac0 6e8b5bc6 052eac57 b2c3c9ca
$ sha512sum install.sh | grep f517006d9897747bed8a4694b1acba1b
40f53af6 9e20dae5 713ba06c f517006d 9897747b ed8a4694 b1acba1b 1464beb4
60055629 3f2356f3 3e9c4e3c 76e3f3af a9db4b32 bd33322b 975696fc e6b23cfb
$ bash install.sh

Pour d'autres options d'installation, voir http://git.savannah.gnu.org/cgit/parallel.git/tree/README

En savoir plus

Voir plus d'exemples: http://www.gnu.org/software/parallel/man.html

Regardez les vidéos d'introduction: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

Parcourez le didacticiel: http://www.gnu.org/software/parallel/parallel_tutorial.html

Inscrivez-vous à la liste de diffusion pour obtenir de l'aide: https://lists.gnu.org/mailman/listinfo/parallel

54
Ole Tange