Gestion de scripts et de processus de bash multithreads sur la ligne de commande

Gestion de scripts et de processus de bash multithreads sur la ligne de commande

Les choses que vous pouvez faire en utilisant un script bash sont illimitées. Une fois que vous commencerez à développer des scripts avancés, vous constaterez bientôt que vous commencerez à vous présenter aux limites du système d'exploitation. Par exemple, votre ordinateur a-t-il 2 threads CPU ou plus (de nombreuses machines modernes ont 8 à 32 threads)? Si c'est le cas, vous bénéficierez probablement de scripts et de codage multipliés. Continuez à lire et découvrez pourquoi!

Dans ce tutoriel, vous apprendrez:

  • Comment implémenter des doublures bash multiples directement à partir de la ligne de commande
  • Pourquoi le codage multithread peut presque toujours et augmentera les performances de vos scripts
  • Comment fonctionnent les processus de fond et de premier plan et comment manipuler les files d'attente
Gestion de scripts et de processus de bash multithread

Exigences et conventions logicielles utilisées

Exigences logicielles et conventions de ligne de commande Linux
Catégorie Exigences, conventions ou version logicielle utilisée
Système Indépendant de la distribution, dépendant de la version Bash
Logiciel Interface de ligne de commande bash (frapper)
Conventions # - Exige que les commandes Linux soient exécutées avec des privilèges racine soit directement en tant qu'utilisateur racine, soit par l'utilisation de Sudo commande
$ - Exige que les commandes Linux soient exécutées en tant qu'utilisateur non privilégié régulier

Lorsque vous exécutez un script bash, il sera au maximum d'utiliser un seul thread CPU, sauf si vous démarrez les sous-coquilles / threads. Si votre machine a au moins deux threads CPU, vous pourrez maximiser les ressources CPU en utilisant des scripts multipliés en bash. La raison en est simple; Dès qu'un «thread» secondaire (lecture: sous-shell) est démarré, ce thread ultérieur peut (et souvent) utiliser un fil CPU différent.

