GNU/Linux >> Tutoriels Linux >  >> Linux

Apprendre et utiliser les appels système fork(), vfork(), wait() et exec() sur les systèmes Linux

Il s'avère que dans tous les systèmes d'exploitation basés sur Linux/Unix, il est bon de comprendre fork et vfork appels système, comment ils se comportent, comment nous pouvons les utiliser et les différences entre eux. Avec ces attendez et exec les appels système sont utilisés pour générer des processus et diverses autres tâches connexes.

La plupart de ces concepts sont expliqués à l'aide d'exemples de programmation. Dans cet article, je vais couvrir ce que sont les appels système fork, vfork, exec et wait, leurs caractères distinctifs et comment ils peuvent être mieux utilisés.

fork()

fork() : Appel système pour créer un processus enfant.

[email protected] ~}$ man fork

Cela donnera une sortie mentionnant à quoi sert le fork, la syntaxe et avec tous les détails requis.

La syntaxe utilisée pour l'appel système fork est la suivante,

fourche pid_t(void);

L'appel système fork crée un enfant qui diffère de son processus parent uniquement par pid (ID de processus) et ppid (ID de processus parent) . L'utilisation des ressources est définie sur zéro. Les verrous de fichiers et les signaux en attente ne sont pas hérités. (Sous Linux "fork" est implémenté comme "copy-on-write() ").

Remarque :- "Copier sur écriture ” -> Chaque fois qu'un appel système fork() est appelé, une copie de toutes les pages (mémoire) liées au processus parent est créée et chargée dans un emplacement de mémoire séparé par le système d'exploitation pour le processus enfant. Mais cela n'est pas nécessaire dans tous les cas et peut être requis uniquement lorsqu'un processus écrit dans cet espace d'adressage ou dans cette zone de mémoire, seule une copie séparée est alors créée/fournie.

Valeurs de retour  :-  Le PID (ID de processus) du processus enfant est renvoyé dans le fil d'exécution parent et "zéro " est renvoyé dans le fil d'exécution de l'enfant. Voici l'exemple de programmation en C qui explique le fonctionnement de l'appel système fork.

[email protected] ~}$ vim 1_fork.c#include#includeInt main(void){printf("Before fork\n");fork();printf( "after fork\n");}[email protected] ~}$ [email protected] ~}$ cc 1_fork.c[email protected] ~}$ ./a.outBefore forkAfter fork[email protected] ~}$ 

Chaque fois qu'un appel système est effectué, il y a beaucoup de choses qui se passent dans les coulisses de n'importe quelle machine unix/linux.

Tout d'abord, le changement de contexte se produit du mode utilisateur au mode noyau (système). Ceci est basé sur la priorité du processus et le système d'exploitation unix/linux que nous utilisons. Dans l'exemple de code C ci-dessus, nous utilisons l'accolade ouvrante "{" qui est l'entrée du contexte et l'accolade fermante "}" qui permet de quitter le contexte. Le tableau suivant explique très clairement le changement de contexte.

vfork()

vfork –> créer un processus enfant et bloquer le processus parent.

Remarque :- Dans vfork, les gestionnaires de signaux sont hérités mais pas partagés.

[email protected] ~}$ man vfork

Cela donnera une sortie mentionnant à quoi sert vfork, la syntaxe et avec tous les détails requis.

pid_t vfork(void);

vfork est identique à fork sauf que le comportement est indéfini si le processus créé par vfork modifie des données autres qu'une variable de type pid_t utilisée pour stocker la valeur de retour p de vfork ou appelle toute autre fonction entre l'appel de _exit() ou l'un des exec () famille.

Remarque : vfork est parfois appelé cas particulier de clone.

Voici l'exemple de programmation C pour vfork() comment cela fonctionne.

[email protected] ~}$ vim 1.vfork.c#include#includeInt main(void){printf("Before fork\n");vfork(); printf("after fork\n");}[email protected] ~}$ vim 1.vfork.c[email protected] ~}$ cc 1.vfork.c[email protected] ~}$ ./a.outBefore vforkafter vforkafter vforka.out :cxa_atexit.c:100 :__new_exitfn :Échec de l'assertion `l !=NULL'. Abandonné

