2010-03-11 6 views
60

Je voudrais introduire la fonction multithreading dans mon script shell.Multithreading in Bash

J'ai un script qui appelle la fonction read_cfg() avec différents arguments. Chacun de ces appels de fonction est indépendant.

Serait-il possible d'instancier ces appels de fonction (pas de scripts) parallèlement. S'il vous plaît laissez-moi comment pouvons-nous atteindre cela ..?

+0

Ce ne multithreading - c'est multitraitement. Chaque instance est exécutée dans un processus distinct, copié de l'original avec 'fork()'. Contrairement aux threads, ces processus possèdent leurs propres tables de descripteurs de fichiers et leur mémoire est une copie à l'écriture (ainsi, lorsqu'ils modifient la valeur d'une variable, le processus parent ne la voit pas). –

Répondre

127

Bien sûr, il suffit d'ajouter & après la commande:

read_cfg cfgA & 
read_cfg cfgB & 
read_cfg cfgC & 
wait 

tous ces emplois seront alors en arrière-plan simultanément. La commande wait facultative attendra que tous les travaux se terminent.

Chaque commande s'exécutera dans un processus séparé, donc techniquement ce n'est pas "multithread", mais je crois que cela résout votre problème.

+6

Vous devriez lire la différence entre le processus et le fil. Ce que vous proposez n'est pas multithread - il implique des processus distincts pour chaque commande. – TomTom

+24

@TomTom: Je connais certainement la différence entre les processus et les threads. Si vous voyez à travers le choix des mots de l'OP, je crois qu'il demande simplement s'il est possible d'exécuter les commandes en parallèle (ce qui est possible). J'ai ajouté une note à ce sujet pour clarifier. – Martin

19

Le contrôle de travail Bash implique plusieurs processus, pas plusieurs threads.

Vous pouvez exécuter une commande en arrière-plan avec le suffixe &.

Vous pouvez attendre la fin d'une commande d'arrière-plan avec la commande wait. Vous pouvez exécuter plusieurs commandes en parallèle en les séparant par |. Cela fournit également un mécanisme de synchronisation, puisque stdout d'une commande à gauche de | est connecté à stdin de commande à droite.

23

Vous pouvez exécuter plusieurs copies de votre script en parallèle, chaque copie pour différentes données d'entrée, par ex. pour traiter tous les fichiers * .cfg sur 4 cœurs:

ls *.cfg | xargs -P 4 -n 1 read_cfg.sh 

Le script read_cfg.sh prend seulement un des paramètres (comme appliqué par -n)

+2

juste une note que vous devez spécifier le chemin complet de 'read_cfg.sh' ou' xargs' dira qu'il ne peut pas trouver le fichier. – Jeshurun

+0

Mieux vaut utiliser 'printf '% s \ 0' * .cfg | xargs -0 ... 'de cette façon cela fonctionne avec des noms de fichiers avec des espaces, des caractères non imprimables, etc. Voir aussi [Pourquoi vous ne devriez pas analyser la sortie de ls (1)] (http://mywiki.wooledge.org/ParsingLs). –