【发布时间】:2020-03-12 09:25:40
【问题描述】:
#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元素推送到struct A的向量a中,每个都在没有临界区的情况下创建。
我认为将新元素同时推送到同一个向量应该会出现一些问题,但是将新元素同时推送到不同的向量应该不会出现错误。
如果我将整个work 函数放入临界区,则不会发生错误。
因此,我得出结论,将新元素推送到不同的向量不会发生错误,但是如果它们在同一个向量中,则会发生错误。
但我无法解释原因。有人请告诉我这件事。 :(
【问题讨论】:
-
我想我找到了原因。当我将新的
struct A推送到向量b.b时,向量b.b将被重新分配以增加容量。结果,struct A& a将被释放并发生错误。
标签: c++ multithreading vector