分叉流程同时打印

时间:2018-03-19 19:28:37

标签: c time fork

在下面的代码中,我不明白为什么分叉进程(其中十个)打印的时间相同。据我了解,每个进程应等待一段随机时间(最多15秒),然后打印截止时间。有人可以解释为什么他们同时打印?

int main() {
    int x, i;

    for (i = 0; i < 9; i++) {   
        x = fork();
        if (x == 0) {
            sleep(rand() % 15);
            printf("%d ended: %ld\n", i, time(NULL));
            exit(0);
        }
    }

    while (wait(NULL) != -1);

    exit(0);
}

2 个答案:

答案 0 :(得分:3)

所有进程使用相同的种子值来使用rand()生成随机数。

rand()的手册页:

  

如果未提供种子值,则rand()函数将自动播种,值为1.

因此,rand()会生成相同的数字序列,因为它们都是以相同的值播种的,C11,7.22.2.2表示:

  

srand函数使用该参数作为后续调用rand返回的新伪随机数序列的种子。如果随后使用相同的种子值调用srand,则应重复伪随机数序列。如果在对srand进行任何调用之前调用rand,则应该生成相同的序列,就像第一次使用种子值1调用srand时一样。

您需要在不同的进程中设置不同的种子值(通过调用srand())。例如,您可以在子进程中使用getpid()来播种:

  if (x == 0) {
        srand((unsigned int)getpid());
        sleep(rand() % 15);
        ...

答案 1 :(得分:1)

正如评论中提到的,所有进程都在同时打印,因为它们都为rand返回了相同的值。

每次调用rand函数时,它都会对返回的前一个值执行一些计算,以获取下一个值。在第一次调用此函数之前,需要使用起始值进行播种。因此,给定一个特定的种子值,rand将始终返回相同的值序列。

种子值设置为srand,但如果您不这样做,则第一次调用rand会有效地调用srand(1)。因此,在您的情况下,每个进程第一次调用rand,隐式种子为1.因此,每个进程返回相同的值。

您可以通过在父进程中生成随机休眠时间来解决此问题。这样,子进程使用的每个值都将不同。此外,虽然这不是问题的原因,但您还应明确调用srand

int main() {
    int x, i;

    srand(time(NULL) ^ getpid());
    for (i = 0; i < 9; i++) {
        int sleep_time = rand() % 15;  // generate random number in parent
        x = fork();
        if (x == 0) {
            sleep(sleep_time);
            printf("%d ended: %ld\n", i, time(NULL));
            exit(0);
        }
    }

    while (wait(NULL) != -1);

    exit(0);
}