2011-10-17 2 views
1

Dans mon application, je crée un ensemble de processus enfants. Après fork() j'ouvre un fichier par processus, définissez le stdout/stderr du processus créé pour pointer vers ce fichier, puis exécutez le programme prévu.Linux - Désactiver les E/S tamponnées dans les processus fils

Y at-il une option pour le processus parent pour configurer les choses de sorte que lorsque le processus fils effectue un printf, il soit immédiatement vidé dans le fichier de sortie sans avoir à appeler flush()? Ou existe-t-il une API qui peut être appelée depuis le processus fils lui-même (avant exec) pour désactiver les E/S mises en mémoire tampon?

+0

Voir la page de manuel de setvbuf, vous pouvez définir stdout sur unbuffered. stderr est déjà défini sur unbuffered. –

Répondre

0

Le problème ici est que printf est mis en mémoire tampon. Les descripteurs de fichiers sous-jacents ne sont pas tamponnés de cette façon (ils sont mis en mémoire tampon dans le noyau, mais l'autre extrémité peut lire à partir du même tampon de noyau). Vous pouvez changer le tampon en utilisant setvbuf comme mentionné dans un commentaire qui aurait dû être une réponse.

setvbuf(stdout, NULL, _IONBF, 0); 

Vous n'avez pas besoin de faire cela pour stdin ou stderr.

Vous ne pouvez pas le faire à partir du processus parent. C'est parce que les tampons sont créés par le processus fils. Le processus parent ne peut manipuler que les descripteurs de fichiers sous-jacents (qui sont dans le noyau), et non stdout (qui fait partie de la bibliothèque C).

P.S. Vous voulez dire fflush, pas flush.

+0

Cette réponse est pour la plupart correcte. Sauf pour le "tamponné dans le noyau". La fonction stdio, 'printf()' et 'setvbuf()' font partie de, est mise en mémoire tampon dans la libc. Buffered dans le noyau sont les pipes et fifos, mais la question indique explicitement que la redirection vers les fichiers a lieu. IOW, si le processus enfant peut être modifié, alors l'appel fourni à 'setvbuf()' sur stdout doit être ajouté au début du processus principal du processus enfant. (stderr n'est pas tamponné par défaut.) – Dummy00001

+0

@ Dummy00001: Tous les E/S sont mis en mémoire tampon dans le noyau, sauf si vous utilisez une extension comme 'O_DIRECT', auquel cas il sera encore tamponné par le disque avant d'être écrit. –

+0

On dirait que le setvbuf() n'est pas conservé à travers un exec? J'ai quelque chose comme ça .. if (fork() == 0) { setvbuf() exec()} Les appels printf dans le code executé sont toujours tamponnés. – Manohar

Questions connexes