Pages : 1
#1 Le 08/06/2009, à 23:21
- lodino
Programation système
J'ai un problème .
Lors de l'appel de la fonction "fork()", le processus fils crée ré-exécute le code du processus père.
Autrement dit si je fait un
printf("toto")
juste avant l'appel de mon fork(), à l'exécution j'ai totototo.
Merci d'avance pour votre aide.
Dernière modification par lodino (Le 08/06/2009, à 23:51)
Hors ligne
#2 Le 08/06/2009, à 23:28
- best_friend_fr
Re : Programation système
Salut,
Fork copie le processus, mais ne change pas le flux d'instruction. Seule différence, la valeur renvoyée par fork. Dans le processus pere, tu prends le pid du fils, et dans le fils, 0.
En gros
int main() {
int pidFils = fork();
if (pidFils) {
printf("père\n");
} else {
printf("fils\n");
}
}
sudo apt-get replace langage_sms by grammaire orthographe ponctuation
La documentation est avant tout faite pour ceux qui posent les questions, et non ceux qui y répondent
Best_friend_fr
Hors ligne
#3 Le 08/06/2009, à 23:35
- bertrand0
Re : Programation système
Il faut vider les buffers avant le fork, sinon les données qu'ils contiennent sont également dupliquées. Voyez la fonction fflush.
Ceux qui écrivent comme ils parlent, quoiqu'ils parlent très bien, écrivent mal.
Buffon, Discours sur le style
Hors ligne
#4 Le 08/06/2009, à 23:37
- xabilon
Re : Programation système
Salut
Déplacé dans "Développement - Programmation"
Pour passer un sujet en résolu : modifiez le premier message et ajoutez [Résolu] au titre.
Hors ligne
#5 Le 08/06/2009, à 23:56
- lodino
Re : Programation système
merci j'essaye fflush(). J'ai demandé a un amis de compiler, exécuter le même code, et lui n'a la duplication. Vous n'auriez pas d'autre idée pour empêcher par default cette duplication ? merci.
Dernière modification par lodino (Le 08/06/2009, à 23:57)
Hors ligne
#6 Le 09/06/2009, à 00:01
- best_friend_fr
Re : Programation système
Je t'ai mis la solution dans mon post... C'est comme ca que marche fork.
sudo apt-get replace langage_sms by grammaire orthographe ponctuation
La documentation est avant tout faite pour ceux qui posent les questions, et non ceux qui y répondent
Best_friend_fr
Hors ligne
#7 Le 09/06/2009, à 00:05
- lodino
Re : Programation système
oki merci, mais comment vous expliquez que sa fonctionne sur d'autre machine et pas la mienne ?
Dernière modification par lodino (Le 09/06/2009, à 00:06)
Hors ligne
#8 Le 09/06/2009, à 00:48
- bertrand0
Re : Programation système
Ton problème, c'est que le buffer de sortie n'est pas toujours flushé par printf: et ce comportement dépend de la bibliothèque C à laquelle le programme est liée à la compilation (en statique) ou au chargement (en dynamique). Tu as supposé que printf affiche directement à l'écran, mais ça n'est pas le cas, il y a un buffer et la doc de printf ne garantie pas que le buffer soit flushé. (le comportement n'est pas explicitement défini, donc il ne faut pas s'appuyer sur une interprétation dans un sens ou dans l'autre.)
Si le buffer pour stdout est bien flushé avant le fork (que ce soit par printf ou par fflush), le fils reçoit une copie du buffer vide.
Si le buffer pour stdout n'est pas flushé (ni par printf ni par un autre moyen), le fils reçoit une copie du buffer contenant "toto". A un moment ou à un autre ces buffers finissent par être flushé: celui du parent ET celui du fils, d'où un double affichage.
Dernière modification par bertrand0 (Le 09/06/2009, à 00:51)
Ceux qui écrivent comme ils parlent, quoiqu'ils parlent très bien, écrivent mal.
Buffon, Discours sur le style
Hors ligne
#9 Le 09/06/2009, à 00:59
- lodino
Re : Programation système
Merci Bertand pour l'explication, vraiment très bien expliqué .
Quelqu'un saurait quelle librairie installé pour que printf() n'omette plus de flushé le buffer ?
Hors ligne
#10 Le 09/06/2009, à 01:02
- bertrand0
Re : Programation système
Tu n'as pas besoin de choisir une bibliothèque C spécifique rien que pour ça.
Il te suffit de rajouter une commande fflush(stdout); juste avant le fork.
printf("toto");
fflush(null);
pid = fork();
Dernière modification par bertrand0 (Le 09/06/2009, à 01:05)
Ceux qui écrivent comme ils parlent, quoiqu'ils parlent très bien, écrivent mal.
Buffon, Discours sur le style
Hors ligne
#11 Le 09/06/2009, à 07:38
- Bigcake
Re : Programation système
Bonjour,
tu peux soit faire un fflush après ton printf comme le dit bertrand0
Ou bien tu peut rajouter un '\n' a la fin de ton printf();
Si tu ne veut pas de retour à la ligne, tu a aussi la possibilité d'utiliser write()
printf("toto\n");
write(1, "toto", 4);
"Les gens" ne sont pas cons, ils ont été habitués à la facilité et à la désinformation. Le meilleur moyen de ne pas les aider, c'est de se moquer. Le meilleur moyen de les aider, c'est de les informer, encore et encore. La réflexion viendra. N'oubliez pas que vous aussi, vous êtes le con d'un autre.
Smartphone+GNU/Linux=Librem5
Hors ligne
#12 Le 09/06/2009, à 10:31
- nicolas.sitbon
Re : Programation système
Ton problème, c'est que le buffer de sortie n'est pas toujours flushé par printf: et ce comportement dépend de la bibliothèque C à laquelle le programme est liée à la compilation (en statique) ou au chargement (en dynamique). Tu as supposé que printf affiche directement à l'écran, mais ça n'est pas le cas, il y a un buffer et la doc de printf ne garantie pas que le buffer soit flushé. (le comportement n'est pas explicitement défini, donc il ne faut pas s'appuyer sur une interprétation dans un sens ou dans l'autre.)
Le problème ne vient pas spécifiquement de printf() et le comportement pour les streams est explicitement défini, contrairement à ce que tu sembles penser:
3 When a stream is unbuffered,characters are intended to appear from the source or at the
destination as soon as possible. Otherwise characters may be accumulated and
transmitted to or from the host environment as a block. When a stream is fully buffered,
characters are intended to be transmitted to or from the host environment as a block when
abuffer is filled. When a stream is line buffered,characters are intended to be
transmitted to or from the host environment as a block when a new-line character is
encountered. Furthermore, characters are intended to be transmitted as a block to the host
environment when a buffer is filled, when input is requested on an unbuffered stream, or
when input is requested on a line buffered stream that requires the transmission of
characters from the host environment.
et
7 At program startup, three text streams are predefined and need not be opened explicitly
— standardinput (for reading conventional input), standardoutput (for writing
conventional output), and standarderror (for writing diagnostic output). As initially
opened, the standard error stream is not fully buffered; the standard input and standard
output streams are fully buffered if and only if the stream can be determined not to refer
to an interactive device.
comme d'habitude, on retrouve un code qui utilise une fonction d'entrée sortie formatté pour une sortie non formatté, pourquoi ne pas utiliser puts() dans ce cas? ça règle les problèmes de buffering et de format string vulnerability.
Hors ligne
#13 Le 09/06/2009, à 15:19
- bertrand0
Re : Programation système
Je n'ai pas dit que printf avait un problème. J'ai dit que le comportement observé est la conséquence du fonctionnement de printf et de la bibliothèque C en général, ou plus spécifiquement de la présence du tampon. Ça n'est pas un problème en soi. Le problème c'est de ne pas en avoir tenu compte.
Quant à la doc, il ne suffit pas de trouver un texte qui mentionne printf et un comportement spécifique . Il faut définir si vous souhaitez fonctionner avec une implémentation spécifique de libc, ou bien vous en tenir à une spec précise, comme par exemple POSIX, C99 ... Ensuite une fois clairement définie la plateforme, vous devez voir la doc de cette plateforme ou de cette spec, et vérifier que le comportement supposé est bien défini, ou bien laissé à la discrétion de l'implémentation... Et dans des points de détail comme celui-ci, bien que je n'ai pas vérifié explicitement dans ce cas, je vous assure qu'il y a fréquemment des variations qui peuvent vous retomber dessus si vous faites trop de suppositions...
Dans le cas qui nous intéresse, vider le tampon est une solution, ouvrir un flux sans tampon en est une autre. Mais pour ma part j'estime que le problème de sortie formatée ou non, bien qu'intéressant, n'a aucun rapport avec le problème présenté. Le "format string vulnerability" est un risque certain quand il est combiné à des buffer overflows potentiels, ou en tant qu'alternative à un buffer overflow et quand on réutilise naïvement les chaînes reçues d'une source extérieure au process (entrée utilisateur , réseau ...), mais ça n'est pas la source du dédoublement de "toto"
Dernière modification par bertrand0 (Le 09/06/2009, à 15:29)
Ceux qui écrivent comme ils parlent, quoiqu'ils parlent très bien, écrivent mal.
Buffon, Discours sur le style
Hors ligne
Pages : 1