Déroulement d'un programme en C
Fermé
aveuglemspas_sourd
Messages postés
286
Date d'inscription
mercredi 23 mai 2007
Statut
Membre
Dernière intervention
12 octobre 2009
-
3 janv. 2009 à 19:32
loupius - 4 janv. 2009 à 23:11
loupius - 4 janv. 2009 à 23:11
A voir également:
- Déroulement d'un programme en C
- Programme demarrage windows 10 - Guide
- Liste déroulante en cascade - Guide
- Mettre en veille un programme - Guide
- Desinstaller un programme - Guide
- Forcer la fermeture d'un programme - Guide
9 réponses
Pour faire simple:
- le principe du 'fork' est de créer un process indépendant de celui qui l'a crée; donc après l'appel, le père et le fils vont vivre leur vie au bon gré du scheduler si bien qu'on est incapable, à priori, de prédire l'ordre.
Un peu moins simple:
- on peut modifier la priorité: pour donner plus ou moins d'importance au temps de déroulement d'un process,
- on peut modifier l'ordonnancement: très intéressant pour agir sur la réactivité d'un process (cas du temps-réél).
- le principe du 'fork' est de créer un process indépendant de celui qui l'a crée; donc après l'appel, le père et le fils vont vivre leur vie au bon gré du scheduler si bien qu'on est incapable, à priori, de prédire l'ordre.
Un peu moins simple:
- on peut modifier la priorité: pour donner plus ou moins d'importance au temps de déroulement d'un process,
- on peut modifier l'ordonnancement: très intéressant pour agir sur la réactivité d'un process (cas du temps-réél).
Pas sourd... pas sûr ! ;=()))
Dans ton cas, les trois process s'exécutent indépendemment les uns des autres; donc à moins de créer une synchronisation par un pipe ou un sémaphore, il est impossible de dire avec certitude dans quel ordre ils s'exécuteront; donc on ne peut rien dire en ce qui concerne l'affichage.
Mais dans ton programme, il y a quelques petites erreurs de conception:
- on doit tester la valeur de retour du 'fork', car si c'est -1, le fils n'est pas créé,
- avant de se terminer, le processus père doit attendre que son fils soit terminé et aussi récupérer les infos système de celui-ci afin de supprimer dans le système les infos du fils (utilisation de la fonction 'wait'), sinon on se retouve avec un processus 'zombie'.
Dans ton cas, les trois process s'exécutent indépendemment les uns des autres; donc à moins de créer une synchronisation par un pipe ou un sémaphore, il est impossible de dire avec certitude dans quel ordre ils s'exécuteront; donc on ne peut rien dire en ce qui concerne l'affichage.
Mais dans ton programme, il y a quelques petites erreurs de conception:
- on doit tester la valeur de retour du 'fork', car si c'est -1, le fils n'est pas créé,
- avant de se terminer, le processus père doit attendre que son fils soit terminé et aussi récupérer les infos système de celui-ci afin de supprimer dans le système les infos du fils (utilisation de la fonction 'wait'), sinon on se retouve avec un processus 'zombie'.
J'ai fini par compiler le programme suivant
et voilà ce que j'ai obtenu:
On voit donc que l'ordre n'est pas prévisible, et il se peut même qu'en lançant plusieurs fois le programme, l'ordre ne soit pas toujours le même.
Le fait d'avoir mis 'wait' chez le père force le père à attendre la fin du fils pour pouvoir terminer. Le fait d'en avoir mis 2 impose d'attendre 2 fois le fils (ce qui est inutile) et non pas d'attendre une fois le fils et une fois le petit-fils. Par contre comme le fils n'attend pas la fin de son fils (c'est-à-dire le petit-fils), il se termine ce qui termine le père... et le petit-fils existe toujours comme on peut le voir puisque le prompt est revenu (le père a rendu la main) et que le commentaire du petit-fils est arrivé. Ce qui prouve bien que la conception de ce programme est erroné, mais cela ne l'empêche pas de tourner.
<#include <sys/types.h> #include <sys/wait.h> #include <stdio.h> #include <unistd.h> int main () { int status; if (fork ()) { printf("Père: fils lancé\n") ; wait (&status); printf("Père: OK:\n"); wait (&status); printf("Père: Fini!\n") ; } else { if(fork()) { printf("Fils: petit fils lancé\n") ; } else { printf("Petit-fils: lancement\n"); printf("Petit-fils: terminé \n"); } } return (0); }
et voilà ce que j'ai obtenu:
[loupius@azerty essais]$ ./a.out Fils: petit fils lancé Père: fils lancé Petit-fils: lancement Père: OK Père: Fini ! [loupius@azerty essais]$ Petit-fils: terminé
On voit donc que l'ordre n'est pas prévisible, et il se peut même qu'en lançant plusieurs fois le programme, l'ordre ne soit pas toujours le même.
Le fait d'avoir mis 'wait' chez le père force le père à attendre la fin du fils pour pouvoir terminer. Le fait d'en avoir mis 2 impose d'attendre 2 fois le fils (ce qui est inutile) et non pas d'attendre une fois le fils et une fois le petit-fils. Par contre comme le fils n'attend pas la fin de son fils (c'est-à-dire le petit-fils), il se termine ce qui termine le père... et le petit-fils existe toujours comme on peut le voir puisque le prompt est revenu (le père a rendu la main) et que le commentaire du petit-fils est arrivé. Ce qui prouve bien que la conception de ce programme est erroné, mais cela ne l'empêche pas de tourner.
Tu n'as pas compris le principe de la gestion des processus par le système d'exploitation.
Il faut bien comprendre que tous les processus s'exécutent en même temps; en fait c'est un abus de language et ce qu'il faut en comprendre c'est que le gestionnaire des processus aloue successivement un petit temps machine à chaque processus et ce à un tel rythme qu'on a l'impression que les processus s'exécutent en même temps (je simplifie car dans le cas de système bi-processeurs, on peut avoir deux processus qui s'exécutent, mais s'il y a dix processus, il va bien falloir partager le temps, ce qui revient donc au même) si bien qu'une instruction, tel que 'printf' peut être (et probablement même sera) réalisée en plusieurs fois et qu'entre temps un ou plusieurs processus seront réalisés en partie; c'est la raison pour laquelle entre les deux 'printf' (lancement et terminé) du petit-fils, les deux 'printf' (OK et fini) du père ont été réalisés.
Il faut donc bien comprendre qu'une fois les processus lancés chacun suit son propre programme et non plus l'ordre d'écriture de ton programme; il ne faut donc pas s'attendre à ce que le père soit réalisé, puis le fils, puis le petit-fils (qui est l'odre d'écriture de ton programme).
Tout ce dont on peut être certain, dans le cas de ton programme c'est que:
printf("Père: OK:\n"); et printf("Père: Fini!\n") ;
ne seront exécutés qu'après:
printf("Fils: petit fils lancé\n") ;
puisqu'à cause de wait (&status); le père attend que le fils soit terminé.
C'est la seule certitude.
Il faut bien comprendre que tous les processus s'exécutent en même temps; en fait c'est un abus de language et ce qu'il faut en comprendre c'est que le gestionnaire des processus aloue successivement un petit temps machine à chaque processus et ce à un tel rythme qu'on a l'impression que les processus s'exécutent en même temps (je simplifie car dans le cas de système bi-processeurs, on peut avoir deux processus qui s'exécutent, mais s'il y a dix processus, il va bien falloir partager le temps, ce qui revient donc au même) si bien qu'une instruction, tel que 'printf' peut être (et probablement même sera) réalisée en plusieurs fois et qu'entre temps un ou plusieurs processus seront réalisés en partie; c'est la raison pour laquelle entre les deux 'printf' (lancement et terminé) du petit-fils, les deux 'printf' (OK et fini) du père ont été réalisés.
Il faut donc bien comprendre qu'une fois les processus lancés chacun suit son propre programme et non plus l'ordre d'écriture de ton programme; il ne faut donc pas s'attendre à ce que le père soit réalisé, puis le fils, puis le petit-fils (qui est l'odre d'écriture de ton programme).
Tout ce dont on peut être certain, dans le cas de ton programme c'est que:
printf("Père: OK:\n"); et printf("Père: Fini!\n") ;
ne seront exécutés qu'après:
printf("Fils: petit fils lancé\n") ;
puisqu'à cause de wait (&status); le père attend que le fils soit terminé.
C'est la seule certitude.
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
aveuglemspas_sourd
Messages postés
286
Date d'inscription
mercredi 23 mai 2007
Statut
Membre
Dernière intervention
12 octobre 2009
20
3 janv. 2009 à 23:04
3 janv. 2009 à 23:04
up
aveuglemspas_sourd
Messages postés
286
Date d'inscription
mercredi 23 mai 2007
Statut
Membre
Dernière intervention
12 octobre 2009
20
4 janv. 2009 à 12:09
4 janv. 2009 à 12:09
merci , mais du coup dans quel ordre mes affichage se font ?
aveuglemspas_sourd
Messages postés
286
Date d'inscription
mercredi 23 mai 2007
Statut
Membre
Dernière intervention
12 octobre 2009
20
4 janv. 2009 à 15:04
4 janv. 2009 à 15:04
help^^
aveuglemspas_sourd
Messages postés
286
Date d'inscription
mercredi 23 mai 2007
Statut
Membre
Dernière intervention
12 octobre 2009
20
4 janv. 2009 à 19:37
4 janv. 2009 à 19:37
hm , le souci c'est que ce programme fait partis d'un partiel d'une année précédente donc j'ai voulu le faire pour m'entrainer, du coup s'il contient des erreurs je me vois mal le dire à mon professeur :)
aveuglemspas_sourd
Messages postés
286
Date d'inscription
mercredi 23 mai 2007
Statut
Membre
Dernière intervention
12 octobre 2009
20
4 janv. 2009 à 21:13
4 janv. 2009 à 21:13
Merci à vous de passer autant de temps sur mon problème, mais il reste quelque point que je ne comprend pas :
- "fils lancé" est avant le wait, du coup pourquoi ce n'est pas le premier affichage?
- comment peut il y avoir "lancement" d'afficher sans l'affichage de "terminé"?
- "fils lancé" est avant le wait, du coup pourquoi ce n'est pas le premier affichage?
- comment peut il y avoir "lancement" d'afficher sans l'affichage de "terminé"?