I am writing an application requiring a variable number of threads, which I would like to create within a vector over which I could iterate. The application consistently skips the first iteration of the for-loop but instead performs an unintended operation at the end of the loop. I would like not only to solve the issue but also to understand its origin.
Here is a toy example to recreate the behavior:
#include <iostream>
#include <mutex>
#include <thread>
#include <vector>
std::mutex my_mutex;
void print_func(int idx){
std::lock_guard<std::mutex> f(my_mutex);
std::cout << "Thread id: " << idx << std::endl;
}
int main() {
const auto processor_count = 4;
std::vector<std::thread> ThreadVector;
for(int i = 0; i < processor_count; i ){
ThreadVector.emplace_back([&](){print_func(i);});
}
for(auto& t: ThreadVector){
t.join();
}
return 0;
}
Here's the output:
Thread id: 1
Thread id: 2
Thread id: 3
Thread id: -214744752
Here's the intended behavior:
Thread id: 0
Thread id: 1
Thread id: 2
Thread id: 3
CodePudding user response:
Your lambda:
[&](){print_func(i);}
captures the int i
by reference, so when the thread started, i
is no longer the same value, and for the last iteration, i
goes out of scope, therefore it has garbage value from the stack.
Capturing by value instead of reference will solve your problem:
[i](){print_func(i);}