#include <iostream>
#include <vector>
#include <thread>
#include <mutex>
struct A {
std::vector<int> a;
};
struct B{
std::vector<A> b;
std::mutex mtx;
};
void work(int id, struct B& b) {
std::unique_lock<std::mutex> lck(b.mtx);
b.b.push_back(A());
struct A& a = b.b.back();
lck.unlock();
for(int i = 0; i < 1000; i++) {
std::cout << id << " " << i << std::endl;
a.a.push_back(i);
}
}
int main() {
struct B b;
std::thread t1, t2;
t1 = std::thread([&] {
work(1, b);
});
t2 = std::thread([&] {
work(2, b);
});
t1.join();
t2.join();
return 0;
}
В этом коде возникают некоторые ошибки (например, ошибка сегментации)
Как я писал выше, struct B
имеет вектор struct A
, а struct A
имеет вектор int
.
Шаг 1) Каждый поток добавляет новый элемент struct A
к одному и тому же вектору (b.b
) с критическим сечением.
Шаг 2) После этого каждый поток помещает новый элемент int
в вектор a
из struct A
, каждый из которых создан без критической секции.
Я думал, что одновременный перенос нового элемента в один и тот же вектор должен возникают некоторые проблемы, но одновременное нажатие нового элемента в разные векторы не должно приводить к ошибкам.
Если я помещу целую функцию work
в критическую секцию, ошибки не возникает.
Итак, я пришел к выводу, что при добавлении нового элемента в разные векторы не возникнет ошибка, НО, если они находятся в одном и том же векторе, возникнет ошибка.
Но я не могу объяснить причину. Кто-нибудь, пожалуйста, расскажите мне об этом. (