У меня в приложении std::list<Info> infoList
, который разделен между двумя потоками. Эти 2 темы обращаются к этому списку следующим образом:
Тема 1 : использует push_back()
, pop_front()
или clear()
в списке (в зависимости от ситуации)
Поток 2 : использует iterator
для перебора элементов в списке и выполнения некоторых действий.
Поток 2 выполняет итерацию списка следующим образом:
for(std::list<Info>::iterator i = infoList.begin(); i != infoList.end(); ++i)
{
DoAction(i);
}
Код скомпилирован с использованием GCC 4.4.2.
Иногда ++ i вызывает segfault и вылетает из приложения. Ошибка вызвана в строке 143 std_list.h в следующей строке:
_M_node = _M_node->_M_next;
Полагаю, это гоночное состояние. Список мог измениться или даже очиститься потоком 1, пока поток 2 его итерировал.
Я использовал Mutex для синхронизации доступа к этому списку, и все прошло нормально во время моего начального теста. Но система просто зависает при стресс-тестировании, что делает это решение совершенно неприемлемым. Это приложение в режиме реального времени, и мне нужно найти решение, чтобы оба потока могли работать максимально быстро, не влияя на общую пропускную способность приложений.
Мой вопрос такой:
Поток 1 и поток 2 должны выполняться максимально быстро, поскольку это приложение в реальном времени. Что я могу сделать, чтобы предотвратить эту проблему и сохранить производительность приложения? Существуют ли алгоритмы без блокировок для решения такой проблемы?
Это нормально, если я пропускаю некоторые недавно добавленные Info
объекты в итерации потока 2, но что я могу сделать, чтобы итератор не стал висящим указателем?
Спасибо