私はc ++でマルチスレッドを理解しようとしていますが、この問題で立ち往生しています:forループでスレッドを起動すると、誤った値が出力されます。これはコードです:
#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;
}
値0、1、2、3、4が出力されることを期待していましたが、同じ値を2回取得することがよくありました。これは出力です:
Hello from thread 2
Hello from thread 3
Hello from thread 3
Hello from thread 4
Hello from thread 5
何が欠けていますか?
emplace_back
が奇妙であることは注目に値します。emplace_back
引数のリストを受け取り、それをのコンストラクターに渡しstd::thread
ます。の(rvalue)インスタンスを渡したstd::thread
ため、スレッドが作成され、そのスレッドがベクターに移動します。その操作は、より一般的な方法でよりよく表現されpush_back
ます。少し慣用的である(構築済みのthreads.emplace_back([i](){ print_id(i); });
場所)またはthreads.push_back(std::thread([i](){ print_id(i); }));
(構築+移動)のどちらかを書く方が賢明でしょう。
i
値でラムダに渡します[i]
。