консоль в многопоточных приложениях - PullRequest
4 голосов
/ 30 марта 2011

Обычно разрабатываю приложения. Я привык печатать на консоли, чтобы получить полезную информацию об отладке / трассировке.Приложение, которым я сейчас занимаюсь, поскольку оно многопоточное, иногда я вижу, как мои printf перекрывают друг друга.

Я пытался синхронизировать экран, используя mutex, но в итоге я замедлил и заблокировал приложение.Как решить эту проблему?

Мне известны библиотеки журналов MT, но при их использовании, поскольку я слишком много регистрирую, я замедляю (немного) свое приложение.

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

Вам известна какая-либо библиотека, которая уже делает это?Я использую Linux / gcc.

спасибо

afg

Ответы [ 5 ]

11 голосов
/ 31 марта 2011

У вас есть 3 варианта. В порядке возрастания сложности:

  1. Просто используйте простой мьютекс в каждом потоке. Мьютекс является общим для всех потоков.
  2. Отправить все выходные данные в один поток, который не делает ничего, кроме ведения журнала.
  3. Отправьте все выходные данные в отдельное приложение для ведения журнала.

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

Номер 3 - это то, что вы собираетесь делать в приложениях типа сервера, критичных к производительности, но минимальный выигрыш в производительности, который вы получаете при таком подходе, составляет 1: очень трудно достичь, 2: очень легко облажаться и 3: не единственная или даже самая убедительная причина, по которой люди обычно используют такой подход Скорее, люди обычно используют этот подход, когда им требуется отделить службу регистрации от приложений, использующих ее.

1 голос
/ 30 марта 2011

Какую ОС вы используете?

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

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

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

1 голос
/ 30 марта 2011

Как я знаю, критический участок имеет меньший вес.

Если вы используете gcc, вы можете использовать атомарный доступ. Ссылка.

0 голосов
/ 31 марта 2011

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

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

0 голосов
/ 30 марта 2011

Честно говоря, Mutex - единственный способ, которым вы действительно хотите это сделать, поэтому он всегда будет медленным в вашем случае, потому что вы используете так много операторов печати ... так что, чтобы решить свой вопрос, не надоt использовать так много операторов print_f;это ваша проблема для начала.

Хорошо, ваше решение использует мьютекс для печати?Возможно, у вас должен быть мьютекс к очереди сообщений, которую другой поток обрабатывает для печати;это может повесить трубку, но я думаю, что это будет быстрее.Итак, используйте активную цепочку журналирования, которая вращается в ожидании печати входящих сообщений.Сетевое решение тоже может работать, но это требует больше работы;попробуйте это в первую очередь.

...