Can someone please explain why placing arguments for multithreading tasks inside a vector causes those arguments not to be correctly initialized?
#include <iostream>
#include <thread>
#include <stdlib.h>
#include <vector>
using namespace std;
struct my_struct {
int a;
int b;
int c;
};
void test_func(my_struct *arg) {
cout << "inside thread join: a: " << arg->a << " b: " << arg->b << " c: " << arg->c << "\n";
}
int main() {
vector<my_struct> my_structs;
for(int i = 0; i < 5; i++) {
my_struct x = {.a = i+1, .b=i+1, .c=i+1};
my_structs.emplace_back(x);
}
vector<thread> threads;
for (int i = 0; i < 5; i++) {
threads.emplace_back([&](){test_func(&my_structs[i]);});
}
for (auto &th: threads) {
th.join();
}
for (auto &s : my_structs) {
cout << "after join: a: " << s.a << " b: " << s.b << " c: " << s.c << "\n";
}
return 0;
}
The output for above code is
inside thread join: a: 3 b: 3 c: 3
inside thread join: a: 0 b: 0 c: 0
inside thread join: a: 5 b: 5 c: 5
inside thread join: a: 4 b: 4 c: 4
inside thread join: a: 3 b: 3 c: 3
after join: a: 1 b: 1 c: 1
after join: a: 2 b: 2 c: 2
after join: a: 3 b: 3 c: 3
after join: a: 4 b: 4 c: 4
after join: a: 5 b: 5 c: 5
You can see the argument values are incorrect, but they've been fixed after joining the threads.
If I use arrays instead of vectors, the output is totally fine. For example
int main() {
my_struct my_structs[5];
for(int i = 0; i < 5; i++) {
my_structs[i] = {.a = i+1, .b=i+1, .c=i+1};
}
thread threads[5];
for (int i = 0; i < 5; i++) {
threads[i] = thread(test_func, &my_structs[i]);
}
for (auto &th: threads) {
th.join();
}
for (auto &arg : my_structs) {
cout << "after join: a: " << arg.a << " b: " << arg.b << " c: " << arg.c << "\n";
}
return 0;
}
The code above will have perfectly normal output.
inside thread join: a: inside thread join: a: inside thread join: a: 4 b: 4 c: 4
inside thread join: a: 3 b: 3 c: 3
1 b: 1 c: 1
2 b: 2 c: 2
inside thread join: a: 5 b: 5 c: 5
after join: a: 1 b: 1 c: 1
after join: a: 2 b: 2 c: 2
after join: a: 3 b: 3 c: 3
after join: a: 4 b: 4 c: 4
after join: a: 5 b: 5 c: 5
Can some one please explain why the structs inside the vector are not initialized in sequence before the threads are created? Thank you.
Update: One more question please, if I remove the -O3 flag when compiling the code with vectors, it will throw a segfault error when running. However if I do the same on the code with arrays it compiles and runs just fine, is there a reason for this?