std::random_shuffle线程安全吗

Is std::random_shuffle thread safe?

本文关键字:安全 线程 random std shuffle      更新时间:2023-10-16

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

尤其是这种形式:

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

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

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

由于random_shuffle是一个自由函数,因此2.不适用。然而,函数有参数,它在改变底层序列内容的意义上处理这些参数。但是,如果并发调用不在重叠序列上操作,就不会有问题。

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

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

您可能想要编写一个同步版本的随机数生成器,或者在并发调用中使用不同的生成器。我更喜欢使用后者,这样并发的洗牌就不会干扰彼此的随机数序列。(但我绝不是随机数生成方面的专家)。

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

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