2010-11-17 36 views
6

Possible en double:
Why does printf not flush after the call unless a newline is in the format string? (in C)sommeil() retarde la sortie jusqu'à la fin

Salut,

J'utilise la fonction sleep() en C, et je suis en cours d'exécution un problème: je n'étais pas sûr que c'était le problème donc j'ai fait bouillir tout le code à ceci:

int main() { 

    printf("1"); 
    sleep(3); 
    printf("2"); 

    return 0; 
} 

Ce que je pensais que cela devrait produire est 1 .. attendez 3 secondes .. 2. Au lieu le programme attend pendant 3 secondes, puis imprime 12. Est-il possible d'utiliser la fonction de veille pour obtenir la première sortie?

Merci

+0

Comme je le mentionne ci-dessous, je ne savais pas que c'était la cause du problème. –

Répondre

3

Il est pas en fait la fonction de sommeil qui retarde la sortie, c'est la nature tampon du flux de sortie standard. La sortie de 2 est presque certainement également retardée jusqu'à ce que votre programme quitte la ligne principale mais le délai est si petit que vous ne le remarquez pas.

La sortie standard est mise en mémoire tampon si elle peut être détectée comme faisant référence à un périphérique interactif (sinon, elle est entièrement mise en mémoire tampon).

Si vous fflush (stdout) après chaque appel de sortie que vous voulez voir immédiatement, cela résoudra le problème.

Vous pouvez également utiliser setvbuf avant d'opérer sur stdout, pour le mettre à unbuffered et vous n'aurez pas à vous soucier d'ajouter toutes ces fflush lignes à votre code:

setvbuf (stdout, NULL, _IONBF, BUFSIZ); 

Il suffit de garder à l'esprit que peut affecter les performances un peu si vous envoyez la sortie dans un fichier. Gardez également à l'esprit que la prise en charge est définie par l'implémentation et n'est pas garantie par la norme.

section ISO C99 7.19.3/3 est le bit correspondant:

Lorsqu'un flux est unbuffered, les caractères sont destinés à apparaître à partir de la source ou à la destination le plus tôt possible. Sinon, des caractères peuvent être accumulés et transmis à l'environnement hôte ou en provenance de celui-ci en tant que bloc.

Lorsqu'un flux est entièrement mis en tampon, les caractères sont destinés à être transmis vers ou depuis l'environnement hôte en tant que bloc lorsqu'un tampon est rempli.

Lorsqu'un flux est ligne mise en tampon, les caractères sont destinés à être transmis vers ou depuis l'environnement hôte en tant que bloc lorsqu'un caractère de nouvelle ligne est rencontré. En outre, les caractères sont destinés à être transmis en bloc à l'environnement hôte lorsqu'un tampon est rempli, lorsque l'entrée est demandée sur un flux non tamponné ou lorsque l'entrée est demandée sur un flux en ligne tamponné nécessitant la transmission de caractères. de l'environnement hôte.

La prise en charge de ces caractéristiques est définie par l'implémentation et peut être affectée via les fonctions setbuf et setvbuf.

1

La sortie des tampons de bibliothèque standard, en attente jusqu'à ce qu'il y est suffisamment sortie pour amortir le coût de l'impression réelle.

Vous devez vider la mémoire tampon après chaque impression pour vous assurer qu'il sera imprimé avant que le code continue:

fflush(stdout); 
+0

Ce n'est pas le système d'exploitation qui effectue la mise en mémoire tampon, c'est la bibliothèque standard. –

+0

@Chris - Merci, corrigé. –

1
+3

Si vous pouvez répondre simplement en liant à une autre question, c'est un doublon - et vous devriez juste commenter pour nous le faire savoir, afin que nous puissions le fermer en double. – Cascabel

+0

Je ne savais pas que c'était le problème derrière cela, je pensais que cela a été causé par quelque chose dans la fonction sleep(), mais je vais ajouter le commentaire moi-même. –

0

Essayez:

int main() { 

    printf("1"); fflush(stdout); 
    sleep(3); 
    printf("2"); fflush(stdout); 

    return 0; 
} 

pour forcer la bibliothèque io pour vider les tampons est avant le sommeil et le retour des déclarations.