【问题标题】:Does random_device start at a different state for each thread?每个线程的 random_device 是否以不同的状态开始?
【发布时间】:2019-10-12 08:41:20
【问题描述】:

是否保证 random_device 不会在每个新线程的相同内部状态下启动?那么下面的代码有可能给出两个不同的值吗?

#include <iostream>
#include <random>
#include <thread>
#include <mutex>

using namespace std;

int main()
{
    auto thr = []()
    {
        static mutex mtx;
        mtx.lock();
        cout << random_device()() << " " << endl;
        mtx.unlock();
    };
    thread t1( thr );
    thread t2( thr );
    t1.join();
    t2.join();
}

【问题讨论】:

  • 不,我认为不能保证。
  • 为什么你需要这个呢?您可以简单地预先创建多个 RNG 或重复使用 random_device 。
  • 不,绝对与此无关。
  • @appleapple,random_device 是线程安全的,所以我可以这样做吗?我宁愿不相信这一点,因为这会使 random_device 的效率显着降低,即使没有争用因此没有内核等待。

标签: c++ random


【解决方案1】:

没有这样的保证。

在 cppreference 上我们可以阅读

std::random_device 可以根据实现定义的伪随机数引擎来实现,如果非确定性源(例如硬件设备)对实现不可用。在这种情况下,每个 std::random_device 对象都可能生成相同的数列。

这基本上取决于实现。

另一件事是创建新的random_devices 会产生性能成本。最好重复使用同一个。

auto thr = []()
{
    static mutex mtx;
    static random_device rd{};
    mtx.lock();
    cout << rd() << " " << endl;
    mtx.unlock();
};

【讨论】:

  • 我知道,但为了简单起见,我省略了单独的 random_device,它在这个例子中并没有什么坏处。
  • @BonitaMontero 我认为关键是如果您重复使用相同的random_device,您可以保证获得不同的值(除非实现只返回一个值)。所以在这个例子的上下文中它确实很重要。
  • 跨线程边界重用 random_device 没有意义。它肯定不是线程安全的。
  • @BonitaMontero 不确定您指的是什么。根据实现,它可以是完全线程安全的。在示例中,它也没有跨线程边界使用。通常,您只使用它来播种 PRNG,因此您可以以线程安全的方式将 RNG 或种子传递给线程。
  • 不确定,因为它是实现定义的。因为random_device 只用于初始化你的RNG,所以性能可能不是最重要的。 AFAIK linux 机器将使用/dev/urandom,这是线程安全的。 Windows 机器将使用一些 WinAPI 调用。我不认为它也不太可能是线程安全的。但 c++ 标准不保证
猜你喜欢
  • 2013-01-22
  • 2014-07-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-01
  • 2015-09-25
  • 1970-01-01
相关资源
最近更新 更多