c++ - how - fourche() et sortie




use fork linux (6)

J'ai un programme simple:

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

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


Ce n'est pas tout à fait ce que vous pensiez à l'origine. Le tampon de sortie n'est pas partagé - lorsque vous exécutez la fourche, les deux processus obtiennent une copie du même tampon . Ainsi, une fois que vous avez créé une fourchette, les deux processus finissent par vider le tampon et imprimer le contenu séparément.

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


Ce que vous voyez probablement ici est un effet de mise en mémoire tampon. En général, la sortie est mise en mémoire tampon jusqu'à ce qu'elle soit vidée explicitement ou implicitement avec une action telle que la sortie d'une nouvelle ligne. Étant donné que la sortie est mise en mémoire tampon, les deux copies du processus bifurqué ont une sortie bufférée et, par conséquent, toutes deux l'affichent à la fin du processus et le vidage du tampon


La raison en est que lorsque vous invoquez std::cout<< cela n'effectue pas vraiment la sortie elle-même mais les données sont laissées dans un tampon dans le système. Lorsque vous faites la fourche, le code et les données sont copiés, ainsi que tous les tampons associés. Enfin, le père et le fils les rejettent à la sortie standard et vous voyez ainsi la sortie dupliquée.


La sortie standard utilise des E / S bufférisées. Lorsque fork() est appelée, la sortie standard n'est pas vidée et le contenu mis en mémoire tampon est répliqué dans le processus enfant. Ces tampons sont vidés lorsque le processus quitte, ce qui entraîne les deux sorties que vous voyez.

Si vous changez le programme pour:

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

vous devriez en voir un seul.


Parce que vous avez appelé fork () sans rincer tous les tampons en premier.

cout.flush();
fork();

Si tu utilises:

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

Vous n'en voyez qu'un. Je suppose que fork() copie le buffer de sortie std::cout .





fork