我是多线程编程的初学者。我有一个家庭作业,我应该创建一些线程(在我的例子中是10),并在每个线程中生成一个随机数。当我调试代码(或放入"sleep(1)"命令)时,它工作正常,否则生成的值不再相等。如果你认为我还有什么不明白的地方,请帮我解释一下。代码:
#include<stdio.h>
#include<pthread.h>
#include<time.h>
int rn, sharedArray[10];
pthread_mutex_t lock;
int randomgenerator(){
//sleep(1);
srand(time(NULL)); // The value of random depend on the time with some changes in the time library
int rn, MAX = 10; // between 0 and 10
rn = rand()%MAX;
return rn;
}
void *rgen(void *arg){
int order = (int*)arg;
//pthread_mutex_lock(&lock);
int rn = randomgenerator();
printf("%d,%dn", order,rn); //not working without printf why????
sharedArray[order]= rn;
//pthread_mutex_unlock(&lock);
pthread_exit(NULL);
}
void main(int argc, char *argv[]){
pthread_mutex_init(&lock, NULL);
pthread_t th[10];
int i;
for (i = 0; i <10; i ++){
pthread_create(&(th[i]), 0, rgen, (void *)i);
pthread_join(th[i], NULL);
}
int j, result = 0;
for (j=0; j<10; j++){
result = sharedArray[j] + result;
}
printf("the final result is: %dn",result);
pthread_exit(NULL);
pthread_mutex_destroy(&lock);
}
输出为:
0,3
1,3
2,3
3,3
4,3
5,3
6,3
7,3
8,3
9,3
the final result is: 30
我期望通过取消睡眠的注释得到的输出是:
0,7
1,4
2,1
3,8
4,5
5,2
6,9
7,6
8,3
9,0
the final result is: 45
问题是这一行:
srand(time(NULL));
兰德的手册页上写着:
srand()函数将其参数设置为rand()返回的新伪随机整数序列的种子。通过调用具有相同种子值的srand(),这些序列是可重复的。
你每次都会播种一粒新种子。这是错误的!你应该只给srand打一次电话。
当您注释掉睡眠时,所有线程都设置了相同的种子,然后获得该序列中的第一个随机数。如果他们在同一秒内完成,他们每个人都会得到相同的随机值。
解决方案:
在创建任何线程之前,将对srand
的调用移动到main
。
注意:
函数rand()不是可重入的,也不是线程安全的,因为它使用的是每次调用都会修改的隐藏状态。
这意味着您不能安全地从多个线程同时调用rand
。您应该使用互斥或信号量来保护调用,或者切换到可重入函数,如rand_r。