Comment écrire un fichier dans plusieurs processus en utilisant des fonctions d’E / S standard sous Linux?

Je travaille sur une fonctionnalité qui nécessite l’écriture d’un fichier journal unique (identifié par son chemin) dans plusieurs processus. Auparavant, chaque processus appelait printf pour diffuser le journal sur le terminal (sortie standard). Maintenant, je dois changer la destination de sortie en fichier. J’ai donc essayé d’utiliser freopen pour redirect la freopen standard vers le fichier dans chaque processus.

 freopen(file_path, "a", stdout); // 

Mais il semble que cela ne fonctionne pas bien. Un journal est manquant. Quelle est la pratique courante pour y parvenir?

BTW Dans notre exigence, l’utilisateur devrait être autorisé à changer de destination de journalisation entre le fichier et la sortie standard, de sorte que le premier argument “file_path” pourrait être tty lorsqu’il serait rétabli sur le terminal. Est-ce correct d’appeler freopen(tty, "a", stdout) ?

Les écritures en mode O_APPEND feront ce que vous voulez tant qu’elles sont inférieures aux octets PIPE_BUF , ce qui est généralement suffisant (environ 4k).

Par conséquent, définissez le fichier ed nouvellement freopen () sur buffed line ( _IOLBF ci-dessous), puis assurez-vous que vos écritures contiennent une nouvelle ligne pour vider le tampon:

 freopen(file_path, "a", stdout); setvbuf(stdout, (char *)NULL, _IOLBF, 0); // aka setlinebuf(stdout) under BSD ... printf("Some log line\n"); // Note the newline! 

Vous avez beaucoup d’options:

1) l’approche la plus simple serait que chaque processus écrive simplement dans le même journal indépendamment. Le problème, bien sûr, est que le fichier serait brouillé si deux processus écrivaient des messages différents en même temps.

2) Au lieu de cela, vous pouvez faire en sorte que les processus envoient des messages à un “maître logger”, qui transmettrait alors les messages un par un, dans l’ordre reçu. Le “master logger” peut utiliser des sockets. Si tous les processus étaient sur le même hôte, vous pourriez plutôt utiliser une queue de messages ou un canal nommé.

3) Plus simple encore, vous pourriez avoir un sémaphore à l’échelle du système pour vous assurer qu’un seul message à la fois est écrit.

4) Une autre approche pourrait consister à utiliser un enregistreur open-source tel que log4j ou syslog-ng

Placez votre sortie sur un handle de fichier appelé, par exemple, sortie à l’aide de fprintf . Comme les output = yourFile fichiers ne sont que des pointeurs, définissez simplement output = stdout ou output = yourFile . Ensuite, chaque fprintf(output, "sometext") finit par se retrouver là où ce handle est défini pour le moment. Vous pouvez même avoir une fonction pour redirect dynamicment la sortie à la volée en fonction des entrées de l’utilisateur.