Lorsque l'on crer un processus à l'intérieur d'un programme grâce à la
fonction système 'fork', le processus fils partage maintenant les
fichiers ouverts part le processus parent.
Jusqu'à maintenant, pas de problème.
Si dans le processus parent, on le force à attendre la fin du
processus fils (wait()) avant d'écrire dans le fichier et qu'un
fclose(fichier) à été fait dans le fils, le parent à toujours la
possibilité d'écrire dans le fichier et les deux lignes sont présentes
lorsque l'on édite le fichier.
Hypothèse : le fichier prends du temps à ce fermer et le parent à le
temps de se glisser pour écrire mais la fonction sleep(10) vient
refuter cette hypothèse.
Hypothèse : le fclose n'a pas vraiment fonctionné... mais l'affichage
du retour de fonction vient refuter cette deuxième hypothèse.
Hypothèse : c'est l'algo d'ordenancement de l'OS et/ou la version du
compilateur qui est bogué. J'ai tenté l'exécution de ce programme sous
RedHat, gcc 3.2.2 20030222 (RedHat Linux 3.3.3-5) et le même phénomène
se produit.
Voici un exemple de ce que j'avance (essayez-le et envoyez-moi vos
commentaires et/ou explications) :
/*Système d'exploitation : SunOS 5.8*/
/*Compilateur : gcc version 2.95 19990728(release)*/
#include <stdio.h>
#include <unistd.h>
main() {
int pid;
int retourExit;
FILE *fd;
if ((fd = fopen("test","w")) != NULL) {
pid = fork();
}
else {
printf("Erreur d'ecriture");
exit(-1);
}
if (pid == 0) {/*On est dans le fils*/
fprintf ( fd, " Je suis le fils \n");
printf("Retour du fclose : %d", fclose(fd));
exit(0);
}
else {
wait(&retourExit); /*On attends l'exécution du fils avant de
poursuivre*/
sleep(10);
fprintf ( fd, " Je suis le père \n");
}
}
J'espère que quelqu'un pourra trouver une explication, pour ma part,
j'ai épuisé les petites connaissances que j'ai dans le domaine.
Lorsque l'on crer un processus à l'intérieur d'un programme grâce à la fonction système 'fork', le processus fils partage maintenant les fichiers ouverts part le processus parent.
Jusqu'à maintenant, pas de problème.
Si, un, quand meme. Tu n'as pas poste dans le groupe adequat pour
repondre a ta question. Afin de maximiser tes chances d'obtenir des reponses satisfaisantes, je te conseille de reposter sur un groupe consacre aux unixoides. fr.comp.lang.c se contente de discuter du langage C tel que defini par la norme ISO, et non pas des nombreuses API systeme et autres ecrites dans ce langage. -- Bertrand Mollinier Toublet OO Check out Nerd Boy .||. by Joaquim Gandara bb at http://www.Nerb-Boy.net
Booli wrote:
Lorsque l'on crer un processus à l'intérieur d'un programme grâce à la
fonction système 'fork', le processus fils partage maintenant les
fichiers ouverts part le processus parent.
Jusqu'à maintenant, pas de problème.
Si, un, quand meme. Tu n'as pas poste dans le groupe adequat pour
repondre a ta question. Afin de maximiser tes chances d'obtenir des
reponses satisfaisantes, je te conseille de reposter sur un groupe
consacre aux unixoides. fr.comp.lang.c se contente de discuter du
langage C tel que defini par la norme ISO, et non pas des nombreuses API
systeme et autres ecrites dans ce langage.
--
Bertrand Mollinier Toublet
OO Check out Nerd Boy
.||. by Joaquim Gandara
bb at http://www.Nerb-Boy.net
Lorsque l'on crer un processus à l'intérieur d'un programme grâce à la fonction système 'fork', le processus fils partage maintenant les fichiers ouverts part le processus parent.
Jusqu'à maintenant, pas de problème.
Si, un, quand meme. Tu n'as pas poste dans le groupe adequat pour
repondre a ta question. Afin de maximiser tes chances d'obtenir des reponses satisfaisantes, je te conseille de reposter sur un groupe consacre aux unixoides. fr.comp.lang.c se contente de discuter du langage C tel que defini par la norme ISO, et non pas des nombreuses API systeme et autres ecrites dans ce langage. -- Bertrand Mollinier Toublet OO Check out Nerd Boy .||. by Joaquim Gandara bb at http://www.Nerb-Boy.net
Anthony FLEURY
Booli wrote:
Lorsque l'on crer un processus à l'intérieur d'un programme grâce à la fonction système 'fork', le processus fils partage maintenant les fichiers ouverts part le processus parent.
Jusqu'à maintenant, pas de problème.
Cette question aurait plutot sa place sur un groupe unix. Tu vas te faire taper sur les doigts à parler d'unix ici, car toute discussion doit se faire sur des choses indépendantes de la plateforme.
<HS Total> Petite indication cependant, le comportement est tout à fait normal. En fait, le père et le fils partagent la même table de descripteurs de fichier, ok. À sa création, le fils possède une table des descripteurs de fichier qui pointe sur la même table que son père. Tout ce qui est offset dans le fichier est dans cette table, donc si tu avances avec l'un des deux, tu avances avec l'autre. Cependant, si tu tentes de fermer un fichier, il ne le sera réelement que lorsque tous les processus l'utilisant l'auront fermés. Pour l'analogie, c'est un peu comme unlink pour les fichiers. Tant que tu as toujours au moins un lien sur le fichier dans ta table des descripteurs, il ne sera pas effectivement fermé. <HS>
-- Anthony FLEURY Testing can show the presense of bugs, but not their absence. -- Edsger W. Dijkstra
Booli wrote:
Lorsque l'on crer un processus à l'intérieur d'un programme grâce à la
fonction système 'fork', le processus fils partage maintenant les
fichiers ouverts part le processus parent.
Jusqu'à maintenant, pas de problème.
Cette question aurait plutot sa place sur un groupe unix. Tu vas te faire
taper sur les doigts à parler d'unix ici, car toute discussion doit se
faire sur des choses indépendantes de la plateforme.
<HS Total>
Petite indication cependant, le comportement est tout à fait normal. En
fait, le père et le fils partagent la même table de descripteurs de
fichier, ok. À sa création, le fils possède une table des descripteurs de
fichier qui pointe sur la même table que son père. Tout ce qui est offset
dans le fichier est dans cette table, donc si tu avances avec l'un des
deux, tu avances avec l'autre. Cependant, si tu tentes de fermer un
fichier, il ne le sera réelement que lorsque tous les processus l'utilisant
l'auront fermés. Pour l'analogie, c'est un peu comme unlink pour les
fichiers. Tant que tu as toujours au moins un lien sur le fichier dans ta
table des descripteurs, il ne sera pas effectivement fermé.
<HS>
--
Anthony FLEURY
Testing can show the presense of bugs, but not their absence.
-- Edsger W. Dijkstra
Lorsque l'on crer un processus à l'intérieur d'un programme grâce à la fonction système 'fork', le processus fils partage maintenant les fichiers ouverts part le processus parent.
Jusqu'à maintenant, pas de problème.
Cette question aurait plutot sa place sur un groupe unix. Tu vas te faire taper sur les doigts à parler d'unix ici, car toute discussion doit se faire sur des choses indépendantes de la plateforme.
<HS Total> Petite indication cependant, le comportement est tout à fait normal. En fait, le père et le fils partagent la même table de descripteurs de fichier, ok. À sa création, le fils possède une table des descripteurs de fichier qui pointe sur la même table que son père. Tout ce qui est offset dans le fichier est dans cette table, donc si tu avances avec l'un des deux, tu avances avec l'autre. Cependant, si tu tentes de fermer un fichier, il ne le sera réelement que lorsque tous les processus l'utilisant l'auront fermés. Pour l'analogie, c'est un peu comme unlink pour les fichiers. Tant que tu as toujours au moins un lien sur le fichier dans ta table des descripteurs, il ne sera pas effectivement fermé. <HS>
-- Anthony FLEURY Testing can show the presense of bugs, but not their absence. -- Edsger W. Dijkstra
Willy
<HS Total> fichier, ok. À sa création, le fils possède une table des descripteurs de fichier qui pointe sur la même table que son père.
donc faire un fflush () ?
bon, celà dit, si je me souviens bien, qd on fait un fopen, ça peut poser des problèmes avec fork. Il faut redescendre plus bas pour partager correctement les descripteurs de fichier, voir la commande "open".
Mais je n'en suis pas du tout sûr ;-)
bon courage @+ Willy
<HS Total>
fichier, ok. À sa création, le fils possède une table des
descripteurs de fichier qui pointe sur la même table que son père.
donc faire un fflush () ?
bon, celà dit, si je me souviens bien, qd on fait un fopen, ça peut poser
des problèmes avec fork.
Il faut redescendre plus bas pour partager correctement les descripteurs de
fichier, voir la commande "open".
<HS Total> fichier, ok. À sa création, le fils possède une table des descripteurs de fichier qui pointe sur la même table que son père.
donc faire un fflush () ?
bon, celà dit, si je me souviens bien, qd on fait un fopen, ça peut poser des problèmes avec fork. Il faut redescendre plus bas pour partager correctement les descripteurs de fichier, voir la commande "open".
Mais je n'en suis pas du tout sûr ;-)
bon courage @+ Willy
espie
In article <c0eauu$45s$, Willy wrote:
<HS Total> fichier, ok. À sa création, le fils possède une table des descripteurs de fichier qui pointe sur la même table que son père.
donc faire un fflush () ?
bon, celà dit, si je me souviens bien, qd on fait un fopen, ça peut poser des problèmes avec fork. Il faut redescendre plus bas pour partager correctement les descripteurs de fichier, voir la commande "open".
Mais je n'en suis pas du tout sûr ;-)
Moi j'en suis nettement plus sur, et on redeviendrait presque in-charte.
Les fonctions de la bibliotheque standard C, comme fopen(3) et consorts, en bonnes fonctions de bibliotheques, sont entierement implementees (en general) en C relativement independant du systeme. Sur un systeme Unix, elles ne vont guere `que' traduire des arguments, ET rajouter une gestion de tampon, donc allocation memoire, et quelques variables correspondantes: un FILE *, c'est un vrai fichier ouvert (file descriptor sous Unix), plus quelques drapeaux, deux/trois pointeurs, et un ou deux tampons (et eventuellement des indications de synchronisations avec d'autres flux, en particulier si la bibliotheque `connait' C++, mais je m'egare).
Arrive fork(2), qui est un gentil appel systeme, qui ignore totalement l'existence de la bibliotheque standard C, qui le lui rend bien, d'ailleurs.
Consequence: toute cette savante gestion de tampons, ou on depose d'abord ce qu'on doit ecrire en memoire jusqu'a en avoir assez, est totalement ignoree par le fork(2).
Application: int main() { printf("toto"); fork(); printf("n"); exit(0); }
va assez souvent afficher deux fois toto sur un systeme Unix.
Parfaitement normal et rigoureux cote norme, vu que fork() est inconnu de la norme C, et a donc le droit de generer du comportement non-standard.
Le fflush(stdout) ou fflush(NULL) permet de retomber sur nos pattes pour les flux en sortie. C'est plus complique pour les flux en entree, pour lesquels fflush() ne fonctionne pas (garantie), et ou on ne peut pas faire grand chose cote norme C (il y a une fonction similaire POSIX qui sait plus ou moins faire).
La solution souvent utilisee consiste a gerer les flush au niveau file-descriptor avant le fork(), quitte a faire un fdopen() apres pour pouvoir beneficier des joies de la bibliotheque standard.
In article <c0eauu$45s$1@aphrodite.grec.isp.9tel.net>,
Willy <nospam@9online.fr> wrote:
<HS Total>
fichier, ok. À sa création, le fils possède une table des
descripteurs de fichier qui pointe sur la même table que son père.
donc faire un fflush () ?
bon, celà dit, si je me souviens bien, qd on fait un fopen, ça peut poser
des problèmes avec fork.
Il faut redescendre plus bas pour partager correctement les descripteurs de
fichier, voir la commande "open".
Mais je n'en suis pas du tout sûr ;-)
Moi j'en suis nettement plus sur, et on redeviendrait presque in-charte.
Les fonctions de la bibliotheque standard C, comme fopen(3) et consorts,
en bonnes fonctions de bibliotheques, sont entierement implementees (en
general) en C relativement independant du systeme. Sur un systeme Unix,
elles ne vont guere `que' traduire des arguments, ET rajouter une gestion
de tampon, donc allocation memoire, et quelques variables correspondantes:
un FILE *, c'est un vrai fichier ouvert (file descriptor sous Unix), plus
quelques drapeaux, deux/trois pointeurs, et un ou deux tampons (et
eventuellement des indications de synchronisations avec d'autres flux, en
particulier si la bibliotheque `connait' C++, mais je m'egare).
Arrive fork(2), qui est un gentil appel systeme, qui ignore totalement
l'existence de la bibliotheque standard C, qui le lui rend bien,
d'ailleurs.
Consequence: toute cette savante gestion de tampons, ou on depose d'abord
ce qu'on doit ecrire en memoire jusqu'a en avoir assez, est totalement
ignoree par le fork(2).
Application:
int main()
{
printf("toto");
fork();
printf("n");
exit(0);
}
va assez souvent afficher deux fois toto sur un systeme Unix.
Parfaitement normal et rigoureux cote norme, vu que fork() est inconnu
de la norme C, et a donc le droit de generer du comportement non-standard.
Le fflush(stdout) ou fflush(NULL) permet de retomber sur nos pattes pour
les flux en sortie. C'est plus complique pour les flux en entree, pour
lesquels fflush() ne fonctionne pas (garantie), et ou on ne peut pas
faire grand chose cote norme C (il y a une fonction similaire POSIX qui
sait plus ou moins faire).
La solution souvent utilisee consiste a gerer les flush au niveau
file-descriptor avant le fork(), quitte a faire un fdopen() apres pour
pouvoir beneficier des joies de la bibliotheque standard.
<HS Total> fichier, ok. À sa création, le fils possède une table des descripteurs de fichier qui pointe sur la même table que son père.
donc faire un fflush () ?
bon, celà dit, si je me souviens bien, qd on fait un fopen, ça peut poser des problèmes avec fork. Il faut redescendre plus bas pour partager correctement les descripteurs de fichier, voir la commande "open".
Mais je n'en suis pas du tout sûr ;-)
Moi j'en suis nettement plus sur, et on redeviendrait presque in-charte.
Les fonctions de la bibliotheque standard C, comme fopen(3) et consorts, en bonnes fonctions de bibliotheques, sont entierement implementees (en general) en C relativement independant du systeme. Sur un systeme Unix, elles ne vont guere `que' traduire des arguments, ET rajouter une gestion de tampon, donc allocation memoire, et quelques variables correspondantes: un FILE *, c'est un vrai fichier ouvert (file descriptor sous Unix), plus quelques drapeaux, deux/trois pointeurs, et un ou deux tampons (et eventuellement des indications de synchronisations avec d'autres flux, en particulier si la bibliotheque `connait' C++, mais je m'egare).
Arrive fork(2), qui est un gentil appel systeme, qui ignore totalement l'existence de la bibliotheque standard C, qui le lui rend bien, d'ailleurs.
Consequence: toute cette savante gestion de tampons, ou on depose d'abord ce qu'on doit ecrire en memoire jusqu'a en avoir assez, est totalement ignoree par le fork(2).
Application: int main() { printf("toto"); fork(); printf("n"); exit(0); }
va assez souvent afficher deux fois toto sur un systeme Unix.
Parfaitement normal et rigoureux cote norme, vu que fork() est inconnu de la norme C, et a donc le droit de generer du comportement non-standard.
Le fflush(stdout) ou fflush(NULL) permet de retomber sur nos pattes pour les flux en sortie. C'est plus complique pour les flux en entree, pour lesquels fflush() ne fonctionne pas (garantie), et ou on ne peut pas faire grand chose cote norme C (il y a une fonction similaire POSIX qui sait plus ou moins faire).
La solution souvent utilisee consiste a gerer les flush au niveau file-descriptor avant le fork(), quitte a faire un fdopen() apres pour pouvoir beneficier des joies de la bibliotheque standard.
Antoine Leca
En c0ue45$1tuh$, Marc Espie va escriure:
int main() { printf("toto"); fork(); printf("n"); exit(0); }
va assez souvent afficher deux fois toto sur un systeme Unix.
Parfaitement normal et rigoureux cote norme, vu que fork() est inconnu de la norme C, et a donc le droit de generer du comportement non-standard.
Qui plus est, ce code est parfaitement standard, à partir du moment où on dit que fork() « clone » le processus, donc nous avons en fait ici deux programmes (identiques) au sens de la norme C. Les deux affichent, cela me paraît tout-à-fait conforme.
Non ?
Antoine
En c0ue45$1tuh$1@biggoron.nerim.net, Marc Espie va escriure:
int main() {
printf("toto");
fork();
printf("n");
exit(0); }
va assez souvent afficher deux fois toto sur un systeme Unix.
Parfaitement normal et rigoureux cote norme, vu que fork() est inconnu
de la norme C, et a donc le droit de generer du comportement
non-standard.
Qui plus est, ce code est parfaitement standard, à partir du moment où on
dit que fork() « clone » le processus, donc nous avons en fait ici deux
programmes (identiques) au sens de la norme C. Les deux affichent, cela me
paraît tout-à-fait conforme.
int main() { printf("toto"); fork(); printf("n"); exit(0); }
va assez souvent afficher deux fois toto sur un systeme Unix.
Parfaitement normal et rigoureux cote norme, vu que fork() est inconnu de la norme C, et a donc le droit de generer du comportement non-standard.
Qui plus est, ce code est parfaitement standard, à partir du moment où on dit que fork() « clone » le processus, donc nous avons en fait ici deux programmes (identiques) au sens de la norme C. Les deux affichent, cela me paraît tout-à-fait conforme.
Non ?
Antoine
Guillaume
Qui plus est, ce code est parfaitement standard, à partir du moment où on dit que fork() « clone » le processus, donc nous avons en fait ici deux programmes (identiques) au sens de la norme C. Les deux affichent, cela me paraît tout-à-fait conforme.
Bien sûr, mais il ne me semble pas que la norme parle du concept de "processus". Donc, le comportement de ce code est tout à fait prédictible, mais ce n'est pas la norme seule qui peut le prédire.
Au fait, moi j'aurais plutôt utilisé la valeur de retour de fork(). Cet exemple donne de très mauvaises habitudes (ne pas tester les valeurs de retour). La tester aurait permis:
- de savoir si la création du processus enfant a réussi ou non; - de savoir si la suite du code s'éxecute dans le processus enfant ou dans le processus parent.
Qui plus est, ce code est parfaitement standard, à partir du moment où on
dit que fork() « clone » le processus, donc nous avons en fait ici deux
programmes (identiques) au sens de la norme C. Les deux affichent, cela me
paraît tout-à-fait conforme.
Bien sûr, mais il ne me semble pas que la norme parle du concept de
"processus". Donc, le comportement de ce code est tout à fait
prédictible, mais ce n'est pas la norme seule qui peut le prédire.
Au fait, moi j'aurais plutôt utilisé la valeur de retour de fork().
Cet exemple donne de très mauvaises habitudes (ne pas tester les
valeurs de retour). La tester aurait permis:
- de savoir si la création du processus enfant a réussi ou non;
- de savoir si la suite du code s'éxecute dans le processus enfant
ou dans le processus parent.
Qui plus est, ce code est parfaitement standard, à partir du moment où on dit que fork() « clone » le processus, donc nous avons en fait ici deux programmes (identiques) au sens de la norme C. Les deux affichent, cela me paraît tout-à-fait conforme.
Bien sûr, mais il ne me semble pas que la norme parle du concept de "processus". Donc, le comportement de ce code est tout à fait prédictible, mais ce n'est pas la norme seule qui peut le prédire.
Au fait, moi j'aurais plutôt utilisé la valeur de retour de fork(). Cet exemple donne de très mauvaises habitudes (ne pas tester les valeurs de retour). La tester aurait permis:
- de savoir si la création du processus enfant a réussi ou non; - de savoir si la suite du code s'éxecute dans le processus enfant ou dans le processus parent.
espie
In article <40338c79$0$5909$, Guillaume wrote:
Au fait, moi j'aurais plutôt utilisé la valeur de retour de fork(). Cet exemple donne de très mauvaises habitudes (ne pas tester les valeurs de retour). La tester aurait permis:
- de savoir si la création du processus enfant a réussi ou non; - de savoir si la suite du code s'éxecute dans le processus enfant ou dans le processus parent.
Ben voyons. De toutes facons en l'occurrence, le but du jeu etait de montrer un comportement `aberrant'. On voit mal en quoi afficher deux fois toto peut etre utile ici.
In article <40338c79$0$5909$7a628cd7@news.club-internet.fr>,
Guillaume <grsNOSPAM@NO-SPAMmail.com> wrote:
Au fait, moi j'aurais plutôt utilisé la valeur de retour de fork().
Cet exemple donne de très mauvaises habitudes (ne pas tester les
valeurs de retour). La tester aurait permis:
- de savoir si la création du processus enfant a réussi ou non;
- de savoir si la suite du code s'éxecute dans le processus enfant
ou dans le processus parent.
Ben voyons. De toutes facons en l'occurrence, le but du jeu etait de
montrer un comportement `aberrant'. On voit mal en quoi afficher
deux fois toto peut etre utile ici.
Au fait, moi j'aurais plutôt utilisé la valeur de retour de fork(). Cet exemple donne de très mauvaises habitudes (ne pas tester les valeurs de retour). La tester aurait permis:
- de savoir si la création du processus enfant a réussi ou non; - de savoir si la suite du code s'éxecute dans le processus enfant ou dans le processus parent.
Ben voyons. De toutes facons en l'occurrence, le but du jeu etait de montrer un comportement `aberrant'. On voit mal en quoi afficher deux fois toto peut etre utile ici.
Antoine Leca
En 40338c79$0$5909$, Guillaume va escriure:
Qui plus est, ce code est parfaitement standard, à partir du moment où on dit que fork() « clone » le processus, donc nous avons en fait ici deux programmes (identiques) au sens de la norme C. Les deux affichent, cela me paraît tout-à-fait conforme.
Bien sûr, mais il ne me semble pas que la norme parle du concept de "processus".
Bon, j'ai pas été assez clair, je vais donc développer.
fork() est défini par une norme, en l'occurence POSIX. Non ? Si. Son effet, dans cette norme, est de « cloner » les processus. Non ? Si. Et un processus, dans POSIX, c'est une notion bien définie. Sa représentation en C, cela s'appelle un programme (c'est même l'objet de la norme C que de définir ce que c'est qu'un programme). Donc où est le problème ?
Donc, le comportement de ce code est tout à fait prédictible,
Tu parles de l'original (celui de 2Booli"), ou de l'exemple de Marc Espie ? Parce que en ce qui concerne le second, c'est ton avis et tu le partages... (Même Marc a pris de grosses précautions, « assez souvent »)
mais ce n'est pas la norme seule qui peut le prédire.
Allez, c'est reparti. On va encore avoir droit à « ceci n'est pas dans l'objet de la norme C, donc 'raus »: Il m'avait semblé avoir vu la balise [HS], pourtant...
Au fait, moi j'aurais plutôt utilisé la valeur de retour de fork().
Pourquoi faire ? pour la multiplier avec celle de printf ? ou avec celle de fflush ? ;-)
Antoine
En 40338c79$0$5909$7a628cd7@news.club-internet.fr, Guillaume va escriure:
Qui plus est, ce code est parfaitement standard, à partir du moment
où on dit que fork() « clone » le processus, donc nous avons en fait
ici deux programmes (identiques) au sens de la norme C. Les deux
affichent, cela me paraît tout-à-fait conforme.
Bien sûr, mais il ne me semble pas que la norme parle du concept de
"processus".
Bon, j'ai pas été assez clair, je vais donc développer.
fork() est défini par une norme, en l'occurence POSIX. Non ? Si. Son effet,
dans cette norme, est de « cloner » les processus. Non ? Si. Et un
processus, dans POSIX, c'est une notion bien définie. Sa représentation en
C, cela s'appelle un programme (c'est même l'objet de la norme C que de
définir ce que c'est qu'un programme). Donc où est le problème ?
Donc, le comportement de ce code est tout à fait prédictible,
Tu parles de l'original (celui de 2Booli"), ou de l'exemple de Marc Espie ?
Parce que en ce qui concerne le second, c'est ton avis et tu le partages...
(Même Marc a pris de grosses précautions, « assez souvent »)
mais ce n'est pas la norme seule qui peut le prédire.
Allez, c'est reparti. On va encore avoir droit à « ceci n'est pas dans
l'objet de la norme C, donc 'raus »: Il m'avait semblé avoir vu la balise
[HS], pourtant...
Au fait, moi j'aurais plutôt utilisé la valeur de retour de fork().
Pourquoi faire ? pour la multiplier avec celle de printf ? ou avec celle de
fflush ? ;-)
Qui plus est, ce code est parfaitement standard, à partir du moment où on dit que fork() « clone » le processus, donc nous avons en fait ici deux programmes (identiques) au sens de la norme C. Les deux affichent, cela me paraît tout-à-fait conforme.
Bien sûr, mais il ne me semble pas que la norme parle du concept de "processus".
Bon, j'ai pas été assez clair, je vais donc développer.
fork() est défini par une norme, en l'occurence POSIX. Non ? Si. Son effet, dans cette norme, est de « cloner » les processus. Non ? Si. Et un processus, dans POSIX, c'est une notion bien définie. Sa représentation en C, cela s'appelle un programme (c'est même l'objet de la norme C que de définir ce que c'est qu'un programme). Donc où est le problème ?
Donc, le comportement de ce code est tout à fait prédictible,
Tu parles de l'original (celui de 2Booli"), ou de l'exemple de Marc Espie ? Parce que en ce qui concerne le second, c'est ton avis et tu le partages... (Même Marc a pris de grosses précautions, « assez souvent »)
mais ce n'est pas la norme seule qui peut le prédire.
Allez, c'est reparti. On va encore avoir droit à « ceci n'est pas dans l'objet de la norme C, donc 'raus »: Il m'avait semblé avoir vu la balise [HS], pourtant...
Au fait, moi j'aurais plutôt utilisé la valeur de retour de fork().
Pourquoi faire ? pour la multiplier avec celle de printf ? ou avec celle de fflush ? ;-)
Antoine
Guillaume
Au fait, moi j'aurais plutôt utilisé la valeur de retour de fork().
Pourquoi faire ? pour la multiplier avec celle de printf ? ou avec celle de fflush ? ;-)
Tout simplement parce que c'est avec la valeur de retour seulement que l'on va rendre l'exécution de la suite du code parfaitement prédictible. C'était juste une parenthèse, mais qui méritait d'être soulevée.
Rappelons juste que fork() renvoie le PID du processus enfant au processus parent, 0 au processus enfant et -1 si la création du processus enfant a échoué. Dans l'exemple donné (en supposant que fork() réussisse), l'appel à printf() sera exécuté à la fois dans le contexte du processus parent et dans le contexte du processus enfant. Il y aura donc bien deux appels à printf().
Ce n'est donc qu'avec un test rigoureux de la valeur de retour de fork() que l'on peut savoir exactement ce qui va se passer dans tout le code qui s'exécutera après son appel.
En ce qui concerne le comportement spécifique des flots d'E/S partagés par plusieurs processus (dans le sujet initial), il est très largement dépendant du système d'exploitation sous-jacent. Il n'y a donc pas de réponse univoque et d'ailleurs elle ne dépend pas du langage (ici C) de programmation.
Au fait, moi j'aurais plutôt utilisé la valeur de retour de fork().
Pourquoi faire ? pour la multiplier avec celle de printf ? ou avec celle de
fflush ? ;-)
Tout simplement parce que c'est avec la valeur de retour seulement que
l'on va rendre l'exécution de la suite du code parfaitement prédictible.
C'était juste une parenthèse, mais qui méritait d'être soulevée.
Rappelons juste que fork() renvoie le PID du processus enfant au
processus parent, 0 au processus enfant et -1 si la création du
processus enfant a échoué. Dans l'exemple donné (en supposant que
fork() réussisse), l'appel à printf() sera exécuté à la fois dans
le contexte du processus parent et dans le contexte du processus
enfant. Il y aura donc bien deux appels à printf().
Ce n'est donc qu'avec un test rigoureux de la valeur de retour de fork()
que l'on peut savoir exactement ce qui va se passer dans tout le code
qui s'exécutera après son appel.
En ce qui concerne le comportement spécifique des flots d'E/S partagés
par plusieurs processus (dans le sujet initial), il est très largement
dépendant du système d'exploitation sous-jacent. Il n'y a donc pas
de réponse univoque et d'ailleurs elle ne dépend pas du langage (ici C)
de programmation.
Au fait, moi j'aurais plutôt utilisé la valeur de retour de fork().
Pourquoi faire ? pour la multiplier avec celle de printf ? ou avec celle de fflush ? ;-)
Tout simplement parce que c'est avec la valeur de retour seulement que l'on va rendre l'exécution de la suite du code parfaitement prédictible. C'était juste une parenthèse, mais qui méritait d'être soulevée.
Rappelons juste que fork() renvoie le PID du processus enfant au processus parent, 0 au processus enfant et -1 si la création du processus enfant a échoué. Dans l'exemple donné (en supposant que fork() réussisse), l'appel à printf() sera exécuté à la fois dans le contexte du processus parent et dans le contexte du processus enfant. Il y aura donc bien deux appels à printf().
Ce n'est donc qu'avec un test rigoureux de la valeur de retour de fork() que l'on peut savoir exactement ce qui va se passer dans tout le code qui s'exécutera après son appel.
En ce qui concerne le comportement spécifique des flots d'E/S partagés par plusieurs processus (dans le sujet initial), il est très largement dépendant du système d'exploitation sous-jacent. Il n'y a donc pas de réponse univoque et d'ailleurs elle ne dépend pas du langage (ici C) de programmation.
espie
In article <4033bb01$0$5909$, Guillaume wrote:
Au fait, moi j'aurais plutôt utilisé la valeur de retour de fork().
Pourquoi faire ? pour la multiplier avec celle de printf ? ou avec celle de fflush ? ;-)
Tout simplement parce que c'est avec la valeur de retour seulement que l'on va rendre l'exécution de la suite du code parfaitement prédictible. C'était juste une parenthèse, mais qui méritait d'être soulevée.
Il y a une erreur de logique dans ton raisonnement. Tu ne peux pas savoir a l'avance si ton fork() va renvoyer -1 ou reussir.
Tu m'expliqueras dans ces conditions comme le fait de sauver cette valuer de retour va rendre l'execution de la suite du code `parfaitement predictible'.
De toutes facons, on ne sait deja pas avec certitude au moment de printf("toto'); ce que fait l'implementation de la bibliotheque C. (on peut savoir ce que fait une implementation donnee, bien sur).
Partant de la, le comportement de la suite aura bien du mal a etre predictible...
In article <4033bb01$0$5909$7a628cd7@news.club-internet.fr>,
Guillaume <grsNOSPAM@NO-SPAMmail.com> wrote:
Au fait, moi j'aurais plutôt utilisé la valeur de retour de fork().
Pourquoi faire ? pour la multiplier avec celle de printf ? ou avec celle de
fflush ? ;-)
Tout simplement parce que c'est avec la valeur de retour seulement que
l'on va rendre l'exécution de la suite du code parfaitement prédictible.
C'était juste une parenthèse, mais qui méritait d'être soulevée.
Il y a une erreur de logique dans ton raisonnement.
Tu ne peux pas savoir a l'avance si ton fork() va renvoyer -1 ou reussir.
Tu m'expliqueras dans ces conditions comme le fait de sauver cette valuer
de retour va rendre l'execution de la suite du code `parfaitement
predictible'.
De toutes facons, on ne sait deja pas avec certitude au moment de
printf("toto'); ce que fait l'implementation de la bibliotheque C.
(on peut savoir ce que fait une implementation donnee, bien sur).
Partant de la, le comportement de la suite aura bien du mal a etre
predictible...
Au fait, moi j'aurais plutôt utilisé la valeur de retour de fork().
Pourquoi faire ? pour la multiplier avec celle de printf ? ou avec celle de fflush ? ;-)
Tout simplement parce que c'est avec la valeur de retour seulement que l'on va rendre l'exécution de la suite du code parfaitement prédictible. C'était juste une parenthèse, mais qui méritait d'être soulevée.
Il y a une erreur de logique dans ton raisonnement. Tu ne peux pas savoir a l'avance si ton fork() va renvoyer -1 ou reussir.
Tu m'expliqueras dans ces conditions comme le fait de sauver cette valuer de retour va rendre l'execution de la suite du code `parfaitement predictible'.
De toutes facons, on ne sait deja pas avec certitude au moment de printf("toto'); ce que fait l'implementation de la bibliotheque C. (on peut savoir ce que fait une implementation donnee, bien sur).
Partant de la, le comportement de la suite aura bien du mal a etre predictible...