Supposons un instant que vous avez une machine moderne avec 8 fils ou plus. Pouvez-vous commencer à voir comment si nous serions en mesure d'exécuter du code - huit threads parallèles en même temps, chacun exécutant sur un thread CPU différent (ou partagé sur tous les threads) - de cette façon, il exécuterait beaucoup plus rapidement que un seul thread processus en cours d'exécution sur un seul thread CPU (qui peut être co-partagé avec d'autres processus en cours))? Les gains réalisés dépendront un peu de ce qui est exécuté, mais les gains y seront presque toujours!

Excité? Super. Plongeons-y.

Nous devons d'abord comprendre ce qu'est une sous-coquille, comment elle est démarrée, pourquoi vous en utiliseriez un et comment il peut être utilisé pour implémenter le code bash multithread.

Une sous-coquille est un autre processus client de bash exécuté / démarré à partir de la présence actuelle. Faisons quelque chose de facile et commençons un à partir d'une invite de terminal de bash ouverte:

$ bash $ exit exit $ 

Que s'est-il passé ici? Nous avons d'abord commencé une autre coquille de bash (frapper) qui a commencé et à son tour a donné une invite de commande ($). Alors le second $ Dans l'exemple ci-dessus est en fait une coquille de bash Piquer (Piquer est l'identifiant de processus; Un identifiant de nombre unique qui identifie de manière unique chaque processus de course dans un système d'exploitation). Enfin, nous sommes sortis de la sous-coquille via sortie et retourné à la sous-coque parent! Pouvons-nous en quelque sorte la preuve que c'est vraiment ce qui s'est passé? Oui:

$ echo 220250 $ $ bash $ echo 222629 $ 

Il y a une variable spéciale dans Bash $$, qui contient le Piquer du shell actuel utilisé. Pouvez-vous voir comment l'identifiant de processus a changé une fois que nous étions à l'intérieur d'une sous-coquille?

Super! Maintenant que nous savons ce que sont les sous-coquilles et un peu sur la façon dont ils fonctionnent, plongeons dans des exemples de codage multi-thread et en apprenons plus!

Multi-threading simple en bash

Commençons par un simple exemple multi-thread en une ligne, dont la sortie peut sembler un peu déroutante au début:

$ pour i en $ (Seq 1 2); faire écho $ i; fait 1 2 $ pour I en $ (Seq 1 2); faire echo $ i & Done [1] 223561 1 [2] 223562 2 $ [1] - DID ECHO $ ​​I [2] + fait echo $ i $ 

En premier pour LOOP (Voir notre article sur Bash Loops pour apprendre à coder les boucles
), nous publions simplement la variable $ i qui va de 1 à 2 (en raison de notre utilisation de la commande SEQ), ce qui - intéressant - est démarré dans une sous-coquille!

NOTE
Vous pouvez utiliser le $ (…) syntaxe partout Dans une ligne de commande pour démarrer une sous-coquille: c'est un moyen très puissant et polyvalent de coder les sous-coquilles directement dans d'autres lignes de commande!

Dans la seconde pour Loop, nous n'avons changé qu'un seul personnage. À la place d'utiliser ; - Un idiom de syntaxe Bash EOL (fin de ligne) qui met fin à une commande donnée (vous pouvez y penser comme entrer / exécuter / aller avant), nous avons utilisé &. Ce changement simple fait un programme presque complètement différent, et notre code est désormais multithread! Les deux Echo traiteront plus ou moins en même temps, avec un petit délai dans le système d'exploitation, ayant encore à exécuter la deuxième ligne de boucle (pour écho '2').

Vous pouvez penser à & d'une manière similaire à ; avec la différence que & Dira au système d'exploitation de «continuer à exécuter la commande suivante, continuez à traiter le code» alors que ; Attendra la commande d'exécution actuelle (terminée par ;) pour se terminer / terminer avant de revenir à l'invite de commande / avant de continuer à traiter et à exécuter le code suivant.

Examinons maintenant la sortie. Nous voyons:

[1] 223561 1 [2] 223562 2 $ 

Au début, suivi de:

[1] - fait echo $ i [2] + fait echo $ i $ 

Et il y a aussi une ligne vide entre les deux, qui est le résultat de processus d'arrière-plan toujours en cours en attendant l'entrée de commande suivante (essayez cette commande à quelques fois sur la ligne de commande, ainsi que quelques variations lumineuses, et vous obtiendrez un Sentez comment cela fonctionne).

La première sortie ([1] 223561) nous montre qu'un processus de fond a été démarré, avec PID 223561 et le numéro d'identifiant 1 y a été donné. Ensuite, déjà avant que le script n'atteigne le deuxième écho (un écho étant probablement une instruction de code coûteuse à exécuter), la sortie 1 a été montré.

Notre processus d'arrière-plan n'a pas terminé complètement car la sortie suivante indique que nous avons commencé une deuxième sous-coquille / thread (comme indiqué par [2]) avec pid 223562. Par la suite, le deuxième processus sort le 2 («Indicative»: les mécanismes du système d'exploitation peuvent affecter cela) avant que le deuxième thread finalise.

Enfin, dans le deuxième bloc de sortie, nous voyons les deux processus se terminer (comme indiqué par Fait), ainsi que ce qu'ils exécutaient en dernier (comme indiqué par echo $ i). Notez que les mêmes nombres 1 et 2 sont utilisés pour indiquer les processus d'arrière-plan.

Plus de multi-threading à bash

Ensuite, exécutons trois commandes de sommeil, toutes terminées par & (ils commencent donc comme des processus d'arrière-plan) et faisons varier leur durée de sommeil, nous pouvons donc plus clairement voir comment fonctionne le traitement en arrière-plan.

$ Sleep 10 & Sleep 1 & Sleep 5 & [1] 7129 [2] 7130 [3] 7131 $ [2] - Done Sleep 1 $ [3] + Done Sleep 5 $ [1] + Done Sleep 10 

La sortie dans ce cas devrait être explicite. La ligne de commande revient immédiatement après notre Sleep 10 & Sleep 1 & Sleep 5 & La commande et les 3 processus d'arrière-plan, avec leurs PID respectifs, sont affichés. J'appuie entre plusieurs fois. Après 1 seconde, la première commande a terminé en donnant le Fait pour l'identifiant de processus [2]. Par la suite, le troisième et premier processus s'est terminé, selon leurs durées de sommeil respectives. Notez également que cet exemple montre clairement que plusieurs travaux fonctionnent efficacement, simultanément, en arrière-plan.

Vous avez peut-être également ramassé le + Connectez-vous dans les exemples de sortie ci-dessus. Il s'agit de contrôle du travail. Nous examinerons le contrôle de l'emploi dans l'exemple suivant, mais pour le moment il est important de comprendre que + indique le travail qui sera contrôlé si nous devions utiliser / exécuter des commandes de contrôle de travail. C'est toujours le travail qui a été ajouté à la liste des travaux de course plus récemment. C'est le travail par défaut, qui est toujours celui récemment ajouté à la liste des emplois.

UN - indique le travail qui deviendrait le prochain par défaut pour les commandes de contrôle du travail si le travail actuel (le travail avec le + signe) se terminerait. Le contrôle des travaux (ou en d'autres termes; manipulation du fil d'arrière-plan) peut sembler un peu intimidant au début, mais il est en fait très pratique et facile à utiliser une fois que vous vous y êtes habitué. Plongeons-nous dans!

Contrôle d'emploi à Bash

$ Sleep 10 & Sleep 5 & [1] 7468 [2] 7469 $ Jobs [1] - Running Sleep 10 & [2] + Running Sleep 5 & $ fg 2 Sleep 5 $ fg 1 sommeil 10 $ 

Ici, nous avons placé deux sommets en arrière-plan. Une fois qu'ils ont commencé, nous avons examiné les travaux en cours d'exécution en utilisant le emplois commande. Ensuite, le deuxième fil a été placé au premier plan en utilisant le FG commande suivie du numéro de travail. Vous pouvez y penser comme ça; le & dans le sommeil 5 la commande a été transformée en un ;. En d'autres termes, un processus de fond (non attendu) est devenu un processus de premier plan.

Nous avons ensuite attendu le sommeil 5 commande pour finaliser et placer par la suite le sommeil 10 commander au premier plan. Notez que chaque fois que nous l'avons fait, nous devions attendre que le processus de premier plan se termine avant de recevoir notre ligne de commande, ce qui n'est pas le cas lorsque vous utilisez uniquement des processus d'arrière-plan (car ils fonctionnent littéralement en arrière-plan)).

Contrôle des emplois en bash: interruption du travail

$ sleep 10 ^ z [1] + arrêt de sommeil 10 $ bg 1 [1] + sommeil 10 & $ fg 1 sommeil 10 $ 

Ici, nous appuyons sur Ctrl + Z pour interrompre un sommeil en cours d'exécution 10 (qui s'arrête comme indiqué par Arrêté). Nous plaçons ensuite le processus en arrière-plan et l'avons finalement placé au premier plan et attendons qu'il termine.

Contrôle des emplois en bash: interruption du travail

$ sleep 100 ^ z [1] + arrêt de sommeil 100 $ tuer% 1 $ [1] + terminer le sommeil 100 

Ayant commencé 100 secondes dormir, Nous interrompons ensuite le processus en cours d'exécution par Ctrl + Z, puis tuons le premier processus de fond démarré / exécuté en utilisant le tuer commande. Notez comment nous utilisons %1 Dans ce cas, au lieu de simplement 1. En effet FG et bg sont. Ainsi, pour indiquer à tuer que nous voulons effectuer le premier processus de fond, nous utilisons % suivi par le numéro de processus de fond.

Contrôle des emplois en bash: ren renouvelage du processus

$ sleep 100 ^ z [1] + arrêt de sommeil 100 $ bg% 1 [1] + sommeil 100 & $ Diet 

Dans cet dernier exemple, nous terminons à nouveau une course dormir, et le placer en arrière-plan. Enfin nous exécutons le renier Commande que vous pouvez lire comme: dissocier tous les processus d'arrière-plan (travaux) à partir du shell actuel. Ils continueront de fonctionner, mais ne sont plus «détenus» par le shell actuel. Même si vous fermez votre coquille et votre déconnexion actuelles, ces processus continueront de fonctionner jusqu'à ce qu'ils se terminent naturellement.

Ceci est un moyen très puissant d'interrompre un processus, de le placer en arrière-plan, de le renier puis de se déconnecter de la machine que vous utilisiez, à condition que vous n'ayez plus besoin d'interagir avec le processus. Idéal pour ces processus de longue date sur SSH qui ne peuvent pas être interrompus. Simplement Ctrl + z Le processus (qui l'interrompt temporairement), le placer dans l'arrière-plan, le renoncer à tous les travaux et la déconnexion! Rentrez à la maison et passez une bonne soirée détendue en sachant que votre travail continuera de courir!

Exemples de ligne de commande de scripts et de gestion de processus multipliés

Conclusion

Dans ce didacticiel, nous avons vu comment implémenter des doublures bash multiples directement à partir de la ligne de commande et explorer pourquoi le codage multi-thread augmente souvent les performances de vos scripts. Nous avons également examiné le fonctionnement des processus de formation et de premier plan, et nous avons manipulé les files d'attente. Enfin, nous avons exploré comment renier notre file d'attente d'emploi à partir du processus actuel, nous fournissant un contrôle supplémentaire sur les processus en cours d'exécution. Profitez de vos nouvelles compétences trouvées et laissez-nous un commentaire ci-dessous avec vos expériences de contrôle du travail!

Tutoriels Linux connexes:

  • Une introduction à l'automatisation Linux, des outils et des techniques
  • Choses à installer sur Ubuntu 20.04
  • Choses à faire après l'installation d'Ubuntu 20.04 Focal Fossa Linux
  • Masterring Bash Script Loops
  • Gestion des processus de fond de bash
  • Boucles imbriquées dans les scripts bash
  • Ubuntu 20.04 Guide
  • Choses à faire après l'installation d'Ubuntu 22.04 Jammy Jellyfish…
  • Exemples de lignes de commande de commande de bash utile - Partie 6
  • Tutoriel de débogage GDB pour les débutants