Saya mencoba memahami Multi-threading di c ++, tapi saya terjebak dalam masalah ini: jika saya meluncurkan utas dalam untuk loop mereka mencetak nilai yang salah. Ini kodenya:
#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;
}
Saya berharap bisa mencetak nilai 0,1,2,3,4 tetapi saya sering mendapatkan nilai yang sama dua kali. Ini hasilnya:
Hello from thread 2
Hello from thread 3
Hello from thread 3
Hello from thread 4
Hello from thread 5
Apa yang saya lewatkan?
emplace_back
aneh: emplace_back
mengambil daftar argumen dan meneruskannya ke konstruktor std::thread
. Anda telah melewati instance (rvalue) dari std::thread
, maka akan membangun utas, lalu memindahkan utas itu ke vektor. Operasi itu lebih baik diungkapkan dengan metode yang lebih umum push_back
. Akan lebih masuk akal baik menulis threads.emplace_back([i](){ print_id(i); });
(membangun di tempat) atau threads.push_back(std::thread([i](){ print_id(i); }));
(membangun + bergerak) yang agak lebih idiomatis.
i
nilai ke lambda[i]
,.