我正在编写一个程序,其中有工作线程创建从0到3或从0到x-1(一个变量)的随机数。
我需要学习的是如何在C中生成这些随机数。
我正在使用gcc编译器,并在Ubuntu 11.10上工作。
我正在编写一个程序,其中有工作线程创建从0到3或从0到x-1(一个变量)的随机数。
我需要学习的是如何在C中生成这些随机数。
我正在使用gcc编译器,并在Ubuntu 11.10上工作。
rand()
和srand()
在这种情况下都不能安全地使用。
它们既不可重入也不线程安全。一般来说,C语言和C++标准对于任何标准库函数的线程安全性都没有任何要求。
某些实现确实可以提供线程安全版本,但这并不是标准要求。
为了能够在多线程环境中使用随机数生成器,您需要使用一个允许传递状态的实现。这样,您可以为每个线程保留一个状态值,生成高质量的随机数而无需进行同步。
C标准库没有提供任何选择。这使得100%的可移植性变得相当困难。您应该在问题中提到您的环境,以获得准确的答案。
请查看GNU Scientific Library,它声称提供多线程随机数生成器。
gsl_rng_alloc
创建)。也就是说,通过拥有多个随机数生成器,每个生成器都有自己的状态,而不是在每次使用生成器时锁定状态来实现线程安全。 - Jamesrand
返回意外的结果,那么问题在哪里? - ugorenrand()
实现也会有一定概率给出完全相同的随机值。但原则上来说你是对的,因为使用正确的 rand()
时这是已知的概率,而在这种情况下不是这样。如果用于密码学,这实际上可能很重要。 - ugoren使用rand_r()
(参见 rand(3))
函数rand_r()需要一个指向无符号整型的指针作为状态参数。
它是可重入的,并且以种子作为输入,因此线程可以独立地管理其种子。
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
void* cb1(void*) {
while(1) {
printf("cb1, rand:%d\n",rand());
sleep(1);
}
}
void* cb2(void*) {
while(1) {
printf("cb2, rand:%d\n",rand());
sleep(1);
}
}
int main() {
pthread_t th1, th2;
srand(1);
pthread_create(&th1, NULL, cb1, NULL);
pthread_create(&th2, NULL, cb2, NULL);
pthread_join(th1, NULL);
pthread_join(th2, NULL);
return 0;
}
真实而美丽的事物;
http://en.wikipedia.org/wiki/Mersenne_twister
编写自己的随机数生成器。
(抱歉。我刚刚看了一下那个维基页面。我上次看的时候还好,你可以阅读它并实现扭曲器。现在它是一堆学位级别的数学,对任何人都没有解释,除了那些花了四年时间在大学学习数学的人群。我在维基上经常看到这种情况 :-(
threads.h
,看起来像这样:mtx_t rand_mtx;
//run only once.
int rand_init(int seed)
{
srand(seed);
mtx_init(&rand_mtx, mtx_plain);
}
int synced_rand()
{
mtx_lock(&rand_mtx);
int r = rand();
mtx_unlock(&rand_mtx);
return r;
}