代码之家  ›  专栏  ›  技术社区  ›  Christopher Miller

“std::mt19937”静态函数变量线程安全吗?

  •  2
  • Christopher Miller  · 技术社区  · 2 年前

    我有一个功能 rand_double() 其使用 静态函数变量 带类型 std::mt19937 。多个线程可以同时使用此函数。

    #include <random>
    
    auto random_double(double min, double max) {
        static std::mt19937 generator{std::random_device{}()}; // Forgot to seed it, thanks @user4581301
        return std::uniform_real_distribution<>{min, max}(generator);
    }
    

    我的第一个问题是, 上面的代码是线程安全的吗 ?我知道自从C++11 初始化 的静态函数变量总是线程安全的,但是生成器的并发使用呢?

    2 回复  |  直到 2 年前
        1
  •  4
  •   Ted Lyngmo    2 年前

    要生成随机数 std::uniform_real_distribution 电话 operator() 参数生成器的。

    如果 mersenne twister 操作员有副作用:

    “发动机的状态提前了一个位置”

    这(通过任何指示器)都不被认为是线程安全操作。

    您可以将其用作 thread_local 这将具有预期效果,即。 static 在每个特定线程中:

    auto random_double(double min, double max) {
        thread_local std::mt19937 generator(std::random_device{}());
        return std::uniform_real_distribution<>{min, max}(generator);
    }
    
        2
  •  0
  •   xapi    2 年前

    不是线程安全的,因为生成器的并发使用可能导致数据争用。虽然C++11保证静态函数变量的初始化是线程安全的,但它不能确保这些变量的后续使用的线程安全。

    在您的代码中,生成器在多个线程之间共享,没有任何同步机制。因此,如果多个线程同时调用random_double,它们可能会同时访问和修改共享生成器,这可能导致未定义的行为或不准确的随机数。

    推荐文章