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

StackOverflow https://stackoverflow.com/questions/594851

Вопрос

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

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

Просматривая файл, можно заметить, что некоторые записи перемешаны.

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

Проблемы

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

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

Решение

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

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

Другие советы

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top