Adloun

Deux sorties, deux destins

Exercice · niveau 2 · informatique (MP2I/MPI), chapitre 8 — Mémoire, fichiers et entrées-sorties

Énoncé

Ce programme écrit alternativement sur les deux sorties. On l'exécute deux fois : une fois vers le terminal, une fois avec ./prog > tout.txt 2>&1. Les deux sorties sont-elles dans le même ordre ?


for (int i = 0; i < 3; i = i + 1) {
    printf("resultat %d\n", i);
    fprintf(stderr, "trace %d\n", i);
}

Corrigé

Non, et la mesure est catégorique. Au terminal, les six lignes s'entrelacent dans l'ordre du programme. Redirigées ensemble dans un fichier, elles sortent ainsi :


trace 0
trace 1
trace 2
resultat 0
resultat 1
resultat 2

Toutes les traces avant tous les résultats, alors que le programme les a écrites en alternance.

La cause est le tamponnage, et il dépend de la destination :

FluxVers un terminalVers un fichier ou un tube
`stdout`tampon de lignetampon de bloc (8 ko ici)
`stderr`aucun tamponaucun tampon

Redirigé, stdout accumule ses trois lignes dans son tampon et ne les écrit qu'à la fin du programme ; stderr écrit immédiatement. D'où l'inversion.

Ce n'est pas un défaut, c'est le contrat : la sortie d'erreur doit parvenir même si le programme est tué à l'instant suivant — un message d'erreur perdu dans un tampon ne sert à rien. Le prix est cet ordre trompeur, et il coûte cher en mise au point : on croit lire une chronologie, on lit deux chronologies superposées.

Les deux parades. Séparer les flux — &gt; res.txt 2&gt; err.txt — ce qui rend chaque fichier lisible et est la raison d'être des deux sorties ; ou forcer l'écriture par fflush(stdout) avant chaque trace, ce qui rétablit l'ordre au prix d'un appel système par ligne.

Les autres exercices de ce chapitre Le cours du chapitre

Un blocage sur cet exercice ? Le tuteur d'Adloun guide par questions, sans donner la réponse.