56 votes

fork() et sortie

J'ai un programme simple :

int main()
{
    std::cout << " Hello World";
    fork();
}

Après l'exécution du programme, ma sortie est la suivante : Hello World Hello World . Pourquoi cela se produit-il au lieu d'un seul Hello world ? Je suppose que le processus enfant est réexécuté en coulisses et que le tampon de sortie est partagé entre les processus ou quelque chose de ce genre, mais est-ce le cas ou quelque chose d'autre se produit-il ?

93voto

w00te Points 11664

Ce n'est pas tout à fait ce que vous pensiez au départ. Le tampon de sortie n'est pas partagé - lorsque vous exécutez le fork, les deux processus obtiennent une copie du même tampon . Ainsi, après la bifurcation, les deux processus finissent par vider le tampon et imprimer le contenu à l'écran séparément.

Ce site ne se produit que parce que cout est une IO tamponnée . Si vous avez utilisé cerr, qui n'est pas mis en mémoire tampon, vous ne devriez voir le message qu'une seule fois, avant la bifurcation.

44voto

hmjd Points 76411

La sortie standard utilise des entrées/sorties en mémoire tampon. Lorsque le fork() est appelé, la sortie standard n'est pas vidée et le contenu de la mémoire tampon est répliqué dans le processus enfant. Ces tampons sont vidés lorsque le processus sort, ce qui donne les deux sorties que vous voyez.

Si vous changez le programme pour :

std::cout << " Hello World;" << std::endl;

vous ne devriez en voir qu'un seul.

17voto

Joshua Points 13231

Parce que vous avez appelé fork() sans vider tous les tampons d'abord.

cout.flush();
fork();

10voto

Michael Mior Points 13475

Le code de sortie "Hello World" n'est exécuté qu'une seule fois. Le problème est que la mémoire tampon de sortie n'est pas vidée. Donc quand vous bifurquez le processus, "Hello World" est toujours dans le tampon de sortie. Lorsque les deux programmes se terminent, leurs tampons de sortie seront vidés et vous verrez la sortie deux fois.

La façon la plus simple de le démontrer est d'ajouter une nouvelle ligne à la fin de votre chaîne de caractères, ce qui provoquera un vidage implicite, ou un vidage explicite avec la commande std::cout.flush(); . Vous ne verrez alors le résultat qu'une seule fois.

9voto

James McLaughlin Points 11924

Si vous utilisez :

std::cout << " Hello World" << std::flush;

Tu n'en vois qu'une. Je suppose fork() copie n'importe quel tampon de sortie std::cout écrit à.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X