#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
int i =10;
/* initialize random seed: */
srand(time(NULL));
while(i--){
if(fork()==0){
/* initialize random seed here does not make a difference:
srand(time(NULL));
*/
printf("%d : %d\n",i,rand());
return;
}
}
return (EXIT_SUCCESS);
}
打印相同(每次运行时不同)数量10次 - 预计? 我有一个更复杂的代码片段,每个分叉的进程依次运行 - 没有区别
答案 0 :(得分:18)
输出必须相同。如果两个进程每个都使用相同的种子播种随机数,并且每次调用rand
一次,则必须获得相同的结果。这就是拥有种子的重点。您的所有流程都使用相同的种子调用srand
(因为您只调用srand
一次)并且他们都会调用rand
一次,因此他们必须获得相同的内容结果
取消注释srand
不会产生任何影响,因为除非秒数已经改变,否则它们仍将提供相同的种子。你可以这样做:
srand(time(NULL) ^ (getpid()<<16));
答案 1 :(得分:5)
rand()
函数是伪随机数字生成器。这意味着生成的数字的序列是确定性的,仅取决于提供的种子。
因为您要将同一个进程分叉10次,所以随机数生成器的状态对于每个子进程都是相同的。下次拨打rand()
时,您将获得相同的值。
通过在子进程中调用srand(time(NULL))
,您可能帮助,但time()
的粒度只有1秒,所以您的所有孩子可能都在同一秒内开始。使用相同值进行播种会生成相同的伪随机序列。
您可以尝试使用取决于子编号的值播种:
srand(time(NULL) - i*2);
(如果i*2
在fork循环期间前进1秒,我使用time()
。)
答案 2 :(得分:5)
如果您的代码运行得足够快,srand()
可能会为每个分叉播种完全相同的时间。 time()
只会每秒更改一次。
答案 3 :(得分:2)
甚至在循环中添加srand(time(NULL));
(你已注释的if
块内的行)没有区别的原因是因为现代计算机可以非常快地执行整个块,并且time
以秒计。从手册页:
time()返回自Epoch ...以来的秒数...
如果您在sleep(1);
循环中的if
语句后添加while
并取消注释srand
来电,则结果会有所不同,因为time
现在会返回一个不同的值,因为已经过了一秒钟。
然而,使用不同的种子值而不是等待更合适。像i
这样的东西是个好主意,因为它对于循环的每次迭代都是唯一的。
答案 4 :(得分:0)
之所以这样,是因为所有程序都以相同的值播种(在while循环之外)。一旦你分叉了新程序,你就应该再次播种,否则两者都会生成相同的序列。
答案 5 :(得分:0)
进行子进程时,您不会重新播种。随机数生成器的状态完全相同。
即使您再次在您的孩子中播种,您也会以+/- 1秒的粒度播种。当你分叉时,一切都发生在不到一秒钟。
尝试用不同且更随机的东西播种。
答案 6 :(得分:0)
这解决了问题:
srand48((long int)time(NULL));
i= (lrand48()/rand()+1) % 123
我没有使用fork进行测试,但在调用100次之内它可以工作。
带有pid编号的种子。它有点但很难解决问题。
这是在某些页面中:&#34;这是srand(time(0)+ getpid());但我不得不在案例0中称之为,即子过程&#34;。