Je note que l' <system.h>
est un non-standard-tête; je l'ai remplacé par <unistd.h>
et le code compilé correctement.
Lors de la sortie de votre programme est d'aller dans un terminal (écran), c'est la ligne de mise en mémoire tampon. Lors de la sortie de votre programme va à un tuyau, il est entièrement mis en mémoire tampon. Vous pouvez contrôler le mode de mise en mémoire tampon par le Standard de la fonction C setvbuf()
et de la _IOFBF
(complet) la mémoire tampon, _IOLBF
(ligne) la mémoire tampon et d' _IONBF
(pas de tampon) modes de fonctionnement.
Vous avez pu le démontrer dans votre programme révisé par la tuyauterie de la sortie de votre programme, par exemple, cat
. Même avec les retours à la ligne à la fin de l' printf()
des chaînes, vous pouvez voir la double information. Si vous l'envoyez directement à la borne, puis vous verrez un grand nombre d'informations.
La morale de l'histoire est prudent de faire appel fflush(0);
de vider tous les tampons d'e/S avant de bifurquer.
Ligne-par-ligne d'analyse, comme l'a demandé (broches etc supprimés et les espaces enlevé par un marquage de l'éditeur):
printf( "Hello, my pid is %d", getpid() );
pid = fork();
if( pid == 0 )
printf( "\nI was forked! :D" );
sleep( 3 );
else
waitpid( pid, NULL, 0 );
printf( "\n%d was forked!", pid );
L'analyse:
- Des Copies "Bonjour, mon pid est 1234" dans le tampon de sortie standard. Car il n'y a pas de saut de ligne à la fin et la sortie est en cours d'exécution en ligne-mode mémoire tampon (ou full-mode mémoire tampon), rien ne s'affiche sur le terminal.
- Donne-nous de deux processus distincts, avec exactement le même matériel dans la sortie standard (stdout) de la mémoire tampon.
- L'enfant a
pid == 0
et exécute les lignes 4 et 5; le parent a une valeur non nulle pour pid
(l'un des rares différences entre les deux processus - les valeurs de retour de getpid()
et getppid()
sont les deux autres).
- Ajoute un saut de ligne et "j'ai été fourchue! :D" à la mémoire tampon de sortie de l'enfant. La première ligne de sortie s'affiche sur le terminal; le reste est tenue dans la mémoire tampon depuis la sortie est de la ligne de mise en mémoire tampon.
- Tout s'arrête pendant 3 secondes. Après cela, l'enfant s'arrête normalement à travers le retour à la fin de la main. À ce stade, les données résiduelles dans la sortie standard (stdout) de la mémoire tampon est vidé. Cela laisse de la position de sortie à la fin d'une ligne car il n'y a pas de saut de ligne.
- Le parent vient ici.
- Le parent attend l'enfant à la fin de mourir.
- La mère ajoute un saut de ligne et "1345 était fourchue!" à la mémoire tampon de sortie. Le saut de ligne vide le "Bonjour" message à la sortie, après le incomplète généré par l'enfant.
Le parent maintenant arrête normalement à travers le retour à la fin de la main, et les données résiduelles est vidé; car il n'y a pas de saut de ligne à la fin, la position du curseur après le point d'exclamation, et l'invite du shell s'affiche sur la même ligne.
Ce que je vois, c'est:
Osiris-2 JL: ./xx
Hello, my pid is 37290
I was forked! :DHello, my pid is 37290
37291 was forked!Osiris-2 JL:
Osiris-2 JL:
Le PID numéros sont différents, mais l'aspect général est clair. L'ajout de nouvelles lignes à la fin de l' printf()
des déclarations (qui devient la norme de pratique très rapidement) modifie la sortie d'un lot:
#include <stdio.h>
#include <unistd.h>
int main()
{
int pid;
printf( "Hello, my pid is %d\n", getpid() );
pid = fork();
if( pid == 0 )
printf( "I was forked! :D %d\n", getpid() );
else
{
waitpid( pid, NULL, 0 );
printf( "%d was forked!\n", pid );
}
return 0;
}
Maintenant, je reçois:
Osiris-2 JL: ./xx
Hello, my pid is 37589
I was forked! :D 37590
37590 was forked!
Osiris-2 JL: ./xx | cat
Hello, my pid is 37594
I was forked! :D 37596
Hello, my pid is 37594
37596 was forked!
Osiris-2 JL:
Notez que lors de la sortie passe à la borne, c'est la ligne de tampon, de sorte que le "Bonjour" de la ligne s'affiche avant l' fork()
et il n'y avait qu'un seul exemplaire. Lorsque la sortie est redirigée vers cat
, il est pleinement mis en mémoire tampon, de sorte que rien ne s'affiche avant l' fork()
, et les deux procédés ont le "Bonjour" de la ligne dans la mémoire tampon pour être vidées.