Outils et concepts système

Nous allons aborder ici les différentes formes que peuvent prendre des tâches sur les environnements qui nous intéressent : les machines personnelles et les clusters de calcul.

Qu est ce qu un processus ? Qu est ce qu un job ?

On parle souvent de calcul, de traitement, de pipeline, de chaînage d'opérations. Ces termes sont assez abstraits. Dans ce chapitre nous allons rapidement voir ce que sont les processus et les jobs. Ces concepts sont utiles pour la suite quand seront abordés les thèmes de la performance, de la parallélisation, des processeurs multicœurs...

programme, binaire, script

Derrière tous ces termes se cache la notion de programme. Un programme est une suite d'instructions stockées dans une mémoire dure. Ces instructions peuvent être écrites en langage machine, on appelle ça un binaire, et peuvent aussi être écrites en langage de plus haut niveau destiné à être interprété, on appelle ça un script.

Un script est une sorte de programme mais il dépend d'un interpréteur (sous forme de binaire le plus souvent).

Un binaire peut être lié à des librairies (fichiers contenant des fonctions) sur le système. On appelle cela un binaire dynamique puisqu'il va chercher dynamiquement au moment de l'exécution les fonctions auxquelles il est lié sur le système.

Un binaire peut aussi contenir toutes les fonctions/librairies dont il dépend, on appelle cela un binaire statique (par conséquent, le fichier est plus gros).

Lancer un programme ou un script en tâche de fond (background)

En bash, on peut lancer une commande en arrière plan, c'est à dire que cette commande ne va pas occuper le shell interactif pendant sont exécution. Elle va rendre la main à l'utilisateur mais elle continue à s'exécuter.

sleep 120 &
jobs
fg %1
bg %1

processus

Un processus est un programme en cours d'exécution. C'est à dire une copie "vivante" du programme sur la mémoire vive.

principe général

Lorsqu'on "lance" ou "exécute" un programme, il est copié depuis la mémoire dure (disque dur ou autre) sur la mémoire vive depuis laquelle le processeur va lire et suivre les instructions. La mémoire vive ne sert pas qu'à accueillir les images des programmes, le système d'exploitation y place aussi les variables utilisées pendant l'exécution. Donc pour être plus précis, un processus est un programme en cours d'exécution matérialisé par une zone (isolée) en RAM contenant les instructions et les variables. Si on lance deux fois le même programme, on produit deux processus donc deux espaces étanches dans la mémoire vive. Un processus ne peut modifier que ses propres variables, c'est à dire celles qui sont dans sa zone mémoire.

Un processeur classique simple a une vitesse limitée et ne peut effectuer qu'une opération à la fois. Pourtant une machine est capable d'exécuter simultanément plusieurs processus qui demandent plus de puissance que le processeur n'est capable d'en donner. C'est au niveau des processus que se joue le partage du processeur dans un système d'exploitation. Ce dernier tente d'allouer un temps d'exécution à chaque processus actif de telle sorte qu'aucun d'entre eux ne se trouve bloqué trop longtemps. On peut appeller cela de la pseudo-parallélisation des processus. A un instant T, un seul processus "tourne" mais sur une échelle de temps plus grande, tous les processus se font allouer du temps processeur.

threads

Un programme est une succession d'opérations séquentielles en cours d'exécution sur le système. Cependant, certains programmes ont besoin de faire plusieurs choses à la fois. Par exemple, un programme de messagerie instantanée doit pouvoir envoyer et recevoir des messages simultanément. La technique la plus répandue pour satisfaire le besoin d'exécution parallèle au sein d'un même programme/processus est le thread.

Un thread peut être vu comme un sous-processus. Si un processus est composé de plusieurs threads, lorsque ce processus dispose du processeur, le système va partager le temps d'accès au processeur entre les threads. Lorsqu'on programme en multithread on doit faire très attention au fait que tous les threads accèdent à la même mémoire donc aux mêmes variables. Il existe des outils pour gérer les accès concurrentiels à la mémoire et des techniques de programmation pour éviter de se retrouver dans des cas de figure bloquants.

La programmation multithreadée est plus détaillée dans le chapitre concernant la parallélisation.

multicoeur

Un processeur multicoeur est capable d'effectuer plusieurs opération en même temps, autant qu'il a de coeurs. Les systèmes d'exploitation modernes sont capables d'utiliser cette faculté du processeur pour faire fonctionner plusieurs processus en même temps. Cette fois ci, le temps du processeur n'est plus forcément partagé entre plusieurs processus, il peut éventuellement être dédié à un processus.

