问题
I'm trying to understand Multi-threading in c++, but I'am stuck in this problem: if I launch threads in a for loop they print wrong values. This is the code:
#include <iostream>
#include <list>
#include <thread>
void print_id(int id){
printf("Hello from thread %d\n", id);
}
int main() {
int n=5;
std::list<std::thread> threads={};
for(int i=0; i<n; i++ ){
threads.emplace_back(std::thread([&](){ print_id(i); }));
}
for(auto& t: threads){
t.join();
}
return 0;
}
I was expecting to get printed the values 0,1,2,3,4 but I often got the same value twice. This is the output:
Hello from thread 2
Hello from thread 3
Hello from thread 3
Hello from thread 4
Hello from thread 5
What I'm missing?
回答1:
The [&]
syntax is causing i
to be captured by reference. So quite often therefore i
will be further advanced when the thread runs than you might expect. More seriously, the behaviour of your code is undefined if i
goes out of scope before a thread runs.
Capturing i
by value - i.e. std::thread([i](){ print_id(i); })
is the fix.
回答2:
Two problems:
You have no control over when the thread runs, which means the value of the variable
i
in the lambda might not be what you expect.The variable
i
is local for the loop and the loop only. If the loop finishes before one or more thread runs, those threads will have an invalid reference to a variable whose lifetime have ended.
You can solve both these problems very simply by capturing the variable i
by value instead of by reference. That means each thread will have a copy of the value, and that copy will be made uniquely for each thread.
回答3:
Another thing :
Do not wait until to have always an ordered sequence: 0, 1, 2, 3, ... because the multithreading execution mode has a specificity: indeterminism.
Indeterminism means that the execution of the same program, under the same conditions, gives a different result.
This is due to the fact that the OS schedules threads differently from one execution to another depending on several parameters: CPU load, priority of other processes, possible system interruptions, ...
Your example contains only 5 threads, so it's simple, try to increase the number of threads, and for example put a sleep in the processing function, you will see that the result can be different from one execution to another .
来源:https://stackoverflow.com/questions/60093210/c-threads-inside-for-loop-print-wrong-values