Является ли реализация fprintf() в glibc потокобезопасной?

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

изменить: чтобы уточнить, рассматриваемая программа представляет собой плагин http://www.lighttpd.net/, а сервер работает с несколькими рабочими потоками. .

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

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

Проблемы

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

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

person John Carter    schedule 27.02.2009    source источник
comment
Наблюдаете ли вы это в файле, который вы пишете с помощью fprintf, или вы наблюдаете это в потоках stdout и stderr?   -  person Craig S    schedule 27.02.2009


Ответы (3)


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

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

person PaulJWilliams    schedule 27.02.2009

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

Это не имеет ничего общего с безопасностью потоков, так как это имеет значение только в многопоточных программах с одним процессом.

person dsm    schedule 27.02.2009

Текущий стандарт C++ не говорит ничего полезного о параллелизме, равно как и стандарт C 1990 года. (Я не читал стандарт C 1999 года, поэтому не могу комментировать его; в готовящемся стандарте C++0x действительно что-то сказано, но я не знаю, что именно навскидку.)

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

person David Thornley    schedule 27.02.2009