在下面的代码中,我不明白为什么分叉进程(其中十个)打印的时间相同。据我了解,每个进程应等待一段随机时间(最多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);
}
答案 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);
}