`std::mt19937` 静态函数变量是线程安全的吗?

Tel*_*ope 4 c++ random thread-safety c++20 mt19937

我有一个函数,它使用类型为 的静态函数变量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);
}
Run Code Online (Sandbox Code Playgroud)

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

Nik*_*iou 5

要生成随机数,std::uniform_real_distribution请调用operator()参数生成器。

如果是梅森扭曲器,操作员会产生副作用:

“引擎的状态前进一位”

(从任何指标来看)这都不被视为线程安全操作。

您可以使用它来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);
}
Run Code Online (Sandbox Code Playgroud)

  • 并不是说它通常很重要,但如果均匀分布很重要,也请保留一个“thread_local”实例,因为它具有“内存”(状态)。 (2认同)