可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
#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);
}
Prints the same (different on each run) number 10 times - expected ?
I have a more complicated piece of code where each forked process runs in turn - no difference
回答1:
The outputs must be the same. If two processes each seed the random number with the same seed and each call rand
once, they must get the same result. That's the whole point of having a seed. All of your processes call srand
with the same seed (because you only call srand
once) and they all call rand
once, so they must get the same result.
Uncommenting the srand
won't make a difference because unless the number of seconds has changed, they will still give the same seed. You could do:
srand(time(NULL) ^ (getpid()<<16));
回答2:
The rand()
function is a pseudo-random number generator. This means that the sequence of numbers generated is deterministic, depending only upon the seed provided.
Because you are forking the same process 10 times, the state of the random number generator is the same for each child. The next time you call rand()
you will get the same value.
By calling srand(time(NULL))
inside the child process, you are potentially helping but the granularity of time()
is only 1 second, so all your children probably start inside the same second. Seeding with the same value generates the same pseudo-random sequence.
You could try seeding with a value that depends on the child number:
srand(time(NULL) - i*2);
(I used i*2
in the event that time()
advances by 1 second during the fork loop.)
回答3:
If your code is running fast enough, srand()
might be seeded with the exact same time for each fork. time()
only changes every second.
回答4:
The reason that even adding srand(time(NULL));
(the line inside the if
block that you have commented) inside the loop isn't making a difference is because modern computers can execute that whole block extremely fast, and time
counts in seconds. From the man pages:
time() returns the time as the number of seconds since the Epoch...
If you add a sleep(1);
after the if
statement in the while
loop and uncomment the srand
call, the results will be different, since time
would now return a different value because a second has elapsed.
It would however be more appropriate to use a different seed value, rather than waiting. Something like i
would be a good idea since it'll be unique for each iteration of the loop.
回答5:
You're not reseeding when you make a child process. The state of the random number generator is exactly the same.
Even if you seed again in your child, you're seeding with the time with a +/- 1 second granularity. When you fork, it all happens in less than a second.
Try seeding it with something different and more random.
回答6:
The reason for this is because all programs are seeded with the same value (outside that while loop). You should seed again once you've forked the new program or both will produce the same sequence.
回答7:
This solve the problem:
srand48((long int)time(NULL));
i= (lrand48()/rand()+1) % 123
I havent tested with fork, but inside a for calling 100 times it works.
seed with the pid number. It's a little but difficult to solve problem.
This was in some page: "this worked srand(time(0)+getpid()); but I had to call this within the case 0 i.e child process".