В моей программе запущено несколько потоков. Каждый поток получает указатель на какой-то объект (в моей программе — вектор). И каждый поток изменяет вектор.
И иногда моя программа завершается с ошибкой segm. Я думал, что это произошло, потому что поток A начинает что-то делать с вектором, в то время как поток B не завершил работу с ним? Может ли это быть правдой?
Как я должен это исправить? Синхронизация потоков? Или, может быть, сделать флаг VectorIsInUse и установить этот флаг в true при работе с ним?
vectorКак и все контейнеры STL, не является потокобезопасным. Вы должны явно управлять синхронизацией самостоятельно. std::mutex или же boost::mutex можно использовать для синхронизации доступа к vector,
Не используйте флаг, так как он не является потокобезопасным:
isInUse флаг и это falseisInUse флаг и это falseisInUse в trueisInUse является false и устанавливает его truevectorОбратите внимание, что каждый поток должен будет заблокировать vector на все время его нужно использовать. Это включает в себя изменение vector и используя vectorитераторы как итераторы могут стать недействительными, если элемент, на который они ссылаются, erase() или vector претерпевает внутреннее перераспределение. Например не делайте:
mtx.lock();
std::vector<std::string>::iterator i = the_vector.begin();
mtx.unlock();
// 'i' can become invalid if the `vector` is modified.
Если вам нужен контейнер, который можно безопасно использовать из множества потоков, вам нужно использовать контейнер, специально разработанный для этой цели. Интерфейс стандартных контейнеров не предназначен для одновременной мутации или любого другого параллелизма, и вы не можете просто заблокировать проблему.
Вам нужно что-то вроде TBB или PPL, который имеет concurrent_vector в этом.
Вот почему почти каждая библиотека классов, предлагающая потоки, также имеет примитивы синхронизации, такие как взаимные блокировки / блокировки. Вам необходимо настроить один из них и установить / снять блокировку для каждой операции с общим элементом (операции чтения и записи, поскольку необходимо также предотвращать чтение во время записи, а не просто предотвращать одновременную запись нескольких записей).