GNU/Linux >> Tutoriels Linux >  >> Linux

Présentation du processus UNIX (à l'intérieur d'un processus Linux et types de processus)

Un processus est une instance en cours d'exécution d'un programme. Dans cet article, nous avons utilisé deux termes « programme » et « instance en cours d'exécution ». Supposons que nous exécutons un programme simultanément 5 fois, puis correspondant à chaque instance, il y aura un processus en cours d'exécution dans le système. Nous disons donc qu'un processus est une "instance en cours d'exécution" d'un programme.

Comme vous le savez déjà, vous pouvez utiliser la commande ps pour afficher les processus en cours d'exécution sur votre système. Pour une utilisation efficace de la commande ps, reportez-vous à 7 exemples pratiques de commande PS pour la surveillance de processus.

1. Regarder à l'intérieur d'un processus

Maintenant, puisque nous savons clairement ce qu'est exactement un processus, creusons un peu plus pour voir en quoi consiste un processus. Un processus Unix peut être considéré comme un conteneur qui contient :

Instructions du programme

Les instructions de programme sont conservées dans des segments de texte qui sont exécutés par la CPU. Habituellement, pour les programmes tels que les éditeurs de texte qui sont exécutés fréquemment, le segment de texte est partagé. Ce segment a des privilèges en lecture seule, ce qui signifie qu'un programme ne peut pas modifier son segment de texte.

Données

La plupart du temps, les données sont conservées dans le segment de données. Le segment de données peut être classé en segment de données initialisé et segment de données non initialisé. Comme son nom l'indique, le segment de données initialisé contient les variables globales initialisées au préalable, tandis que le segment de données non initialisé (également appelé segment "BSS") contient des variables globales non initialisées. De plus, les variables statiques sont stockées dans le segment de données.

Les variables locales qui sont locales aux fonctions sont stockées sur la pile. Stack est particulier à une fonction et en plus de contenir les informations sur les variables locales, il contient également des informations sur l'adresse où le flux reviendra une fois l'exécution de la fonction terminée. Stack contient également des informations sur l'environnement des appelants, comme certains des registres de la machine sont également stockés sur la pile. Une fonction appelée alloue de la mémoire pour ses variables locales et ses variables temporaires sur la pile elle-même. En cas de fonction récursive, une pile indépendante pour chaque appel de fonction existe.

Ensuite, il y a les données qui sont stockées sur le tas. Cette mémoire pour ces données est allouée lors de l'exécution sur le segment de tas. Le segment de tas n'est pas local à un processus mais partagé entre les processus. C'est la raison pour laquelle les programmeurs C s'inquiètent beaucoup des fuites de mémoire qui sont causées sur le segment de tas et peuvent affecter d'autres processus sur le système.

Arguments de ligne de commande et variables d'environnement

Un processus contient également de la place pour stocker les variables d'environnement et les arguments de ligne de commande que nous transmettons au programme. Habituellement, le vecteur contenant les informations de la ligne de commande est stocké ici, puis l'adresse de ce vecteur d'informations et le nombre d'éléments dans le vecteur sont copiés dans 'argv' et 'argc' (les deux arguments de la fonction 'main()').

Outre les informations ci-dessus, un processus contient également des informations telles que

  • État de ses E/S
  • Sa priorité et d'autres informations de contrôle

Les privilèges sont l'une des informations de contrôle les plus importantes pour un processus. Un processus hérite directement de tous les privilèges de l'utilisateur qui a déclenché ce processus. Par exemple, un processus déclenché par un utilisateur qui ne dispose pas de privilèges de superutilisateur ne peut pas effectuer de tâches nécessitant des privilèges root, tandis qu'un processus déclenché par root peut effectuer tout ce pour quoi il est programmé. Une exception à la règle ci-dessus est lorsqu'un processus peut acquérir des privilèges plus importants que l'utilisateur qui l'a déclenché si le bit setuid ou setgid est défini pour ce processus particulier. Mais nous n'entrerons pas dans les détails à ce sujet ici (reportez-vous aux pages de manuel de setuid et setgid pour plus d'informations à ce sujet).

2. Processus d'arrière-plan et d'avant-plan

Comme nous l'avons déjà dit, nous pouvons démarrer un processus par son nom sous Unix. Comme certains programmes standard, "ls", "ps", etc. peuvent être démarrés en tapant simplement leur nom à l'invite du shell. Il y a deux façons de démarrer un processus

  • Commencer au premier plan
  • Démarrage en arrière-plan

Supposons qu'il existe un utilitaire qui consomme du temps et effectue un comptage. Disons que le nom de l'utilitaire est 'count' Maintenant, pour déclencher et exécuter le programme au premier plan, j'exécute la commande suivante (où 'count' est le nom du binaire du code ci-dessus) :

$ ./count
Counting done

Nous voyons donc qu'après avoir exécuté le binaire './count', il a fallu près de 10 secondes avant que la sortie ne soit affichée sur stdout et jusque-là, le shell n'était occupé que par ce processus. c'est-à-dire que vous ne pouvez effectuer aucune autre opération sur le même shell. Maintenant, pour déclencher un processus en arrière-plan, ajoutez '&' à la fin de la commande :

$ ./count &
[1] 4120

$ # Do some work on shell while the above program is working in the background

$ Counting done

