梅森纳捻线器对CPP安全吗 [英] Is mersenne twister thread safe for cpp

查看:71
本文介绍了梅森纳捻线器对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(或staticmutex防护).

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