电话
400 9058 355
rand() 因随机质量差、模偏差、线程不安全且依赖全局状态,现已不推荐使用;应改用 std::mt19937 配合 std::random_device 和分布类,确保线程安全与高质量随机性。
因为 rand() 是 C 标准库遗留函数,生成的伪随机数质量差、范围固定(RAND_MAX 通常只有 32767),且无法控制分布类型。更严重的是,它依赖全局状态,多线程下不安全,且种子只能用 srand() 设一次——哪怕你反复调用 srand(time(nullptr)),在快速循环中极易得到重复序列。
常见错误现象:rand() % 100 看似生成 0–99,但若 RAND_MAX 不是 100 的整数倍,低值概率会略高(模偏差);用 time(nullptr) 在一秒内多次初始化,结果全一样。

rand() 做密码学、模拟、游戏逻辑等对随机性有要求的场景srand()
rand() % N,改用 rand() / (RAND_MAX / N + 1)(仍不推荐,仅作对比理解)std::mt19937 是 C++11 引入的 Mersenne Twister 引擎,周期长(2¹⁹⁹³⁷−1)、统计性质好、速度快,是当前最常用的标准随机引擎。但它本身只产生均匀分布的 32 位无符号整数(uint32_t),必须配合分布类(如 std::uniform_int_distribution)才能得到指定范围或类型的随机值。
关键点:引擎要独立实例化,不能全局共享;种子应使用 std::random_device 获取真随机熵,而非 time(nullptr)。
std::random_device rd; // 真随机源(通常读 /dev/urandom 或 CryptGenRandom) std::mt19937 gen(rd()); // 用真随机数初始化 mt19937 std::uniform_int_distributiondis(1, 100); // 定义 [1, 100] 均匀分布 int x = dis(gen); // 每次调用生成一个 int
std::random_device 可能不可用或退化为伪随机(如 MinGW),可用 rd.entropy() == 0 判断std::mt19937 gen(42)
gen)建议按需创建或作为局部静态变量,避免跨线程共享分布类负责把引擎输出映射到目标范围与类型,不是引擎本身决定的。同一个 std::mt19937 实例可搭配多个分布对象,互不影响。
std::uniform_real_distribution dis(0.0, 1.0) (注意右边界不包含)std::uniform_int_distribution dis('a', 'z') ,再转 char(dis(gen))
std::uniform_int_distribution dis(-10, 10)
dis(gen) % 10——分布类已处理模偏差,直接用它即可性能提示:分布对象构造开销小,可复用;引擎调用是主要耗时,但 mt19937 很快,一般无需缓存结果。
每个线程必须拥有自己的 std::mt19937 实例。共享引擎会导致数据竞争,结果不可预测,且破坏随机性。
典型错误:把 gen 声明为全局或静态变量,然后多线程并发调用 dis(gen)。
thread_local std::mt19937 gen(rd()))std::random_device 通常是线程安全的,但某些实现可能不是;若担心,可在主线程生成一个种子,再用它初始化各线程的 mt19937
真正容易被忽略的是:即使你只用一个线程,如果对象生命周期管理不当(比如分布对象比引擎先销毁),也可能引发未定义行为。确保分布对象的生存期不长于它所使用的引擎。
邮箱:8955556@qq.com
Q Q:8955556
本文详解如何将Go官方present工具(用于生成HTML5...
PySNMP在不同版本中对SNMP错误状态(errorSta...
time.Sleep仅阻塞当前goroutine,其他gor...
PHPfopen()创建含特殊符号的文件名失败主因是操作系统...
WooCommerce中通过代码为分组产品动态聚合子商品的属...
io.ReadFull返回io.ErrUnexpectedE...
本文详解Yii2中控制器向视图传递ActiveRecord数...
本文详解为何通过wp_set_object_terms()为...
Pytest中使用@mock.patch类装饰器会导致补丁泄...
带缓冲的channel是并发安全的FIFO队列;make(c...