#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;
}
This code occurs some errors (like segmentation fault)
As I wrote above, struct B
has a vector of struct A
and struct A
has a vector of int
.
Step 1) Each threads pushes new struct A
element to the same vector (b.b
) with critical section.
Step 2) After then, each thread pushes new int
element to the vector a
of struct A
each created without critical section.
I thought pushing new element to the same vector concurrently should occurs some problems, but pushing new element to the different vectors concurrently should not occur errors.
If I put whole work
function into the critical section, it doesn't occur error.
So, I concluded pushing new element to the different vectors will not occur error, BUT if they are in the same vector, it occurs error.
But I cannot explain the reason. Someone please tell me about this. :(
When the second thread pushes a new value to b.b
this vector might get resized. If it gets resized all references to it's elements are getting invalidated. So the reference A& a
of the first thread gets invalidated.
You could
std::list
(linked list) resize()
the vector b.b
before working with it, so it doesn't need to be resized later (or reserve()
, doesn't make much of a difference here)std::vector
reallocates its memory when you push_back
, because it needs additional memory.
If you reserve() the vector, it won't reallocate until it needs additional memory.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With