gpt4 book ai didi

c++ - 在C++中使用rand()或std::random_device安全生成随机数

转载 作者:行者123 更新时间:2023-12-01 14:53:27 27 4
gpt4 key购买 nike

我很难找到令人信服的有关C++中随机数生成的线程安全性的来源。

我正在处理的应用程序当前只有很少的线程可以访问随机数生成,但是将来可能会更多。

使用的第一件事是:

int randomInRange(const int min, const int max)
{
srand(time(0));
return min + (rand() % max);
}

从我发现的意义上说,这是错误的,因为为每个调用都设置了种子,因此它会对 rand()函数的统计随机性和性能产生负面影响。

尝试的下一件事情是使用一个拥有 std::mt19937单个实例的单例:
// RandomHelper.h
class RandomHelper
{
private:
std::mt19937 engine;

// Singleton
RandomHelper() : engine(std::random_device()()) {}

public:
static RandomHelper& getInstance();

int randomInRange(int min, int max)
{
std::uniform_int_distribution<int> uidist(min, max);
return uidist(engine);
}
};

// RandomHelper.cpp
RandomHelper& RandomHelper::getInstance()
{
static RandomHelper instance;
return instance;
}

这应该有助于统计随机性。但是为此,我了解每个线程有一个 std::mt19937实例会更好。

我不确定我理解为什么。

这是因为如果多个线程在完全相同的时间调用 RandomHelper::getInstance().randomInRange(.., ..),它们将得到相同的结果?又是不是线程安全的?

为了避免这种情况的发生,现将其实现为以下方式:
int randomInRange(const int min, const int max)
{
thread_local std::mt19937 engine(std::random_device{}());
std::uniform_int_distribution<int> uidist(min, max);
return uidist(engine);
}

到目前为止,这似乎是最好的解决方案,但我找不到关于 std::mt19937std::random_device的线程安全性的大量信息,以查看是否实际上需要在单例中具有那些实例的单个实例的thread_local变体。

我愿意做更多的研究,但是除了通常的C++引用文献之外,我不知道在哪里寻找,就我所知,这些引用文献并未提及任何有关线程安全性的内容。

最佳答案

随机数生成器引擎不是线程安全的。

使用thread_local为每个线程初始化一个引擎使其线程安全,所以我想说您的解决方案很好。

如果您对random_device的线程安全性有疑问,也可以将其设置为thread_local:

int randomInRange(const int min, const int max)
{
thread_local std::random_device rd;
thread_local std::mt19937 rng(rd());
thread_local std::uniform_int_distribution<int> uid;
return uid(rng, decltype(uid)::param_type{min,max});
}

还有更多未提及的话题:

C++ thread-safe uniform distribution random number generation

C++11 Thread safety of Random number generators

我敢肯定还有更多。

关于c++ - 在C++中使用rand()或std::random_device安全生成随机数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60450514/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com