Próbuję zrozumieć wielowątkowość w c ++, ale utknąłem w tym problemie: jeśli uruchomię wątki w pętli for, wypiszą one nieprawidłowe wartości. To jest kod:
#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;
}
Spodziewałem się wydrukowania wartości 0,1,2,3,4, ale często otrzymywałem tę samą wartość dwukrotnie. To jest wynik:
Hello from thread 2
Hello from thread 3
Hello from thread 3
Hello from thread 4
Hello from thread 5
Czego mi brakuje?
emplace_backjest dziwne: emplace_backbierze listę argumentów i przekazuje ją konstruktorowi std::thread. Minąłeś instancję (rvalue) std::thread, dlatego zbudujesz wątek, a następnie przeniesiesz ten wątek do wektora. Operację tę lepiej wyraża bardziej popularna metoda push_back. Bardziej sensowne byłoby pisanie threads.emplace_back([i](){ print_id(i); });(konstruowanie na miejscu) lub threads.push_back(std::thread([i](){ print_id(i); }));(konstruowanie + ruch), które są nieco bardziej idiomatyczne.
iprzez wartość lambda,[i].