Qu’est-ce que signifie entièrement tamponné, tamponné en ligne et non tamponné en C?

Je suis tombé sur une ligne dont la sortie de la commande cat est entièrement tamponnée. Qu’est-ce que ça veut dire?

Norme C11 en ligne , 7.21.3 / 3:

Lorsqu’un stream n’est pas mis en mémoire tampon , les caractères doivent apparaître dès que possible dans la source ou dans la destination. Sinon, les caractères peuvent être accumulés et transmis vers ou depuis l’environnement hôte sous forme de bloc. Lorsqu’un stream est entièrement mis en mémoire tampon , les caractères sont destinés à être transmis vers ou depuis l’environnement hôte sous forme de bloc lorsqu’un tampon est rempli. Lorsqu’un stream de ligne est mis en mémoire tampon , les caractères sont destinés à être transmis à ou depuis l’environnement hôte sous forme de bloc lorsqu’un caractère de nouvelle ligne est rencontré. De plus, les caractères sont destinés à être transmis sous forme de bloc à l’environnement hôte lorsqu’un tampon est rempli, lorsque l’entrée est demandée sur un stream non tamponné ou lorsque l’entrée est demandée sur un stream en ligne mis en mémoire tampon qui nécessite 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 .

7.21.3 / 7:

Au démarrage du programme, trois stream de texte sont prédéfinis et n’ont pas besoin d’être ouverts explicitement – entrée standard (pour lire une entrée conventionnelle), sortie standard (pour écrire une sortie classique) et erreur standard (pour écrire une sortie de diagnostic). Initialement ouvert, le stream d’erreur standard n’est pas entièrement mis en mémoire tampon; les stream d’entrée et de sortie standard sont entièrement mis en mémoire tampon si et seulement si le stream peut être déterminé de ne pas faire référence à un périphérique interactif.

La sortie non mise en mémoire tampon écrit les octets du fichier d’entrée sur la sortie standard sans délai dès leur lecture.

La sortie en mémoire tampon complète lit d’abord le fichier complet en séquence comme il l’a lu, puis il est stocké dans une mémoire tampon et affiche le contenu de la mémoire tampon.

Avec l’option -u, vous pouvez l’éviter.

[ J’utilise Perl dans les exemples pour la concision et la facilité de reproduction, mais les concepts illustrés ne sont pas spécifiques à Perl. C fonctionne de la même manière. ]

La mise en mémoire tampon dicte la fréquence à laquelle les éléments écrits dans un descripteur de fichier sont vidés (envoyés) vers le système d’exploitation. Comparez le comportement des deux commandes suivantes:

 # With buffering (default) perl -e'$|=0; print "a"; sleep(2); print "b\n";' # Without buffering perl -e'$|=1; print "a"; sleep(2); print "b\n";' 

Normalement, le tampon n’est vidé que lorsqu’il est plein. La sortie tamponnée en ligne est également vidée lorsqu’une nouvelle ligne est rencontrée. Comparer:

 perl -e'print "a"; sleep(2); print "b\n";' perl -e'print "a\n"; sleep(2); print "b\n";' 

La plupart des programmes utilisent la mise en mémoire tampon des blocs. Cependant, ils optent généralement pour la mise en mémoire tampon de lignes pour la sortie standard lorsqu’elle est connectée à un terminal. Comparer:

 # Perl's STDOUT is line-buffered when connected to a terminal. perl -e'print "a\n"; sleep(2); print "b\n";' # Perl's STDOUT is fully buffered when connected to a pipe. perl -e'print "a\n"; sleep(2); print "b\n";' | cat # unbuffer uses pseudo-ttys to fool a program into thinking it's connected to a terminal. unbuffer perl -e'print "a\n"; sleep(2); print "b\n";' | cat