Bonjour à tous
Je me suis trouvé récemment confronté à un souci miniime. En effet, j'ai remarqué que dans le fichier contenant les logs de mon serveur, les lignes étaient toutes rangées par serveur (le serveur est lancé par xinetd donc il peut y en avoir plusieurs qui tournent en même temps).
Mais le serveur écrit plusieurs lignes de log. Et chaque ligne est terminée par '\n'. Et j'étais jusqu'à présent persuadé que le '\n' activait un fflush() (en tout cas, c'est comme ça quand on écrit dans stdout). Donc dans le log qui contient toutes les lignes, ces lignes auraient dû être rangées en fonction du moment où elles sont écrites et non en fonction de qui les écrit.
J'en suis arrivé à la conclusion que le '\n' n'active pas de fflush(). Donc les lignes sont écrites physiquement au moment où le serveur se termine et qu'il ferme le log.
Pour vérifier, j'ai créé un petit code de test...
Code c : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> void fils(FILE *fp, int n) { int i; for (i=0; i < 5; i++) { fprintf(fp, "pid=%d écriture fils %d (%d)\n", getpid(), n, i); //fflush(fp); sleep(n); } } int main() { FILE *fp=NULL; int i; unlink("toto"); fp=fopen("toto", "a"); for (i=1; i <= 3; i++) { printf("Fils %d\n", i); if (fork() == 0) { fils(fp, i); exit(0); } } while (wait(NULL) != -1); fclose(fp); printf("ok\n"); return 0; }
Voià. Je crée 3 fils. Chaque fils écrit à son rythme dans un seul et unique log. Or, au final, le fichier de log "toto" contient les lignes rangées par n° de fils et non rangées par ordre d'écriture. Mais si maintenant on décommente le fflush(fp), là les lignes arrivent dans le log rangées par ordre d'écriture.
Et le résultat est le même si, au lieu d'ouvrir le fichier dans le père, je l'ouvre dans chaque fils...
Code c : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> void fils(FILE *fp, int n) { fp=fopen("toto", "a"); int i; for (i=0; i < 5; i++) { fprintf(fp, "pid=%d écriture fils %d (%d)\n", getpid(), n, i); //fflush(fp); sleep(n); } fclose(fp); } int main() { FILE *fp=NULL; int i; unlink("toto"); for (i=1; i <= 3; i++) { printf("Fils %d\n", i); if (fork() == 0) { fils(fp, i); exit(0); } } while (wait(NULL) != -1); printf("ok\n"); return 0; }
Donc il semblerait bien que le '\n' n'active pas forcéement un fflush(). Toutefois, on m'a toujours conseillé de le mettre pour stdout (et maintenant moi aussi je le conseille aux autres). Donc il semblerait que '\n" active le fflush() quand ça concerne spécifiquement stdout.
Pour vérifier ce dernier détail, je remplace alors fils(fp, i) par fils(stdout, i) et là effectivement, que le fflush() soit activé ou pas, les lignes apparaissent à l'écran dans l'ordre d'écriture.
Si quelqu'un avait un avis à ce propos...
Merci à tous. Heureux si je peux vous intéresser à ce nouveau challenge...![]()
Partager