Я бы, вероятно, сгенерировал бы seed in main
и передал бы seed каждой функции потока. Я бы не стал использовать вывод std::random_device
напрямую - я бы поместил числа в что-то вроде std::set
или std::unordered_set
, пока не получу столько семян, сколько хотел, чтобы убедиться, что я не дал двананизывает одно и то же семя (что, очевидно, было бы пустой тратой времени).
Что-то по этой общей линии:
int do_work(unsigned long long seed) {
//Get random number generators
typedef std::mt19937 MyRNG;
//seed generator
MyRNG rng(seed);
//make my uniform distributions for each parameter
std::uniform_real_distribution<> param1(-1,1);
std::uniform_real_distribution<> param2(-1,1);
double x,y;
//Do my scan
for (int i = 0; i < N; i++) {
x = param1(rng);
y = param2(rng);
//Do things with x and y*
}
}
static const int num_threads = 4;
int main() {
std::set<unsigned long long> seeds;
while (seeds.size() < num_threads)
seeds.insert(std::random_device()());
std::vector<std::thread> threads;
for (auto const seed: seeds)
threads.emplace_back(std::thread(do_work, seed));
for (auto &t : threads)
t.join();
}
В сторону, используя один результат из random_device
для посеваstd::mt19937
довольно сильно ограничивает генератор - вы даете ему только 32 (или, возможно, 64) бита семян, но на самом деле он содержит 19937 бит исходного материала. std::seed_seq
пытается улучшить это хотя бы до некоторой степени (среди прочего, вы можете использовать ряд выходных данных из std::random_device
для создания семени.
О, и учитывая, что ваши два экземпляра uniform_real_distribution
используйте одни и те же параметры, возможно, нет необходимости в двух отдельных объектах распространения.