否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
是没用的。
Traditionaly您从seeder
创建engine
一次(的某种类型的像mt19937
)。然后,您存储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”标签?这与C.无关。 – UnholySheep
我不明白为什么我收到downvotes。我在问这是否线程安全,如果是更新种子的话。 – cateof
可能是因为类似的问题有冗长而详细的答案? –