Является ли реализация fprintf () в glibc поточно-ориентированной? - PullRequest
8 голосов
/ 27 февраля 2009

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

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

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

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

Проблемы

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

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

Ответы [ 3 ]

14 голосов
/ 27 февраля 2009

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

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

7 голосов
/ 27 февраля 2009

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

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

2 голосов
/ 27 февраля 2009

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

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

...