Le signe "&" esperluette indique que ce processus doit être exécuté en arrière-plan. En exécutant un processus en arrière-plan, nous pouvons avoir accès au shell pour effectuer d'autres opérations. Comme, dans la sortie ci-dessus, après avoir exécuté le 'count' binaire en arrière-plan, j'ai utilisé quelques commandes supplémentaires sur le même shell et lorsque le 'count' binaire a été terminé avec son traitement, la sortie a été renvoyée sur le même shell (la dernière ligne). Nous pouvons donc conclure que par défaut, chaque processus s'exécute au premier plan, reçoit une entrée (le cas échéant) du clavier et renvoie la sortie à l'utilisateur. Alors qu'un processus en arrière-plan est un processus qui se déconnecte du clavier, l'utilisateur peut utiliser le même shell pour effectuer plus d'opérations.

Pour plus d'informations sur les processus de premier plan et d'arrière-plan, reportez-vous à :Comment gérer les tâches d'arrière-plan UNIX

3. Types de processus

Nous voyons donc que le processus est un concept fondamental pour un système d'exploitation. Presque toutes les activités sur un système d'exploitation prennent la forme d'un processus pour faire certaines choses. Il existe différents types de processus en cours d'exécution sur un système, certains d'entre eux sont :

Processus enfants

Processus créé par un autre processus pendant l'exécution. Habituellement, les processus enfants sont créés pour exécuter des binaires à partir d'un processus existant. Les processus enfants sont créés à l'aide de l'appel système fork(). Normalement, les processus sont conçus pour s'exécuter via le shell/terminal. Dans ce cas, le shell devient le parent et le processus exécuté devient le processus enfant. Sur Unix/Linux, chaque processus a un parent à l'exception du processus init (nous en apprendrons plus tard).

Processus démons

Ce sont des processus spéciaux qui s'exécutent en arrière-plan. Ce sont des processus liés au système qui n'ont pas de terminal associé. Ces processus exécutent des autorisations root et fournissent généralement des services aux processus. Comme nous savons déjà qu'un processus démon n'a pas de terminal attaché, eh bien, pour y parvenir, le processus doit être détaché du terminal. Le moyen idéal sous Linux/Unix pour ce faire est d'exécuter un processus via un terminal et à partir de ce processus, de créer un autre processus, puis de terminer le processus parent. Puisque le parent est résilié, l'enfant deviendra alors indépendant du terminal et sera pris en charge par le processus init et deviendra donc un processus démon. Un exemple typique serait un démon de messagerie qui attend l'arrivée des e-mails et avertit lorsqu'un e-mail est reçu.

Processus orphelins

Habituellement, un processus crée un processus enfant (comme décrit ci-dessus) et lorsque le processus enfant se termine, un signal est envoyé au parent afin que le parent puisse faire tout ce qu'il doit faire lorsque l'un des enfants est terminé. Mais il y a des situations où le parent est tué. Dans ce cas, les processus fils deviennent orphelins puis repris par le processus init. Bien que le processus init s'approprie le processus orphelin, ces processus sont néanmoins appelés orphelins car leurs parents d'origine n'existent plus.

Processus zombie

Lorsqu'un processus enfant est terminé ou termine son exécution, son entrée dans la table des processus reste jusqu'à ce que le processus parent récupère les informations d'état de l'enfant terminé. Ainsi, jusque-là, le processus terminé entre dans l'état zombie et est appelé processus zombie. Lorsqu'un processus est terminé, toute la mémoire et les ressources associées au processus sont libérées, mais l'entrée du processus dans la table des processus existe. Un signal SIGCHILD est envoyé au parent du processus (qui vient de se terminer). En règle générale, le gestionnaire de ce signal dans le parent exécute un appel "wait" qui récupère l'état de sortie du processus terminé, puis l'entrée de ce processus zombie de la table des processus est également supprimée.

4. Le processus d'initialisation

Comme nous l'avons vu précédemment, le processus init est la 5e étape de la 6e étape du processus de démarrage Linux.

Vous seriez au courant de la fameuse théorie de la «poule et de l'œuf» concernant qui est venu en premier. En termes de processus, comme chaque processus a un processus parent, la même question peut être posée sur le processus parent ou enfant. Eh bien, heureusement, il y a une réponse ici. La réponse est le processus init qui est lancé en tant que premier processus pendant la séquence de démarrage. Cela signifie qu'il n'y a pas de parent du processus init. Vérifions-le, puisque le PID de init est '1', nous utilisons la commande ps :

Nous voyons donc à partir de la sortie que PPID est 0, ce qui signifie qu'il n'y a pas de parent pour ce processus.

$ ps -l 1
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY        TIME CMD
4 S     0     1     0  0  80   0 -  5952 poll_s ?          0:00 /sbin/init

Voici quelques-unes des commandes qui traitent des processus :commande Top, commande HTOP, commande PS, commande Kill (pkill, xkill).


Linux
  1. Commandes Linux - Présentation et exemples

  2. Linux - Comprendre les autorisations Unix et les types de fichiers ?

  3. Linux – Répertoires standard et/ou communs sur les systèmes Unix/linux ?

  4. Linux :trouver et tuer les processus zombies

  5. terminaison de processus mmap, msync et linux

Histoire Unix et Linux

Linux contre Unix

Commandes Zip et Unzip sous Linux/Unix

Présentation des types de bases de données distribuées et de la sécurité

Présentation de RAMFS et TMPFS sous Linux

Comment suivre et tracer un processus Linux