在C++ 11中,算法是std::random_shuffle线程安全(当由两个不同容器上的两个不同线程调用时)?std :: random_shuffle线程安全吗?
,特别是这种形式:
template <class RandomIt> void random_shuffle(RandomIt first, RandomIt last);
在C++ 11中,算法是std::random_shuffle线程安全(当由两个不同容器上的两个不同线程调用时)?std :: random_shuffle线程安全吗?
,特别是这种形式:
template <class RandomIt> void random_shuffle(RandomIt first, RandomIt last);
函数是线程安全的,如果该函数的两个并发执行不在相同数据上“工作”。这里的“工作”意味着没有任何功能可以以非原子,不一致的方式修改数据。有三种方法如何数据可以由功能进行访问:
由于random_shuffle
是一项免费功能,因此2.
不适用。然而,该函数具有参数,并且它对它们起作用,因为它会改变底层序列的内容。但是,如果并发呼叫不对重叠序列进行操作,则不会出现问题。
这留下了静态/全局数据。大多数随机数发生器将为其种子使用某种全局数据。默认的随机函数rand
不需要是线程安全的,并且可能不会显式同步对其全局种子的访问。
所以在你的情况下不,它不是线程安全(除非随机数发生器是)。
你会想要写一个同步版本的随机数发生器,并使用不同的发生器并发调用。我宁愿使用后者,所以并发洗牌不会干扰彼此的随机数字序列。 (但我绝不是随机数字生成专家)。
'rqnd'不是**必须**是线程安全的。这与说**不是**线程安全不一样。任何特定的实现**都可以使它成为线程安全的,它的文档应该告诉你这一点。 –
@PeteBecker *不要求*表示在标准C++中不是线程安全的。如果一个具体的实施提供了比标准要求更多的保证,那就是对标准的扩展。答案是针对一般性的语言问题,而不是针对具体的实施。添加“对特定编译器来说可能更好”是没有必要的,因为它几乎适用于语言的每个角落,因为标准明确允许扩展。但是我会改变有关'rand'的措辞:-) –
它是线程安全的,如果它使用一个线程安全的随机数发生器。生成器是实现定义的(如果它使用std::rand
,它是否是实现定义的,无论这是否安全),因此您需要查阅所用实现的文档。可以肯定的是,您应该使用其他变体之一,为每个线程提供线程安全的生成器或单独的生成器。
最有可能不是:'std :: random_shuffle'的重载可能会调用'std :: rand()',它可能使用了一些全局资源。 – juanchopanza