#c #multithreading #vector #thread-safety #stdvector
Вопрос:
Я столкнулся с проблемой при многопоточности моего приложения, и, похоже, она сводится к не совсем пониманию того, как std::vector
взаимодействует с потоком.
Вообще говоря, я понимаю, что у меня может быть столько одновременных читателей, сколько я хотел бы, и если у меня есть писатель, я должен использовать a std::mutex
для блокировки моей темы, чтобы другие читатели или авторы не могли получить доступ к моему вектору, пока я пишу ему.
Однако у меня есть пример, когда я читаю только с помощью итератора, и это, похоже, приводит к сбою моего кода.
Например, следующий код:
std::vector<int> numbers;
for (int i = 0; i < 100; i ) {
numbers.push_back(std::rand());
}
for (autoamp; it = numbers.begin(); it != numbers.end(); it ) {
std::cout << "Number : " << (*it) << std::endl;
}
отлично подходит для распечатки списка случайных чисел. Но если я просто помещу второй цикл for в поток:
std::vector<int> numbers;
for (int i = 0; i < 100; i ) {
numbers.push_back(std::rand());
}
std::thread([amp;]() {
for (autoamp; it = numbers.begin(); it != numbers.end(); it ) {
std::cout << "Number : " << (*it) << std::endl;
}
});
Затем это каждый раз приводит к сбою с местом записи о нарушении доступа. Я попытался придумать, что может пойти не так. Моей первой мыслью было: «Возможно numbers
, это выходит за рамки, так что, если я сделаю снимок копией?»
std::vector<int> numbers;
for (int i = 0; i < 100; i ) {
numbers.push_back(std::rand());
}
std::thread([=]() {
for (autoamp; it = numbers.begin(); it != numbers.end(); it ) {
std::cout << "Number : " << (*it) << std::endl;
}
});
Та же ошибка. Если я создам класс и создам numbers
переменную-член, та же проблема. Так что, похоже, проблема не в том, что переменная выходит за рамки. Я даже попытался выполнить некоторую логику, кроме std::cout
как на случай, если запись на консоль вызывала проблемы, но это тоже не так.
Я уверен, что мне не хватает некоторых нюансов в использовании std::vector
с несколькими потоками, но я не могу этого понять-может ли кто-нибудь указать на мою ошибку?
Спасибо!
Комментарии:
1.
std::thread(anything);
приводит к тому, что программа завершается с помощьюterminate
вызова., путем~thread
вызова деструктора дляthread
объекта, который не былjoin
изменен илиdetach
изменен. Это не имеет никакого отношения к вектору, и все, что связано с временнымthread
объектом, уничтожаемым точкой с запятой.2. Ух ты, я чувствую себя идиотом! Это досадно тривиальная ошибка!