Au sein d'un processus multithreadé, plusieurs threads peuvent fonctionner en même temps sur des coeurs différents.

Du point de vue de l'utilisateur, l'effet observé est surtout une augmentation de performance. La façon de programmer, de lancer ses programmes, de gérer ses processus est identique sur un processeur monocoeur et multicoeur.

Certains programmes proposent de définir le nombre de threads qu'ils vont créer. Libre à l'utilisateur de choisir une valeur adaptée au nombre de coeur et à la charge potentielle de ces coeurs.

job

Un job est une entité qui englobe la notion de processus. Un job est plus conceptuel, plus abstrait qu'un processus. Il prend forme dans un système de gestion de cluster et sera conçu différemment suivant les clusters. Un job est exécuté sur un noeud de calcul, il ne va donc pas produire de processus sur le noeud maitre mais le ou les noeuds de calculs.

Un job est la combinaison de deux informations :

  • La liste de commandes à exécuter
  • La liste d'options

Outils système : top, ps, pstree, kill, killall

les top-like

C'est une famille d'outils qui donnent des indications en temps réel sur l'utilisation d'une ressource.

Le seul top-like installé par défaut sur les systèmes UNIX est "top".

les top-processus

Les outils suivant affichent des informations sur les processus en cours d'exécution. Le tri par défaut est le pourcentage d'utilisation du processeur.

  • top est présent de base sur tout système GNU/Linux.
  • htop : interface colorée et interactive de top. Il vous faudra l'installer sur votre machine.

autres top

  • iftop : montre toutes les connexions réseau triées par débit
  • iotop : montre les processus qui accèdent au disque dur, triés par débit de transfert (pas sur le cluster)
  • htop : on peut trier les processus par pourcentage d'utilisation de la RAM et plein d'autres critères !

ps

Avec la commande ps, on obtient la liste des processus sur la machine. Par défaut, on ne voit que ses propres processus, pour voir tous les processus :

ps aux

Pour voir combien de fois bash tourne sur la machine :

ps aux | grep bash | wc -l

pstree

pstree et une représentation graphique (en texte) de l'arbre des processus sur la machine. Il est utile pour bien comprendre le lien de parenté entre les processus.

On peut par exemple trouver le processus parent d'un processus très facilement avec :

pstree | grep --color -n5 firefox

qui va afficher 5 lignes avant et 5 lignes après la ligne qui contient "firefox".

pgrep

pgrep renvoie la liste de PID dont le nom (ou autre attribut) correspond au motif donné en entrée. Par exemple :

pgrep python

renvoie les pids de tous les processus qui contiennent "python" dans leur nom ou dans la ligne de commande de lancement.

kill

kill est un faux ami. Il ne sert pas à "tuer" mais à communiquer avec un processus par un SIGNAL.

On peut envoyer le signal KILL à un processus avec l'option -9 :

kill -9 12345

L'envoi du signal d'extinction est tout de même l'utilisation la plus courante de kill.

killall

killall essaie de tuer tous les processus dont le nom contient un motif :

killall firefox

essaiera de tuer les instances de grep.

Exercices outils système

  • Lancez un "sleep 15000" et essayez de le tuer avec un deuxième terminal en une ligne en utilisant les commandes ps, grep, kill et awk. (indice : attention au processus produit par grep dont le nom contient sleep lui aussi)

INDICE Avec grep, on filtre la sortie de ps, ensuite on enleve la ligne qui contient grep puis on prend juste la 2e colonne.

INDICE Pour afficher la deuxième colonne avec awk :

echo "prem    deux     trois" | awk '{print $2}'
  • Lancez dix fois la commande précédente (sleep), avec 300 secondes au lieu 15000, en arrière plan :

INDICE : Dans une boucle, pour lancer une commande en arrière plan, on l'entoure de parenthèse pour que le '&' ne soit pris en compte que pour la commande et pas pour la boucle.

et vérifiez si votre kill précédent fonctionne aussi.

  • La commande "ps -ef" affiche en troisième colonne le PPID (PID du parent). A l'aide de cette information, trouvez le nom du processus parent de firefox.

  • Trouvez quel est le processus qui vous prend le plus de mémoire vive avec ps, sort et head.

INDICE Regardez dans le man de "sort" pour trouver le tri par colonne