梅森纳捻线器对CPP安全吗 [英] Is mersenne twister thread safe for cpp
问题描述
#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());
是多余的吗?
Can multiple threads call this function safely? Is the function thread safe?
It is reduntant to call std::random_device seeder;
and std::mt19937 engine(seeder());
every time?
推荐答案
没有C ++ std
类型以非线程安全的方式使用全局数据.可以在不同的线程中访问这种类型的两个不相关的实例.
No C++ std
type uses global data in a non-thread-safe way. Two unrelated instances of such a type can be accessed in different threads.
默认情况下,如果没有同步,则无法从两个线程访问类型的一个实例.
By default, one instance of a type cannot be accessed from two threads without synchronization.
您将创建局部变量.这些局部变量与其类型的任何其他实例都不相关.这里没有线程安全问题.
You are created local variables. These local variables are unrelated to any other instance of their type. There are no thread safety issues here.
通过具有状态并重新使用它可以最有效地产生伪随机值.您没有执行此操作,因此创建1到6的随机数会相对昂贵.
Pseudo-random values are most efficiently produced by having state and reusing it. You are not doing this, so your random number from 1 to 6 will be relatively expensive to create.
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
是没有用的.
Your use of std::mt19937
is redundant. You are already creating a random_device
, which could be fed to dist
directly, and then created an engine
from it, then using the engine
. The use of engine
here is useless.
传统上,您是从seeder
创建一次engine
(某种类型,例如mt19937
)一次.然后,您存储engine
,并反复将其传递给发行版.
Traditionaly you create an engine
(of some type, like mt19937
) once from a seeder
. You then store the engine
, and repeatedly pass it to distributions.
这会执行一次相对昂贵的真实随机数"生成,以通过引擎通过分布生成一连串的伪随机数.
This does the relatively expensive "real random number" generation once to generate a long series of pseudo-random numbers via engine through distribution.
但是请注意,这种使用需要付费;您必须存储engine
,并且必须防止对其进行多线程访问.
Note, however, that such use has a cost; you must store the engine
and you must prevent multiple-thread access to it.
执行此操作的正确"方法是让一个对象为您生成随机值,然后将其传递到需要的地方.存储使用的初始种子还可以使您重复执行所涉及的随机数集.
The "right" way to do this is to have an object that produces random values for you, and pass it around where you need it. Storing the initial seed used would also permit you to repeat the execution of the set of random numbers involved.
如果您不喜欢显式传递随机状态的想法,则可以使用thread_local
(或static
和mutex
防护).
If you don't like the idea of explicitly passing around your random state, you could use a thread_local
(or static
with a mutex
guard).
thread_local std::mt19937 engine(std::random_device{}());
std::uniform_int_distribution<int> dist(1, 6);
return dist(engine);
这将为每个线程创建一个engine
,并使用您的random_device
中的值初始化engine
.
This creates one engine
per thread, and the engine
is initialized with a value from your random_device
.
这篇关于梅森纳捻线器对CPP安全吗的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!