2012-08-07 2 views
1

У меня есть std::map < std::string, std::string >, у которого значения добавлены к нему нерегулярными интервалами из одного потока (но часто и должны быть очень быстрыми), а иногда и группами удаленных записей.Эффективно итерации по карте при вставке на другую резьбу

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

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

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

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

Если у вас нет возможности использовать карту для этого, может ли кто-нибудь предложить любую другую структуру данных, которую я мог бы использовать?

Редактировать: Я надеюсь на решение, что означает, что при добавлении элемента мне не нужно вынимать дорогой замок.

+0

Я должен добавить, что я не могу использовать C++ 11 в это время. – jcoder

+7

Насколько велика ваша «карта»? Блокирование его на время ввода-вывода может быть дорогостоящим, но вы можете сделать копию карты (быстрее, чем записать ее на диск) и выполнить ввод-вывод из копии. Это гарантирует, что на выходе будет отображаться состояние карты в определенный момент времени. – Chad

+0

Сто или около того записей обычно, но может быть несколько сотен или несколько раз, – jcoder

ответ

4

Есть 2 решения я могу видеть в данный момент:

  1. (легкий, но все еще может занять слишком много времени): скопировать карту (или назначить другой контейнер) во время блокировки, а затем сбросить локальную копию в журнал отладки, но не заблокирован
  2. (Еще одна работа): делегировать обновления карты другому потоку через очередь. Если другой поток - это тот, который сбрасывается в журнал отладки, вам больше не нужны блокировки. Таким образом, быстрые потоки блокируются только при доступе к очереди.
+0

Решение oooh два может работать, важно, чтобы эти обновления карт не долго удерживали основной поток, но не нужно делать это быстро. – jcoder

Смежные вопросы