没有任何一个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
是无用的。
传统上,您会从seeder
创建一个engine
(某种类型的,如mt19937
),然后将其存储,并重复将其传递给分布。
这样做会进行相对昂贵的“真随机数”生成一次,通过引擎通过分布生成一系列伪随机数。
但是请注意,这种使用有成本;您必须存储engine
,并且必须防止多线程访问它。
正确的方法是拥有一个为您生成随机值的对象,并在需要时传递它。存储使用的初始种子也将允许您重复涉及的一组随机数字的执行。
如果您不喜欢明确传递随机状态的想法,则可以使用thread_local
(或带有mutex
保护的static
)。
thread_local std::mt19937 engine(std::random_device{}());
std::uniform_int_distribution<int> dist(1, 6);
return dist(engine);
这将为每个线程创建一个 engine
,并使用来自您的 random_device
的值初始化该 engine
。