Remarque : - Comme expliqué précédemment, le comportement de l'appel système vfork n'est souvent pas prévisible. Comme dans le cas ci-dessus, il avait imprimé avant une fois et après deux fois mais avait interrompu l'appel avec la fonction _exit(). Il est préférable d'utiliser l'appel système fork sauf indication contraire et d'éviter autant que possible d'utiliser vfork.

Différences entre fork() et vfork()

Vfork() comportement expliqué plus en détail dans le programme ci-dessous.

[email protected] ~}$ cat vfork_advanced.c#include #include #include int main(){    int n =10 ; pid_t pid =vfork(); // création du processus enfant    if (pid ==0)          // s'il s'agit d'un processus chili    {        printf("Processus enfant démarré\n"); }    else//exécution du processus parent    {        printf("Maintenant, je reviens au processus parent\n"); }    printf("valeur de n :%d \n",n); // exemple d'impression pour vérifier la valeur "n"    renvoie 0 ;}[email protected] ~}$ cc vfork_advanced.c[email protected] ~}$ ./a.outChild process startedvalue of n :10Maintenant, je reviens à la valeur de processus parent of n :594325573a.out :cxa_atexit.c:100 :__new_exitfn :Échec de l'assertion `l !=NULL'.Abandonné

Remarque : Encore une fois, si vous observez que le résultat de vfork n'est pas défini. La valeur de "n" a été imprimée pour la première fois sous la forme 10, ce qui est attendu. Mais la prochaine fois dans le processus parent, il a imprimé une valeur inutile.

attendre()

L'appel système wait() suspend l'exécution du processus en cours jusqu'à ce qu'un enfant soit sorti ou jusqu'à ce qu'un signal soit délivré dont l'action est de terminer le processus en cours ou d'appeler le gestionnaire de signal.

pid_t attendre(int * statut);

Il existe d'autres appels système liés à l'attente comme ci-dessous,

1) waitpid()  :suspend l'exécution du processus en cours jusqu'à ce qu'un enfant, tel que spécifié par les arguments pid, soit sorti ou jusqu'à ce qu'un signal soit délivré.

pid_t waitpid (pid_t pid, int *status, int options);

2) attendre3()  :Suspend l'exécution du processus en cours jusqu'à ce qu'un enfant soit sorti ou jusqu'à ce qu'un signal soit délivré.

pid_t wait3(int *status, int options, struct rusage *rusage);

3) attendre4() :Identique à wait3() mais inclut la valeur pid_t pid.

pid_t wait3(pid_t pid, int *status, int options, struct rusage *rusage);

exec()

exec() famille de fonctions ou d'appels système remplace l'image de processus actuelle par la nouvelle image de processus.

Il existe des fonctions comme execl , execlp ,exécuter ,execv , execvp et execvpe sont utilisés pour exécuter un fichier.

Ces fonctions sont des combinaisons d'un tableau de pointeurs vers des chaînes à terminaison nulle qui représentent la liste d'arguments, cela aura une variable de chemin avec certaines combinaisons de variables d'environnement.

quitter()

Cette fonction est utilisée pour l'arrêt normal du processus. L'état du processus est capturé pour référence future. Il existe d'autres fonctions similaires exit(3) et _exit(). , qui sont utilisés en fonction du processus sortant que l'on souhaite utiliser ou capturer.

Conclusion :-

Les combinaisons de tous ces appels/fonctions système sont utilisées pour la création, l'exécution et la modification de processus. Ces fonctions sont également appelées ensemble de fonctions de frai "shell". Il faut utiliser ces fonctions avec prudence en gardant à l'esprit le résultat et le comportement.


Linux
  1. Comment utiliser les instantanés LVM pour restaurer des systèmes Linux

  2. Comment installer et utiliser Git dans le système Linux

  3. Comment installer et utiliser Telnet sur les systèmes Linux

  4. Comment utiliser les commandes strace et ltrace sous Linux

  5. Comment installer et utiliser Glances pour surveiller les systèmes Linux

Comment installer et utiliser Skype sur le système Linux. C'est maintenant plus facile

Comment installer et utiliser le compilateur GCC sur le système Linux

Comment monter et utiliser un lecteur exFAT sur un système Linux

Comment installer et utiliser Tmux (multiplexeur de terminaux) dans le système Linux

Comment installer et utiliser AsciiDoc dans le système Linux

Comment installer et utiliser l'émulateur de terminal Konsole dans le système Linux