random_shuffle线程安全吗?如果不是,则使用rand_r

Is random_shuffle threadsafe? and using rand_r if it is not

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

std::random_shuffle线程安全吗?我认为不是,因为常规的rand()不是线程安全的。如果是这种情况,我将如何使用rand_r和random_shuffle,以便我可以给每个线程一个唯一的种子。我已经看到了使用自定义随机生成器和random_shuffle的例子,但我仍然不清楚。

谢谢。

要使用rand_rstd::random_shuffle,您需要编写一个(相当简单的)包装器。您传递给random_shuffle的随机数生成器需要接受一个指定要生成的数字范围的参数,rand_r不需要。

您的包装器看起来像这样:

class rand_x { 
    unsigned int seed;
public:
    rand_x(int init) : seed(init) {}
    int operator()(int limit) {
        int divisor = RAND_MAX/(limit+1);
        int retval;
        do { 
            retval = rand_r(&seed) / divisor;
        } while (retval > limit);
        return retval;
    }        
};

random_shuffle一起使用,例如:

std::random_shuffle(whatever.begin(), whatever.end(), rand_x(some_seed));

您需要提供一个随机数生成器函数或函数对象,该函数或函数对象接受整型值,并返回另一个整型值,该值不会超出您传递给函数的迭代器正在迭代的容器的边界。同样,对于functor对象,它必须实现operator(),以便它可以像函数一样被调用。因为你需要一个线程安全的随机数生成器,使用srandrandcstdlib是一个坏主意…相反,你应该创建一些函数函数对象来实现线程安全的随机数生成器,或者创建一个不实现全局可访问变量的随机数生成器,以便所有内容都保持线程本地存储。

例如,一种可行的方法是,你从另一个库中获得某种类型的随机数生成器,它只会在固定范围内生成随机值,因此你可以为random_shuffle算法使用的随机访问迭代器定义容器的边界。现在,根据您使用的库,您的函子可能看起来像下面这样:

class my_rand_gen
{
   private:
       random_gen_type random_range_gen;
       int min;
       int max;
   public:
       my_rand_gen(const random_gen_type& gen, int min_range, int max_range):
                     random_range_gen(gen), min(min_range), max(max_range) {}
       int operator()(int value) 
       { 
           //ignore the input value and use our own defined range
           //returns a value between min and max
           return random_range_gen(min, max); 
       }
};

现在你可以这样调用这个算法:

random_shuffle(my_vector_start_iter, my_vector_end_iter, 
               my_rand_gen(rand_generator_lib, 
                           vector_start_index, 
                           vector_end_index));

,它会将开始迭代器和结束迭代器之间的向量洗牌到你的向量,而不会溢出向量的边界…换句话说,它将只使用vector_start_indexvector_end_index之间的洗牌值。

可能不会。

使用第二个版本的adnrom_shuffle,它接受随机数生成器的模板参数:http://www.sgi.com/tech/stl/random_shuffle.html。生成器必须匹配:http://www.sgi.com/tech/stl/RandomNumberGenerator.html

struct MyRandomNumberGenerator
{
    int operator()(int limit) const
    {
         // get threadsafe random number
    }
};
// Stuff
random_shuffle(list.begin(), list.end(), MyRandomNumberGenerator());