シードの適切なデフォルトは次のとおりです。
std::random_device r;
std::seed_seq seed{r(), r(), r(), r(), r(), r(), r(), r()};
std::mt19937 eng(seed);
各スレッドでこれを行うだけで、うまくいくはずです:
#include <algorithm>
#include <functional>
#include <iostream>
#include <iterator>
#include <mutex>
#include <random>
#include <thread>
int main() {
std::mutex iomutex;
std::vector<std::thread> threads;
for (int i = 0 ; i < 10; ++i) {
threads.emplace_back([&iomutex](int tid) {
std::random_device r;
std::seed_seq seed{r(), r(), r(), r(), r(), r(), r(), r()};
std::mt19937 eng(seed);
std::uniform_int_distribution<> dist(1, 100);
std::lock_guard<std::mutex> ioguard(iomutex);
std::cout << "Thread " << tid << ": ";
std::generate_n(std::ostream_iterator<int>(std::cout, " "), 10, std::bind(dist, eng));
std::cout << '\n';
}, i);
}
for (auto &&t : threads) {
t.join();
}
}
または、メイン スレッドでシードを計算し、各ワーカーにデータを渡してエンジンを初期化することもできます。残念ながら を渡すことはできないseed_seq
ので、以下の例では初期化されたエンジンを渡すだけです。
int main() {
std::mutex iomutex;
std::vector<std::thread> threads;
std::random_device r;
for (int i = 0 ; i < 10; ++i) {
std::seed_seq seed{r(), r(), r(), r(), r(), r(), r(), r()};
std::mt19937 thread_eng(seed);
threads.emplace_back([&iomutex](int tid, std::mt19937 init_eng) {
std::mt19937 eng(std::move(init_eng));
std::uniform_int_distribution<> dist(1, 100);
std::lock_guard<std::mutex> ioguard(iomutex);
std::cout << "Thread " << tid << ": ";
std::generate_n(std::ostream_iterator<int>(std::cout, " "), 10, std::bind(dist, eng));
std::cout << '\n';
}, i, thread_eng);
}
for (auto &&t : threads) {
t.join();
}
}