Является ли Windows 'rand_s потокобезопасным?
-
02-07-2019 - |
Вопрос
Так же, как и в названии.Подозреваю, что это так, но я не смог найти нигде явно указанного этого.И в отношении этого свойства я бы не хотел полагаться на домыслы.
Решение
Если вы используете многопоточный в версии CRT все функции потокобезопасны, поскольку любая информация, относящаяся к конкретному потоку, хранится в TLS.rand_s на самом деле вообще не использует информацию о состоянии, поскольку он просто вызывает API операционной системы, поэтому вопрос потокобезопасности для rand_s не возникает.rand(), однако, зависит от начального значения для генерации случайного числа.
Другие советы
Крис сказал: rand()
не является потокобезопасным, поскольку его внутреннее состояние статично, но rand_s()
однако он должен быть потокобезопасным.
Джефф добавил, однако, что с многопоточной версией MSVCRT, rand()
Состояние хранится в локальном хранилище потока, так что все в порядке.
Visual Studio поставляется вместе с исходным кодом библиотеки среды выполнения.Хотя пробираться через некоторые из них может быть довольно болезненно, rand_s() довольно проста.
Все, что делает rand_s(), это вызывает SystemFunction036() в ADVAPI32.DLL, чтобы получить случайное значение.Все, что находится в ADVAPI32.DLL, должно быть потокобезопасным.
Со своей стороны, rand_s() получает указатель на эту функцию потокобезопасным способом.
Я не знаю, является ли rand_s потокобезопасным, но похоже, что это, вероятно, так, поскольку, похоже, он выполняет обратный переход к операционной системе для получения энтропии.(пока вы ссылаетесь на многопоточный CRT VC ++, все ставки отменяются, если вы ссылаетесь на однопоточный)
Если это поддерживается Windows CRT, вы можете попробовать вызвать rand_r, который является реентерабельной версией rand для posix.ИЛИ еще лучше boost::random, если вы уже используете boost.
учитывая, насколько распространенной скоро станет многопоточность, никто больше не должен использовать rand() в новом коде - всегда старайтесь использовать rand_r / rand_s /boost / различные защищенные ранды, зависящие от платформы / и т.д.
Я не могу придумать ни одной причины, по которой rand_s() или даже rand () не были бы потокобезопасными.