Генерация случайных чисел, разделенных потоками, в C

#c #multithreading #random #fstream

#c #многопоточность #Случайный #fstream

Вопрос:

Мне нужно создать три файла .txt, заполненных случайными int, вызывая функцию генерации в отдельных потоках.

Проблема в том, что в результате у меня одинаковые значения во всех файлах .txt.

Функция, которая вычисляет и записывает значения:

   void generateMoves(int limit, std::string outputPath) {  //open fstream  std::ofstream fout;  fout.open(outputPath);  if (!fout.is_open()) {  std::cout lt;lt; "Error reading " lt;lt; outputPath lt;lt; " file. Exiting..." lt;lt; std::endl;  exit(1);  }    static thread_local std::mt19937 generator;  std::uniform_int_distributionlt;intgt; distribution(1, 3);    //generating amp; writing moves  for (int i = 0; i lt; limit; i  ) {    int value;  value = distribution(generator);  fout lt;lt; value lt;lt; std::endl;  }    fout.close();  }   

Я вызываю подобные потоки из main():

 int limit = 1000;  std::thread player1(generateMoves, limit, "player1.txt");  std::thread player2(generateMoves, limit, "player2.txt");  std::thread player3(generateMoves, limit, "player3.txt");   player1.join();  player2.join();  player3.join();  

Итак, как правильно разделить генерацию int?

Редактировать: Следуя приведенному ниже комментарию, я вставил разные семена в каждый поток, и теперь все работает нормально. Случайная генерация сейчас выглядит так:

 // put different *s* into each thread  srand(s);  //generating amp; writing  for (int i = 0; i lt; limit; i  ) {  int value;  value = rand() % 3   1;  fout lt;lt; value lt;lt; std::endl;  }  

Комментарии:

1. Используйте начальное значение в конструкторе. Вы создаете все свои генераторы с одним и тем же (по умолчанию) исходным кодом

2. Нет, на самом деле это худшее решение. Теперь все три потока используют (довольно плохой) одиночный генератор случайных чисел, предоставляемый системой.

3. Это не решает вопроса, но привыкает инициализировать объекты значимыми значениями, а не по умолчанию-инициализировать их и немедленно перезаписывать значения по умолчанию. В данном случае это означает изменение std::ofstream fout; fout.open(outputPath); на std::ofstream fout(outputPath); .

Ответ №1:

Как указано в комментариях, все ваши генераторы были созданы из одного исходного кода по умолчанию. Этого достаточно, чтобы дать каждому генератору другое семя:

 std::random_device rd1; static thread_local std::mt19937 generator(rd1());  

При этом используется (очень медленно) std::random_device , но только для генерации уникального начального значения для генератора mt.