2009-02-27 4 views
7

Является ли fprintf потокобезопасным? The glibc manual, похоже, это так, но мое приложение, которое записывает в файл с использованием одного вызова fprintf(), похоже, смешивает частичную запись из разных процессов.Является ли реализация glibc fprintf() потокобезопасной?

Редактировать: Чтобы уточнить, рассматриваемая программа является плагином lighttpd, а сервер работает с несколькими рабочими потоками.

Глядя на файл, некоторые из записей смешаны.

редактировать 2: Кажется, что проблема, которую я вижу может быть из-за «рабочих потоков» LightTPD фактически являющихся отдельными процессами: http://redmine.lighttpd.net/wiki/lighttpd/Docs:MultiProcessor

Проблемы

Выполнив 2 или более процессов на то же гнездо у вас будет лучшее совпадение , но будет иметь несколько недостатков , которые вы должны знать из:

  • mod_accesslog может создавать сломанные журналы доступа, так как один и тот же файл открывается дважды и НЕ синхронизируется.
  • mod_status будет иметь n отдельные счетчики, по одному для каждого процесс.
  • mod_rrdtool не работает, поскольку он получает одну и ту же метку времени дважды.
  • mod_uploadprogress не отображает правильный статус.
+0

Вы наблюдаете это в файле, который вы пишете с помощью 'fprintf', или вы наблюдаете это в потоках' stdout' и 'stderr'? –

ответ

14

Вы вводите в заблуждение два понятия - запись из нескольких потоков и запись из нескольких процессов.

Внутри процесса можно гарантировать, что один вызов fprintf будет завершен до того, как следующий будет разрешен доступ к выходному буферу, но как только ваше приложение начнет выводить его в файл, вы находитесь во власти ОС. Без какого-либо механизма блокировки на основе ОС вы не можете гарантировать, что совершенно другое приложение не будет записывать в ваш файл журнала.

7

Мне кажется, что вам нужно читать на file locking. Проблема заключается в том, что несколько процессов (т. Е. Не потоки) одновременно записываются в один и тот же файл, и нет надежного способа гарантировать, что записи будут атомарными. Это может привести к тому, что файлы перезаписывают записи друг друга, смешанный вывод и вообще не детерминированное поведение.

Это не имеет никакого отношения к защите Thread, поскольку это имеет отношение только к программам многопоточности с одним процессом.

2

Нынешний стандарт C++ не говорит ничего полезного о параллелизме, а также о стандарте 1990 C. (Я не читал стандарт 1999 C, поэтому не могу комментировать его, но наступающий стандарт C++ 0x действительно говорит о вещах, но я точно не знаю, что из себя сделал.)

Это означает, что fprintf () сам по себе не является ни поточно-защищенным, ни иным, и что это будет зависеть от реализации. Я бы точно прочитал, о чем говорит документация glibc, и сравните его с тем, что вы делаете.

Смежные вопросы