Why is rand() not so random after fork?

2020-01-29 18:06发布

#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

标签: c random fork
7条回答
冷血范
2楼-- · 2020-01-29 18:15

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".

查看更多
3楼-- · 2020-01-29 18:21

If your code is running fast enough, srand() might be seeded with the exact same time for each fork. time() only changes every second.

查看更多
SAY GOODBYE
4楼-- · 2020-01-29 18:31

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.)

查看更多
祖国的老花朵
5楼-- · 2020-01-29 18:33

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楼-- · 2020-01-29 18:35

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楼-- · 2020-01-29 18:36

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));
查看更多
登录 后发表回答