IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

fork processus zombie et processus orphelin


Sujet :

C

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2015
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2015
    Messages : 27
    Points : 14
    Points
    14
    Par défaut fork processus zombie et processus orphelin
    Bonjour,

    Décidément en ce moment, je me tourne beaucoup vers vous. Je suis en train de découvrir la partie création de processus avec fork et je dois dans un exercice réaliser un programme manipulant les processus en les faisant passé dans les état zombie ou orphelin selon certaines conditions.

    Voilà l'énoncé :
    Écrire un programme qui engendre trois fils. Un fils rentrera dans l’état zombi et puis deviendra orphelin. Un deuxième fils deviendra orphelin avant rentrer dans l’état zombi. Un troisième fils deviendra zombi et il ne sera jamais orphelin.
    .
    Pour l'instant, mon code s’arrête à la boucle for me permettant de créer 3 processus. Je ne parviens cependant pas à trouver comment faire ce qui m'est demandé.
    Je ne vois pas comment passer un processus dans son état zombi ou dans son état orphelin.
    Pour le processus orphelin, je visualise plus ou moins ce que c'est. C'est le moment ou ce processus fils est toujours en cours d’exécution, mais n'a plus de pères.
    Pour ce qui est du processus zombi, je n'arrive pas à visualiser ce que c'est malgré mettre renseigner dessus.

    Pourriez-vous donc m'éclaircir sur ces processus zombie et orphelin. Dans quels cas, un processus se retrouve dans un de ces états et comment peut-on les obtenir ?

    La solution à ce problème se trouve sur internet (ça a l'air d'un exercice classique des TP de système d'exploitation), mais ceci ne m'a pas pour autant permis de comprendre et je préférerais le faire par moi-même à ma façon (car il y en a surement plusieurs) afin de bien comprendre.


    Merci d'avance de votre aide.

  2. #2
    Responsable Systèmes


    Homme Profil pro
    Gestion de parcs informatique
    Inscrit en
    Août 2011
    Messages
    17 431
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Gestion de parcs informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Août 2011
    Messages : 17 431
    Points : 43 057
    Points
    43 057
    Ma page sur developpez.com : http://chrtophe.developpez.com/ (avec mes articles)
    Mon article sur le P2V, mon article sur le cloud
    Consultez nos FAQ : Windows, Linux, Virtualisation

  3. #3
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 684
    Points : 30 973
    Points
    30 973
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par TuxThePenguin Voir le message
    Pour le processus orphelin, je visualise plus ou moins ce que c'est. C'est le moment ou ce processus fils est toujours en cours d’exécution, mais n'a plus de pères.
    Pour ce qui est du processus zombi, je n'arrive pas à visualiser ce que c'est malgré mettre renseigner dessus.
    Pourriez-vous donc m'éclaircir sur ces processus zombie et orphelin. Dans quels cas, un processus se retrouve dans un de ces états et comment peut-on les obtenir ?
    Bonjour

    Pour l'orphelin c'est exact. Tout processus est toujours généré par un autre. Cela te donne alors tout un "arbre" de processus que tu peux voir avec la commande "ptree". Il peut arriver alors que le père d'un processus disparaisse. Comme un processus ne connait que son père, (et pas son grand père), il se retrouve alors "orphelin" ne sachant plus vers qui se rattacher.

    A ce moment là, 2 cas possibles
    1. a la mort du père, tous les fils reçoivent un signal "hup". A ce signal, ils meurent eux-aussi (et en récursif si eux-mêmes étaient père d'autres processus)
    2. certains processus ayant été lancés via la commande "nohup" ne reçoivent pas ce "hup". Dans ce cas, à la mort de leur père ils restent en vie mais ne pouvant pas demeurer sans père, ils sont alors automatiquement adoptés par init (pid=1)

    Sous Unix, le comportement par défaut est le 1. Sous Linux, c'est le 2. Sous Linux, donc, le nohup devient inutile.

    Un procesuss zombie c'est plus simple: c'est un processus qui est mort mais où le père ne le sait pas encore. Quand tu programmes des père-fils via fork(), tu as ensuite à ta disposition wait(int *r) qui détecte la fin d'un fils et qui stocke la raison de cette fin dans le pointeur "r". Ben tant que le père n'a pas appelé wait(), il ne sait pas que son fils est mort et le fils est donc "zombie". Sous Linux ce terme morbide a un peu évolué en "defunct".

    Ce programme crée un zombie
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    #include <stdio.h> 
    #include <stdlib.h>
     
    int main(int argc, char *argv[]) 
    { 
    	int pid;
    	int r;
    	if ((pid=fork()) == 0)
    	{
    		// Fils
    		sleep(1);
    		printf("\tfils %d de %d\n", getpid(), getppid());
    		sleep(30);
    		printf("\tmort fils %d de %d\n", getpid(), getppid());
    		exit(0);
    	}
    	// Père
    	printf("\tpère %d de %d\n", getpid(), pid);
    	sleep(100);
    	wait(&r);
    	printf("\tpère %d de %d mort (%d)\n", getpid(), pid, r);
    	sleep(100);
    }
    A la création il y a un père et son fils. Le fils vit 30 secondes avant de mourir donc pendant 30 secondes, en utilisant intelligemment ps -edfl | grep tu les vois tous les deux. Ensuite le fils meurt mais le père continue à attendre 70 secondes durant lesquelles le ps te montrera encore le pid du fils à l'état de defunct/zombie (selon ton os). Ensuite le père se réveille en se demandant où est son fils et là, le district attorney lui dit qu'il est crevé alors il pleure encore 100 secondes durant lesquelles le ps ne te montre plus que lui. Puis il finit sa vie lamentable.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  4. #4
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2015
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2015
    Messages : 27
    Points : 14
    Points
    14
    Par défaut
    Merci chrtophe pour ton lien où le cours est très bien fait et merci sve@r pour tes explications sur le processus zombi.

    Si j'ai bien compris en reprenant la consigne de mon exercice, pour le premier processus qui doit passer à l’état zombi puis orphelin, il suffit de ne pas utiliser wait afin d'informer au père la mort du fils, mais de le tuer directement. Si je tue le père après le processus fils, ce dernier sera donc zombi puis orphelin, mais une fois le père mort, vus que wait ne sera pas utiliser, il sera encore zombi non ? Il apparaîtra donc toujours à la fin de la liste des processus sous l'état Z en faisant un ps aux.

    Pour le cas du second processus, je ne comprends pas comment un processus peut devenir zombi alors qu'il est orphelin. Il faudrait tuer le père juste après avoir fait le wait non ? Mais dans ce cas-là le processus fils étant déjà terminé, il ne peut donc pas être orphelin.

    Pour le troisième cas, c'est celui qui reprend l'exemple du processus zombi que sve@r a mit ou celui du cours posté par chrtophe.

    Je vais donc déjà coder les cas du premier processus et du troisième que je visualise comment faire. Pour le second, je suis un peu bloqué par contre.

  5. #5
    Responsable Systèmes


    Homme Profil pro
    Gestion de parcs informatique
    Inscrit en
    Août 2011
    Messages
    17 431
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Gestion de parcs informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Août 2011
    Messages : 17 431
    Points : 43 057
    Points
    43 057
    Par défaut
    Pour résumer :

    L'arrêt d'un processus père va déclencher l'arrêt de ses fils. C'est le principe, car un programme bien fait devrait attendre la fin de tous ses fils pour s'arrêter. En cas de dérogation à cela voir le post de Sver.

    Pourquoi un état de processus Zombie existe ? car il n'est pas à la charge d'un processus de s'auto-détruire, mais à son père. Quand un processus se termine, il passe en zombie. Il restera en zombie tant que :

    - son père étant averti le détruise
    - qu'il soit adopté par init car orphelin

    En fonctionnement normal, un processus ne reste pas suffisamment longtemps zombie pour qu'on le voit. L'état de Zombie permet donc de gérer le deuil du père, que le système puisse gérer un problème de processus mort mais non normalement supprimé.

    Remarque : un processus orphelin, c'est pas normal, cela vient soit d'un crash du père, soit d'une mauvaise gestion ou non utilisation de wait/waitpid.

    La remarque de Sver sur la différence de comportement entre Unix et Linux est intéressante. Sous Linux, un processus orphelin continuera à fonctionner par défaut alors que sous Unix, c'est au choix. Les 2 cas de figures peuvent être un avantage ou un inconvénient selon la situation.

    @Sver : petite question : c'est qu'un comportement par défaut ? Je suppose que sous Linux a également le choix ...
    Ma page sur developpez.com : http://chrtophe.developpez.com/ (avec mes articles)
    Mon article sur le P2V, mon article sur le cloud
    Consultez nos FAQ : Windows, Linux, Virtualisation

  6. #6
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 684
    Points : 30 973
    Points
    30 973
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par chrtophe Voir le message
    @Sver : petite question : c'est qu'un comportement par défaut ? Je suppose que sous Linux a également le choix ...
    C'est ce que j'ai remarqué de nombreuses fois. Facile à vérifier d'ailleurs ; te suffit de lancer un sleep 5000 & puis de fermer le shell qui l'a lancé. Tu verras alors ensuite ton sleep rattaché au init.
    C'est vrai que ce serait plus logique de pouvoir choisir le comportement à adopter mais je n'ai jamais ni cherché, ni trouvé l'option qui permette ça. Ceci dit il existe plein d'options bash. Par exemple en bash par défaut, une variable ne sort pas d'un sous-processus. Exemple i=0; cat /etc/passwd |while read lig; do i=$((i+1)); echo $i; done; echo $i. En bash normal, on aura 0 à la fin (le i a été incrémenté dans le pipe et il est perdu en fin de pipe) mais on peut demander une option spéciale (sais plus laquelle) qui fait que le i est actualisé en dehors du pipe. Peut-être qu'on peut aussi demander une option spéciale qui implémente l'envoi automatique du SIGHUP aux fils à la mort du père...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  7. #7
    Responsable Systèmes


    Homme Profil pro
    Gestion de parcs informatique
    Inscrit en
    Août 2011
    Messages
    17 431
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Gestion de parcs informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Août 2011
    Messages : 17 431
    Points : 43 057
    Points
    43 057
    Par défaut
    Le truc m'ayant intrigué, j'ai cherché un peu sur le net.

    Quand un processus se termine (je parle d'un arrêt normal), celui-ci appelle la fonction noyau exit_notify(), qui est chargé d'envoyer un signal au père, de transmettre les processus enfants à init, puis de se placer en TASK_ZOMBIE, puis appelle l’ordonnanceur.

    D''après ce que j'ai compris, quand le père reçoit le signal de fin de process de son fils concerné,soit il le gère soit il notifie au noyau qu'il s'en fout. Je présumes donc que la task_struct n'est pas libérée si ce signal n'est pas traité et reste donc en zombie, occupant l'espace mémoire de la task_struct et probablement ses piles.Si le processus est orphelin, init devenant son père, c'est lui qui recevra la notification de passage en zombie et enverra le signal au noyau. Ces entrées zombie ont un sens pour gérer la fin des processus petit-fils si il y en a, car ceux-ci ne connaissent pas leur grand-pères.

    @Sver :
    Quand au signal SIGHUP, c'est un signal signifiant que le terminal contrôlant le processus est fermé.

    Du coup, si il y a une différence entre Unix et Linux, je me demande si c'est pas plus lié à la gestion de signaux par le shell qu'au système lui-même. Donc l'esperluette détachant la commande du terminal, le signal SIGHUP ne doit pas être géré. Sais-tu si l'esperluette c'est valable pour tous les shells ? j'ai testé avec csh ça fonctionne.
    Ma page sur developpez.com : http://chrtophe.developpez.com/ (avec mes articles)
    Mon article sur le P2V, mon article sur le cloud
    Consultez nos FAQ : Windows, Linux, Virtualisation

  8. #8
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2015
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2015
    Messages : 27
    Points : 14
    Points
    14
    Par défaut
    Bonjour,

    N'arrivant pas à arriver à mes fins avec cet exercice, je l'ai mis de coté hier pour continuer la suite de mon TP et me remets dessus aujourd'hui.

    Cependant, j'aborde le problème différemment. Avant de tenter de faire le programme créant 3 processus faisant les 3 changements d'état cités dans l'énoncé de mon premier post, je vais essayer de les faire séparément et utiliser ps aux dans un second terminal pour voir comment se comportent mes processus.

    Pour le premier cas, celui où mon processus fils passe à l'état zombie puis devient orphelin, j'ai réalisé le code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    int main(){
    	printf("processus principal pid: %d ppid: %d\n", getpid(), getppid());
    	int pid_fils;
    	if((pid_fils=fork())==0){
    		printf("processus %d fils de %d\n",getpid(), getppid() );
    		sleep(4);
    		printf("fin de %d\n",getpid());
    		exit(EXIT_SUCCESS);
    	}
    	printf("processus %d père de %d\n",getpid(), pid_fils);
    	sleep(10);
    	printf("fin de %d\n",getpid());
    	exit(EXIT_SUCCESS);
     
    return 0;
    }
    En faisant 3 ps aux (un avant la fin du sleep(4), un après la fin du processus fils et avant la fin du sleep(10) et un après), je vois bien le passage de mon processus fils dans son état zombie, mais ce code met t-il vraiment en avant le fait qu'il devient orphelin ? Car certes, le père ne vérifie pas si son fils est fini ou non, et donc en se terminant, on peut supposer que son fils devient orphelin, mais du fait que celui-ci est terminé, il ne se retrouve pas adopté par le init (il m'est, en tout cas, impossible de le vérifier que ce soit avec mes printf dans le programme ou la commande ps aux). Si mon processus fils est terminé et se retrouve dans un état zombie comment peut-il être orphelin après cela ? Auriez-vous un exemple concret de ce phénomène ?

    Pour le second cas, c'est celui qui me cause le plus de souci et d'incompréhension. Voilà le code que j'ai fait jusqu'alors :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    int main(){
    	printf("processus principal pid: %d ppid: %d\n", getpid(), getppid());
    	int pid_fils;
    	if((pid_fils=fork())==0){
    		printf("processus %d fils de %d\n",getpid(), getppid() );
    		sleep(10);
    		printf("processus %d fils de %d\n",getpid(), getppid() );
    		printf("fin de %d\n",getpid());
    		exit(EXIT_SUCCESS);
    	}
    	printf("processus %d père de %d\n",getpid(), pid_fils);
    	sleep(4);
    	printf("fin de %d\n",getpid());
    	exit(EXIT_SUCCESS);
     
    return 0;
    }
    Les printf montrent bien le passage à l'état orphelin du processus et son adoption par le init, mais à aucun moment ceci ne mettra en avant que le fils devient zombie. En utilisant ps aux, je visualise mes 2 processus créés, la disparition du processus père dû à sa fin, mais une fois le processus fils terminé, du fait qu'il est orphelin il disparaît de la liste des processus obtenue par ps aux, on ne sait donc pas s'il se retrouve zombie. Comme pour le premier cas, mais dans l'autre sens, comment un processus orphelin peut-il devenir zombie ? Si j'ai bien compris ce qu'est un processus zombie le père ne sait pas que sont fils est mort, mais dans ce cas présent, le père meurt avant le fils. Auriez-vous là aussi un exemple concret pouvant illustrer ce cas ?

    Pour le troisième cas, c'est celui de l'état zombie donné par sve@r, ou l'on demande au père d'attendre que le processus d'attendre la fin de son fils avec wait malgré le fait que ce dernier soit terminé depuis plusieurs secondes.

    Merci de votre aide.

  9. #9
    Responsable Systèmes


    Homme Profil pro
    Gestion de parcs informatique
    Inscrit en
    Août 2011
    Messages
    17 431
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Gestion de parcs informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Août 2011
    Messages : 17 431
    Points : 43 057
    Points
    43 057
    Par défaut
    Pour que tu comprennes, un processus a un cycle de vie, il passe d'un état à un autre, au moins de RUNNING à ZOMBIE. Voici les états possibles :

    - TASK_RUNNING process en cours
    - TASK_INTERRUPTABLE process dormant, il peut être réveillé
    - TASK_UNINTERRUPTABLE process dormant, il ne peut être réveillé
    - TASK_ZOMBIE process terminé, statut non collecté
    - TASK_STOPPED process stoppé par débogueur ou contrôleur de job
    - TASK_SWAPPING process en swap

    Un process a toujours un père. Il devient toujours Zombie. Lors d'un arrêt propre, le processus devient Zombie, et le statut collecté par son père le fait disparaitre. Exemple, si ce processus à des fils lui aussi, grand-papa peut décider de les laisser vivre à la fin de son fils ou de les buter (si il 'occupe de la collecte de son état, ce qu'il devrait toujours faire). Dans ce cas, le fils reste Zombie et je suppose que les petits enfants sont adoptés par le grand-père, il faudrait tester.

    Le fait qu'un process soit orphelin n'a rien à voir avec le fait qu'il soit RUNNING ou ZOMBIE, de toute façon, il ne restera pas orphelin et sera adopté par init. C'est le noyau qui gère la disparition d'un zombie. Il est précisé statut non collecté, on pourrais le comparer à en attente de destruction.

    C'est la fonction wait() qui est en charge du nettoyage des zombies, si son parent ne l'a pas appelé, init l'adopteur l’appelle régulièrement.

    Pour réaliser ton exercice, part rapport à tout ce qui a été vue réponds aux questions suivantes :
    - comment rendre un processus orphelin ?
    - comment mettre un processus en état de zombie ?
    Ma page sur developpez.com : http://chrtophe.developpez.com/ (avec mes articles)
    Mon article sur le P2V, mon article sur le cloud
    Consultez nos FAQ : Windows, Linux, Virtualisation

  10. #10
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2015
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2015
    Messages : 27
    Points : 14
    Points
    14
    Par défaut
    Merci de ta réponse, je crois avoir compris.

    Dans tous les cas, quand mon processus fil se termine, il est dans l'état zombi et y reste jusqu'à ce que le père ait choisi de le tuer. Pour tuer son fils, il faut utiliser wait qui permet de libérer les ressources sinon ce dernier restera dans l'état zombi. Est ce bien cela ?

    Je viens en plus de trouver en regardant de plus prêt ici http://manpagesfr.free.fr/man/man2/wait.2.html que si un père ne s'est pas chargé de faire disparaitre ses fils zombie et qu'il se termine ainsi, ses fils zombie seront adopté par init qui effectuera automatiquement le wait pour les supprimer.

    Donc pour en revenir à mon exercice, il faut pour le cas du premier fils, le faire se terminer pour le rendre à l'état zombi, puis tuer son père pour qu'il devienne orphelin (et donc par la suite automatiquement supprimé par le init qui l'aura adopté). Pour le cas du second fils, il faut qu'au moment ou le père est tué, ce dernier n'est pas fini. Ceci le fera devenir orphelin donc adopté par le init, une fois ce processus finit, il deviendra zombie et le init se chargera de la supprimer pour libérer les ressources. Enfin pour le cas du troisième fils, il faut que ce soit le père qui le tue grâce à wait. Ce qui veut dire qu'une fois ce processus finit, il devient zombi et est ensuite directement tuer par le père du fait que ce dernier a attendu la fin de l'exécution de son fils avant de se tuer a son tour.

    Il est donc plus simple, je pense que le premier fils créé, par la boucle for soit celui qui ne passera que par l'état zombi et mettre une condition dans le cas où on se trouve dans le père à i=0 alors je fait un wait. Puis au second tour de boucle, que je fasse le processus fils qui deviens zombie en premier. Puis au dernier tour de boucle un fils qui dormira un certain temps, ce qui me permettra de tuer le père avant que ce dernier ne soit terminé. Et une fois le père mort, j'aurais mon second process qui sera orphelin donc adopté par init et du fait qu'il était zombi supprimé par init. En ce qui concerne le dernier processus fils, il sera orphelin donc adopté par init. Le init devra attendre la fin de ce dernier processus (qui dort encore grâce à un sleep) pour qu'il devienne zombi et donc pouvoirs le supprimer.

    Merci encore de vos explications m'ayant apporté beaucoup d'éclaircissement dur le fonctionnement des processus.

  11. #11
    Responsable Systèmes


    Homme Profil pro
    Gestion de parcs informatique
    Inscrit en
    Août 2011
    Messages
    17 431
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Gestion de parcs informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Août 2011
    Messages : 17 431
    Points : 43 057
    Points
    43 057
    Par défaut
    Dans tous les cas, quand mon processus fil se termine, il est dans l'état zombi et y reste jusqu'à ce que le père ait choisi de le tuer. Pour tuer son fils, il faut utiliser wait qui permet de libérer les ressources sinon ce dernier restera dans l'état zombi. Est ce bien cela ?
    Quand un processus est en état de zombie, ses ressources sont déjà libérés. Seule la task_truct reste. Les pages mémoires physiques sont libérés si rien d'autre n'y fait accès.

    Je viens en plus de trouver en regardant de plus prêt ici http://manpagesfr.free.fr/man/man2/wait.2.html que si un père ne s'est pas chargé de faire disparaitre ses fils zombie et qu'il se termine ainsi, ses fils zombie seront adopté par init qui effectuera automatiquement le wait pour les supprimer.
    C'est ce que je disais.

    Donc pour en revenir à mon exercice, il faut pour le cas du premier fils, le faire se terminer pour le rendre à l'état zombi, puis tuer son père pour qu'il devienne orphelin (et donc par la suite automatiquement supprimé par le init qui l'aura adopté).
    Tue son père, comme ça il sera orphelin, puis attend qu'il se termine pour le voir devenir zombie, avant qu'il ne disparaissent une fois gérée par l'appel de wait() par init.

    Pour le reste, tu devrais t'en sortir.

    Bonne continuation.
    Ma page sur developpez.com : http://chrtophe.developpez.com/ (avec mes articles)
    Mon article sur le P2V, mon article sur le cloud
    Consultez nos FAQ : Windows, Linux, Virtualisation

  12. #12
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2015
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2015
    Messages : 27
    Points : 14
    Points
    14
    Par défaut
    Je viens vous montrer mon code afin d'avoir vos avis, si vous pensez que j'ai réalisé l'exercice demandé.

    Voici ce que j'ai fait (le code n'est surement pas optimisé et j'aurais du faire un switch au lieu des if sur le i, ça aurai été plus propre):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    int main(){
    	int i, process, status, dead;
    	printf("processus principal %d\n", getpid());
    	for(i=0; i<3; i++){
    		process=fork();
    		if(i==0){//cas du processus zombi
    			if(process==0){
    				printf("%d fils %d de %d\n",i+1, getpid(), getppid());
    				printf("mort de %d\n", getpid());
    				exit(EXIT_SUCCESS);
    			}else{
    				printf("père %d de %d\n", getpid(), process);
    				dead=wait(&status);
    				printf("fils %d de %d est mort (%d)\n\n",dead, getpid(), status);
    			}
    		}else if(i==1){//processus zombi qui sera orphelin
    			if(process==0){
    				printf("%d fils %d de %d\n",i+1, getpid(), getppid());
    				printf("mort de %d\n", getpid());
    				exit(EXIT_SUCCESS);
    			}else{
    				printf("père %d de %d\n\n", getpid(), process);
    			}
    		}else{//cas du processus orphelin puis zombi
    			if(process==0){
    				printf("%d fils %d de %d\n",i+1, getpid(), getppid());
    				sleep(10);
    				printf("fils %d de %d\n", getpid(), getppid());
    				printf("mort de %d\n", getpid());
    				exit(EXIT_SUCCESS);
    			}else{
    				printf("père %d de %d\n\n", getpid(), process);
    			}
    		}
    		sleep(2);
    	}
    	exit(EXIT_SUCCESS);
    return 0;
    }
    Selon moi, après toutes les explications reçu, mon code est bon. Sinon pouvez-vous m'indiquer ce qui ne va pas.

    J'aurais une petite question supplémentaire, ayant un rapport avec l'affichage dans le terminal. Quand mon processus principal se termine, automatiquement, comme après la fin de tout programme ou fonction, il s'écrit la ligne défini par username@hostname pathCurentDirectory(variable selon ce que dit le bashrc) et on peut taper une nouvelle commande ou lancer un nouveau programme. Cependant lorsque j'ai un processus fils dans mon programme qui n'est pas tué par le processus principal (son père) et qui se finit après lui (à cause d'un sleep par exemple), alors j'ai tous les printf pas encore effectué par le fils s'affichant après le username@hostname pathCurentDirectory. Je trouve cela normale (du fait que le processus que l'on a lancé est terminer, bien que ses fils ne le soit pas) mais à la fois dérangeant au niveau affichage sur le terminal. Est-il possible de faire en sorte que ceci ne s'affiche qu'à la fin de tous les processus engendrés par le programme lancé précédemment ?

    Je ne sais pas si je me suis exprimé correctement donc je mets une photo de ce que j’obtiens en exécutant le programme de l'exercice que je viens de réaliser et montrant ce phénomène.

    Nom : 1fb628d653162f83c451b45b99214caa.png
Affichages : 12835
Taille : 30,2 Ko

  13. #13
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2015
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2015
    Messages : 27
    Points : 14
    Points
    14
    Par défaut
    Une nouvelle question vient de me venir en tête. Lorsque mon processus "principale" (mon programme) se termine, il devient lui aussi zombi normalement, mais qui se charge de le tuer complètement ?
    Je pense que c'est le bash du fait que ce soit son père mais je voudrais avoir la confirmation.

    Merci

  14. #14
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 684
    Points : 30 973
    Points
    30 973
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par TuxThePenguin Voir le message
    je vois bien le passage de mon processus fils dans son état zombi, mais ce code met t-il vraiment en avant le fait qu'il devient orphelin? Car certes, le père ne vérifie pas si son fils est fini ou non, et donc en se terminant, on peut supposé que sont fils devient orphelin, mais du fait que celui-ci est terminé, il ne se retrouve pas adopté par le init (il m'est, en tout cas, impossible de le vérifier que ce soit avec mes printf dans le programme ou la commande ps aux). Si mon processus fils est terminé et se retrouve dans un état zombi comment peut-il être orphelin après cela ? Auriez-vous un exemple concret de ce phénomène ?
    Un zombie est déjà mort !!! Il ne peut donc plus être orphelin !!! Si le père meurt sans avoir eu connaissance de la fin du fils, celui-ci est alors adopté par init qui commence par se renseigner sur l'état du processus qu'il est en train d'adopter. Et comme en mécanique quantique, le simple fait de "regarder" transforme l'état du processus qui passe alors de zombie à décédé.

    Citation Envoyé par TuxThePenguin Voir le message
    Une nouvelle question vient de me venir en tête. Lorsque mon processus "principale" (mon programme) se termine, il devient lui aussi zombi normalement, mais qui se charge de le tuer complètement ?
    Je pense que c'est le bash du fait que ce soit son père mais je voudrais avoir la confirmation.
    Si le programme "principal" a été lancé par le bash, alors celui-ci ayant connaissance de la fin de son fils (statut placé dans sa variable "$$"), le fils en question n'est plus zombie. Il est définitivement mort. Le fait d'être zombie c'est simplement "mon père ne sait pas que je suis mort". Si inversement le père est au courant, alors le procesuss ne devient jamais zombie.

    Citation Envoyé par TuxThePenguin Voir le message
    Cependant lorsque j'ai un processus fils dans mon programme qui n'est pas tué par le processus principal (son père) et qui se finit après lui (à cause d'un sleep par exemple), alors j'ai tous les printf pas encore effectué par le fils s'affichant après le username@hostname pathCurentDirectory. Je trouve cela normale (du fait que le processus que l'on a lancé est terminer, bien que ses fils ne le soit pas) mais à la fois dérangeant au niveau affichage sur le terminal. Est-il possible de faire en sorte que ceci ne s'affiche qu'à la fin de tous les processus engendrés par le programme lancé précédemment ?
    Non. Les printf() des fils continuent à te pourrir ton écran et tu ne peux rien faire. Ou alors quand tu lances le programme principal, tu rediriges vers un fichier. Tous les fils hériteront alors de la redirection.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  15. #15
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2015
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2015
    Messages : 27
    Points : 14
    Points
    14
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Un zombie est déjà mort !!! Il ne peut donc plus être orphelin !!! Si le père meurt sans avoir eu connaissance de la fin du fils, celui-ci est alors adopté par init qui commence par se renseigner sur l'état du processus qu'il est en train d'adopter. Et comme en mécanique quantique, le simple fait de "regarder" transforme l'état du processus qui passe alors de zombie à décédé.
    Si un zombie ne peut être orphelin, le cas "Un fils rentrera dans l’état zombi et puis deviendra orphelin" n'a donc aucun sens vue que d'après ce que tu me dit, un zombie ne peut être orphelin.

    Sinon pense tu que le code que j'ai réalisé répond bien à mon exercice?


    Merci encore de ton aide

  16. #16
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 684
    Points : 30 973
    Points
    30 973
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par TuxThePenguin Voir le message
    Si un zombie ne peut être orphelin, le cas "Un fils rentrera dans l’état zombi et puis deviendra orphelin" n'a donc aucun sens vue que d'après ce que tu me dit, un zombie ne peut être orphelin.
    Ben en tout cas j'ai jamais réussi à en créer. Ci-joint un essai en ce sens
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    #include <stdio.h> 
    #include <stdlib.h>
     
    int main(int argc, char *argv[]) 
    { 
    	int pid;
    	int r;
    	if ((pid=fork()) == 0)
    	{
    		// Fils
    		sleep(1);
    		printf("\tfils %d de %d\n", getpid(), getppid());
    		sleep(20);
    		printf("\tmort fils %d de %d\n", getpid(), getppid());
    		exit(0);
    	}
    	// Père
    	printf("\tpère %d de %d\n", getpid(), pid);
    	sleep(40);
    	exit(0);
    }
    Le fils reste vivant 20 secondes puis meurt mais son père ne s'en préoccupe pas durant sa vie de 40s. Donc pendant encore 20s on voit le fils "zombie". Une fois que le père meurt, le fils (qui devrait devenir orphelin) disparait totalement des écrans ps. Donc pour moi, il ne passe pas orphelin. Ou plutôt il passe peut-être orphelin pendant une microseconde le temps que le init aillle, lui, se renseigner sur son état ce qui rend alors le zombie définitivement mort et donc plus du tout orphelin...

    Citation Envoyé par TuxThePenguin Voir le message
    Sinon pense tu que le code que j'ai réalisé répond bien à mon exercice?
    Tu devrais placer aussi des sleep dans les fils pour temporiser leurs changement d'état. Et si tu créais 3 fonctions fils1, fils2 et fils3 ce serait plus lisible. Surtout que t'es même pas obligé de switcher sur le i (en fait, t'as même pas besoin de "i"). Te suffit de déclarer un tableau de fonctions que tu balayes via son pointeur...

    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    #include <stdio.h> 
    #include <stdlib.h>
     
    void fils1()
    {
    	printf("Fils 1 (%d, %d)\n", getpid(), getppid());
    }
     
    void fils2()
    {
    	printf("Fils 2 (%d, %d)\n", getpid(), getppid());
    }
     
    void fils3()
    {
    	printf("Fils 3 (%d, %d)\n", getpid(), getppid());
    }
     
    int main(int argc, char *argv[]) 
    { 
    	int pid;
     
    	void (*tabFonc[])(void)={fils1, fils2, fils3, NULL};
    	void (**ptFonc)(void);
     
    	for (ptFonc=tabFonc; *ptFonc != NULL; ptFonc++)
    	{
    		if ((pid=fork()) == 0)
    		{
    			(*ptFonc)();
    			exit(0);
    		}
    	}
    	sleep(20);
    }

    Te reste plus qu'à programmer le vrai code de tes 3 fonctions "fils1", "fils2" et "fils3" et c'est réglé. Et c'est 100 fois plus évolutif...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  17. #17
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2015
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2015
    Messages : 27
    Points : 14
    Points
    14
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Ou plutôt il passe peut-être orphelin pendant une microseconde le temps que le init aille, lui, se renseigner sur son état ce qui rend alors le zombie définitivement mort et donc plus du tout orphelin...
    Bas, c'est ce que j'ai compris en lisant la note de la page manuel de wait ici http://manpagesfr.free.fr/man/man2/wait.2.html, une fois le père mort, c'est le init qui se charge d'adopter le fils et d'effectuer le wait pour le supprimer définitivement.

    En tout cas merci pour vos aide et explication, je vais reprendre mon programme et le modifier afin de l'optimiser de la manière dont tu me conseille.

    Je risque de revenir bientôt avec un nouveau poste sur le forum, on vient d'aborder en amphi les pipe et les sémaphores, qui n'ont pas l'aire simple aux premiers abords. Je saurais donc ou venir chercher de l'aide en cas de besoins quand on fera le TP.

    Merci encore à vous deux sve@r et chrtophe

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. création de n processus fils avec fork
    Par TuxThePenguin dans le forum C
    Réponses: 2
    Dernier message: 02/10/2015, 00h39
  2. Exit ou return sur un processus fils(fork) ?
    Par valda117 dans le forum C
    Réponses: 6
    Dernier message: 12/03/2014, 09h10
  3. Processus père attend processus fils
    Par prgasp77 dans le forum Administration système
    Réponses: 12
    Dernier message: 10/09/2009, 15h00
  4. terminaison du processus fils
    Par zahira dans le forum POSIX
    Réponses: 3
    Dernier message: 08/04/2006, 13h35
  5. Partage d'une variable entre les processus fils
    Par Mehdi Feki dans le forum Linux
    Réponses: 7
    Dernier message: 09/01/2005, 13h34

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo