Простой способ избежать столкновения с засорением из разных потоков?

#c #multithreading #contention

#c #многопоточность #конфликт

Вопрос:

У меня есть многопоточная программа, в которой два отдельных потока отправляют отладочные выходные данные в std::clog, и выходные данные чередуются. Я хотел бы найти простой способ заставить выходные данные, по крайней мере, храниться отдельно, за исключением перевода строк в выходных данных. Таким образом, вывод отладки может быть более легко интерпретирован. В некоторых местах я вставил sleep (1) перед выводом и собрал выходные данные в строку перед отправкой в clog, чтобы уменьшить вероятность столкновения, но я бы предпочел более надежное и безотказное решение.

Есть ли простой способ гарантировать, что каждый поток записывает целую строку за раз в std::clog до того, как другой поток сможет войти и записать свою собственную строку вывода?

Ответ №1:

Особенно простого способа сделать это нет, и здесь есть подробное обсуждение этого:http://www.cplusplus.com/forum/general/27760 /

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

Это может быть производным, но если вы std::clog перенаправляете на файл, у вас также может быть несколько файлов для нескольких потоков.

Ответ №2:

Вы … не можете. Вы одновременно выполняете запись в один и тот же поток. Буферизация в clog немного поможет, но гарантий по-прежнему нет.

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

Ответ №3:

Да, вы ищете метод синхронизации между потоками. Обычно они доступны в API операционной системы, вы также можете найти его в Boost.