简体   繁体   English

如何使用rand_r()在C中创建线程安全随机数生成器?

[英]How to create thread-safe random number generator in C using rand_r()?

I was asked to not use rand() because they were not "thread safe" and to also use a different seed value each time. 我被要求不要使用rand()因为它们不是“线程安全的”,并且每次也使用不同的种子值。 I found examples on GitHub using a seed value like this: 我在GitHub上找到了使用像这样的种子值的示例:

unsigned int seed = time(NULL);

That only has a precision by seconds. 那只有几秒钟的精度。 Since the program runs in under 1 second, I end up getting the same random number every instance. 由于程序运行时间不到1秒,因此我最终在每个实例中获得了相同的随机数。

How would I fix this algorithm so that it only uses rand_r() or any other "thread safe" methods to generate 10 random numbers? 如何解决此算法,使其仅使用rand_r()或任何其他“线程安全”的方法来生成10个随机数?

int main()
{
    for(int i = 0; i < 10; i++){
        int random;
        unsigned int seed = time(NULL);
            random = 1 + (rand_r(&seed)% 10);
        printf("%d\n",random);
    }
 return 0;
}

The rand_r function takes a pointer to a state variable. rand_r函数采用一个指向状态变量的指针。 This is set to a seed value before rand_r is called for the first time. 在第一次调用rand_r之前,将其设置为种子值。 Then each time you call rand_r , you pass in address of this value. 然后,每次调用rand_r ,您都传递此值的地址。

To be thread safe, each thread needs to have its own state variable. 为了线程安全,每个线程都需要有自己的状态变量。 You don't however want to use the same initial value for each thread's state variable, otherwise every thread will generate the same sequence of pseudo-random values. 但是,您不想为每个线程的状态变量使用相同的初始值,否则每个线程将生成相同的伪随机值序列。

You need to seed the state variable with data that differs for each thread, such as the thread id, plus other information such as the time and/or pid. 您需要为状态变量添加每个线程不同的数据(例如线程ID)以及其他信息(例如时间和/或pid)。

For example: 例如:

// 2 threads, 1 state variable each
unsigned int state[2];

void *mythread(void *p_mystate)
{
    unsigned int *mystate = p_mystate;
    // XOR multiple values together to get a semi-unique seed
    *mystate = time(NULL) ^ getpid() ^ pthread_self();

    ...
    int rand1 = rand_r(mystate);
    ...
    int rand2 = rand_r(mystate);
    ...
    return NULL;
}

int main()
{
    pthread_t t1, t2;

    // give each thread the address of its state variable
    pthread_create(&t1, NULL, mythread, &state[0]);
    pthread_create(&t2, NULL, mythread, &state[1]);
    ...
    pthread_join(t1, NULL);
    pthread_join(t2, NULL);
    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM