1

在 C++11 中,算法std::random_shuffle线程是否安全(当由两个不同容器上的两个不同线程调用时)?

特别是这种形式:

template <class RandomIt> void random_shuffle(RandomIt first, RandomIt last);
4

2 回答 2

6

如果该函数的两个并发执行不在同一数据上“工作”,则该函数是线程安全的。这里的“工作”意味着没有一个函数可以以非原子、不一致的方式修改数据。函数可以通过三种方式访问​​数据:

  1. 通过函数参数,包括这些参数引用的对象
  2. 通过对象调用成员函数
  3. 函数静态、类静态和全局数据,包括间接调用的函数使用的数据。

由于random_shuffle是免费功能,2.不适用。然而,该函数具有参数,并且它在改变底层序列内容的意义上对它们起作用。但是如果并发调用不对重叠序列进行操作,则不会有问题。

这留下了静态/全局数据。大多数随机数生成器将使用某种全局数据作为其种子。默认随机函数rand不需要是线程安全的,并且可能不会显式同步对其全局种子的访问。

所以在你的情况下,它不是线程安全的(除非随机数生成器是)。

您将需要编写随机数生成器的同步版本,或者在并发调用中使用不同的生成器。我更喜欢使用后者,所以并发洗牌不会干扰彼此的随机数序列。(但我绝不是随机数生成专家)。

于 2013-07-18T10:34:22.323 回答
3

如果它使用线程安全的随机数生成器,它就是线程安全的。生成器是实现定义的(如果它使用std::rand,它是否安全也是实现定义的),因此您需要查阅您正在使用的实现的文档。

可以肯定的是,您应该使用其他变体之一,为每个线程提供线程安全生成器或单独的生成器。

于 2013-07-18T10:27:22.367 回答