Estou tentando entender o Multi-threading em c ++, mas estou preso neste problema: se eu lançar threads em um loop for, eles imprimirão valores incorretos. Este é o código:
#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;
}
Eu esperava imprimir os valores 0,1,2,3,4, mas muitas vezes obtive o mesmo valor duas vezes. Esta é a saída:
Hello from thread 2
Hello from thread 3
Hello from thread 3
Hello from thread 4
Hello from thread 5
O que estou perdendo?
emplace_back
é estranho: emplace_back
pega uma lista de argumentos e a passa para um construtor de std::thread
. Você passou por uma instância (rvalue) de std::thread
, portanto, construirá um thread e depois moverá o thread para o vetor. Essa operação é melhor expressa pelo método mais comum push_back
. Seria mais sensato escrever threads.emplace_back([i](){ print_id(i); });
(construir no lugar) ou threads.push_back(std::thread([i](){ print_id(i); }));
(construir + mover) que são um pouco mais idiomáticos.
i
por valor para lambda[i]
,.