请看完整问题
我知道srand()
应该只调用一次,但我的第二个代码段显示这并不能解决问题!!!
我编写的程序给我输出,我无法理解为什么会这样。不同的代码段变化会产生不同的输出。
代码目标:
该代码使用omp
简单地运行一个3个线程的代码片段。每个线程都必须使用rand()
函数打印3个随机值。因此,总共会有9个输出。线程0
是主线程/主程序的运行流程。线程1
和线程2
是在代码开始时为线程创建的新线程。
代码:
#include<omp.h>
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main()
{
#pragma omp parallel num_threads(3)
{
srand(time(NULL));
int i=0;
for(i=0;i<3;i++)
{
printf("\nRandom number: %d by thread %d", rand(), omp_get_thread_num());
}
}
return 0;
}
输出结果:
Random number: 17105 by thread 0
Random number: 30076 by thread 0
Random number: 21481 by thread 0
Random number: 17105 by thread 1
Random number: 30076 by thread 1
Random number: 21481 by thread 1
Random number: 17105 by thread 2
Random number: 30076 by thread 2
Random number: 21481 by thread 2
但如果我把srand(time(NULL))
放在线程代码之前,像这样:
srand(time(NULL));
#pragma omp parallel num_threads(3)
{
int i=0;
......
......(rest is same)
输出结果为:输出结果:
Random number: 16582 by thread 0
Random number: 14267 by thread 0
Random number: 14030 by thread 0
Random number: 41 by thread 1
Random number: 18467 by thread 1
Random number: 6334 by thread 1
Random number: 41 by thread 2
Random number: 18467 by thread 2
Random number: 6334 by thread 2
问题和我的疑惑:
将`srand`放在外面后,所有线程的第一次调用`rand()`都会得到相同的随机数,它们的第二次调用也会得到相同的随机数,对于第三次调用也是如此。
将`srand`放在内部后,主线程的调用结果与其他线程不同。但是,其中的两个新线程在它们各自调用`rand()`时得到了相同的随机数。
那么,
这里实际上正在发生什么?为什么仅对主线程(线程0)放置`srand()`函数会有影响?
为什么无论哪种方式,其他2个新线程总是输出相同的随机数?
`srand()`和`rand()`是如何关联起来导致这种异常?
我尝试给每个线程提供等待间隔,以消除`rand()`函数被不同线程同时调用可能导致相同的随机数的可能性,但问题与之前完全相同。输出没有变化(只是输出发生的时间不同)。
请帮助我理解整个过程。
srand()
移到代码块外部。程序启动时只应调用一次。 - Iharob Al Asimirand()
不是线程安全的,并提供了一种替代方案。 - Ulrich Eckhardtrand()
不是线程安全的,需要使用rand_r()
,但这是UNIX特定的。 - powersource97