#include <random>
int f() {
std::random_device seeder;
std::mt19937 engine(seeder());
std::uniform_int_distribution<int> dist(1, 6);
return dist(engine);
}
多个线程可以安全地调用此函数吗?函数线程安全吗?
每次都调用
std::random_device seeder;
和std::mt19937 engine(seeder());
是多余的吗? 最佳答案
没有C++ std
类型以非线程安全的方式使用全局数据。可以在不同的线程中访问这种类型的两个不相关实例。
默认情况下,如果没有同步,则无法从两个线程访问类型的一个实例。
您将创建局部变量。这些局部变量与其类型的任何其他实例都不相关。这里没有线程安全问题。
通过具有状态并重新使用它,可以最有效地产生伪随机值。您没有执行此操作,因此从1到6的随机数创建起来会相对昂贵。
std::random_device seeder;
std::mt19937 engine(seeder());
std::uniform_int_distribution<int> dist(1, 6);
return dist(engine);
您对
std::mt19937
的使用是多余的。您已经在创建一个random_device
,可以将其直接输入dist
,然后从中创建一个engine
,然后使用engine
。在这里使用engine
是没有用的。传统上,您需要从
engine
中创建一次mt19937
(某种类型,例如seeder
)。然后,您存储engine
,并将其反复传递给发行版。这一次进行了相对昂贵的“实数随机数”生成,以通过引擎通过分布生成一连串的伪随机数。
但是请注意,这种使用需要付费;您必须存储
engine
,并且必须防止对其进行多线程访问。执行此操作的“正确”方法是让一个对象为您生成随机值,然后将其传递到需要的地方。存储使用的初始种子还可以使您重复执行所涉及的随机数集。
如果您不喜欢显式传递随机状态的想法,则可以使用
thread_local
(或带有static
保护器的mutex
)。thread_local std::mt19937 engine(std::random_device{}());
std::uniform_int_distribution<int> dist(1, 6);
return dist(engine);
这将为每个线程创建一个
engine
,并使用engine
中的值初始化random_device
。关于c++ - 梅森纳捻线器对CPP安全吗,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40655814/