C++11 中有许多新的随机数生成器引擎和分布函数。它们线程安全吗?如果您在多个线程之间共享单个随机分布和引擎,是否安全并且您仍然会收到随机数吗?我正在寻找的场景是这样的,
void foo() {
std::mt19937_64 engine(static_cast<uint64_t> (system_clock::to_time_t(system_clock::now())));
std::uniform_real_distribution<double> zeroToOne(0.0, 1.0);
#pragma omp parallel for
for (int i = 0; i < 1000; i++) {
double a = zeroToOne(engine);
}
}
使用 OpenMP 或
void foo() {
std::mt19937_64 engine(static_cast<uint64_t> (system_clock::to_time_t(system_clock::now())));
std::uniform_real_distribution<double> zeroToOne(0.0, 1.0);
dispatch_apply(1000, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^(size_t i) {
double a = zeroToOne(engine);
});
}
使用 libdispatch。
C++11 标准库基本上是线程安全的。 PRNG 对象上的线程安全保证与容器上的相同。更具体地说,由于 PRNG 类都是pseudo-随机,即它们根据确定的当前状态生成确定性序列,实际上没有空间可以窥视或戳探所包含状态之外的任何内容(用户也可以看到)。
正如容器需要锁才能安全共享一样,您也必须锁定 PRNG 对象。这会使其变得缓慢且不确定。每个线程一个对象会更好。
§17.6.5.9 [数据种族解析]:
1 本节规定了实施应满足的要求
防止数据争用 (1.10)。每个标准库函数应
除非另有说明,否则满足每项要求。实施可能会
防止以下指定情况以外的情况下的数据争用。
2 C++标准库函数不得直接或间接
访问当前线程以外的线程可访问的对象 (1.10)
线程,除非对象是通过直接或间接访问的
函数的参数,包括 this。
3 C++标准库函数不得直接或间接
修改当前线程以外的线程可访问的对象(1.10)
线程,除非对象是通过直接或间接访问的
函数的非常量参数,包括 this。
4 [ 注意:这意味着,例如,实现不能使用
用于内部目的的静态对象无需同步,因为它
即使在未明确共享的程序中也可能导致数据竞争
线程之间的对象。 ——尾注]
5 C++ 标准库函数不得间接访问对象
通过其参数或通过其容器的元素可访问
参数,除非调用其规范所需的函数
在那些容器元素上。
6 对调用标准库获得的迭代器的操作
容器或字符串成员函数可以访问底层
容器,但不得对其进行修改。 [注:特别是容器
使迭代器无效的操作与以下操作冲突
与该容器关联的迭代器。 ——尾注]
7 实现可以在线程之间共享它们自己的内部对象
如果对象对用户不可见并且受到数据保护
比赛。
8 除非另有说明,C++ 标准库函数应
仅在当前线程内执行所有操作,如果
操作具有用户可见的效果 (1.10)。
9 [注意:这允许实现并行化操作,如果
没有明显的副作用。 ——尾注]
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)