Использование итераторов std::вектор в потоке

#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. Ух ты, я чувствую себя идиотом! Это досадно тривиальная ошибка!