Безопасное ведение журнала с использованием потоков

Мне нужно реализовать потокобезопасный механизм ведения журнала на C++ под Windows, и я хочу использовать библиотеку потоков.

Я хотел знать, может ли кто-нибудь дать мне несколько советов по этому поводу и что будет лучшим способом?

Сообщения журнала, скорее всего, будут каждый раз длиной в несколько строк, поэтому мне, вероятно, нужно сначала записать их в буфер, а затем сбросить в файл?

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

Любые советы и подсказки приветствуются.


person Tony The Lion    schedule 07.09.2010    source источник


Ответы (4)


Вместо того, чтобы писать свой собственный, почему бы не использовать существующий:

пантейос

Повышение

person Mitch Wheat    schedule 07.09.2010
comment
Две другие существующие библиотеки: log4cpp (log4cpp.sourceforge.net) и log4cxx (logging.apache.org/log4cxx/index.html). - person Bart van Ingen Schenau; 07.09.2010
comment
@Bart van Ingen Schenau: я видел упоминание о том, что эти 2 могут привести к утечке памяти.... - person Mitch Wheat; 07.09.2010
comment
@Bart: Pantheios позволяет использовать log4cpp в качестве серверной части. - person Matthieu M.; 07.09.2010

Да - сначала записать во временные объекты std::ostringstream, а затем сбросить их в журнал потока. Это нужно не только для того, чтобы не удерживать блокировку слишком долго, но и для того, чтобы манипуляторы потоков из разных потоков не влияли друг на друга, и чтобы отдельные вызовы operator<< не перемежались их выводом в журнале. Временный поток ostringstream позволяет обрабатывать полные, осмысленные многострочные сообщения и следить за тем, чтобы они были написаны как единое целое.

Я бы не стал заморачиваться с выделенной веткой, пока вы не профилируете ее и не увидите, является ли это проблемой. Просто хорошо.

(Распространенная ошибка производительности: потоковая передача сообщения журнала в объект перед принятием решения о том, требует ли уровень ведения журнала регистрации этого сообщения. Чтобы избежать этого, используйте макросы препроцессора, чтобы обернуть if вокруг потоковой передачи.)

person Tony Delroy    schedule 07.09.2010

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

person stefaanv    schedule 07.09.2010

Один из вариантов — поместить код регистрации в отдельное приложение или поток со скрытым окном и использовать PostMessage для отправки данных регистрации.

person ChrisBD    schedule 07.09.2010