我写了这个小程序来帮助我更好地理解过程:
#include <stdio.h>
#include <unistd.h>
int main()
{
int pid;
int i;
if ((pid = fork()) == 0)
{
for (i = 0; i < 100; i++)
{
printf("child, pid = %d, i = %d\n", getpid(), i);
}
}
else if (pid > 0)
{
for (i = 0; i > -100; i--)
{
printf("parent, pid = %d, i = %d\n", getpid(), i);
}
}
else
{
perror("failed fork!\n");
exit(1);
}
return 0;
}
当我实际运行程序时,我很惊讶地看到输出。 父进程首先启动,也可能反过来发生,对吧?在我的机器中,它似乎总是选择父母。 但让我感到惊讶的是,曾经开始的过程无法完成输出所有i值。为什么是这样?进程的时间是否小? 然后更奇怪的是,父母和孩子开始轮流使用printfs,每次输出只有一行,直到父完成循环,因为它有一个headstart然后孩子打印剩下的i值。 如何解释这种行为?
这是我得到的输出:
parent, pid = 3246, i = 0
parent, pid = 3246, i = -1
parent, pid = 3246, i = -2
parent, pid = 3246, i = -3
parent, pid = 3246, i = -4
parent, pid = 3246, i = -5
parent, pid = 3246, i = -6
parent, pid = 3246, i = -7
parent, pid = 3246, i = -8
parent, pid = 3246, i = -9
parent, pid = 3246, i = -10
parent, pid = 3246, i = -11
parent, pid = 3246, i = -12
parent, pid = 3246, i = -13
parent, pid = 3246, i = -14
parent, pid = 3246, i = -15
parent, pid = 3246, i = -16
parent, pid = 3246, i = -17
parent, pid = 3246, i = -18
parent, pid = 3246, i = -19
parent, pid = 3246, i = -20
parent, pid = 3246, i = -21
parent, pid = 3246, i = -22
parent, pid = 3246, i = -23
parent, pid = 3246, i = -24
parent, pid = 3246, i = -25
parent, pid = 3246, i = -26
parent, pid = 3246, i = -27
parent, pid = 3246, i = -28
parent, pid = 3246, i = -29
parent, pid = 3246, i = -30
parent, pid = 3246, i = -31
parent, pid = 3246, i = -32
parent, pid = 3246, i = -33
parent, pid = 3246, i = -34
parent, pid = 3246, i = -35
parent, pid = 3246, i = -36
parent, pid = 3246, i = -37
parent, pid = 3246, i = -38
parent, pid = 3246, i = -39
parent, pid = 3246, i = -40
parent, pid = 3246, i = -41
parent, pid = 3246, i = -42
parent, pid = 3246, i = -43
parent, pid = 3246, i = -44
parent, pid = 3246, i = -45
parent, pid = 3246, i = -46
parent, pid = 3246, i = -47
parent, pid = 3246, i = -48
parent, pid = 3246, i = -49
parent, pid = 3246, i = -50
child, pid = 3247, i = 0
parent, pid = 3246, i = -51
parent, pid = 3246, i = -52
child, pid = 3247, i = 1
parent, pid = 3246, i = -53
child, pid = 3247, i = 2
parent, pid = 3246, i = -54
child, pid = 3247, i = 3
parent, pid = 3246, i = -55
child, pid = 3247, i = 4
parent, pid = 3246, i = -56
child, pid = 3247, i = 5
parent, pid = 3246, i = -57
child, pid = 3247, i = 6
parent, pid = 3246, i = -58
child, pid = 3247, i = 7
parent, pid = 3246, i = -59
child, pid = 3247, i = 8
parent, pid = 3246, i = -60
child, pid = 3247, i = 9
parent, pid = 3246, i = -61
child, pid = 3247, i = 10
parent, pid = 3246, i = -62
child, pid = 3247, i = 11
parent, pid = 3246, i = -63
child, pid = 3247, i = 12
parent, pid = 3246, i = -64
child, pid = 3247, i = 13
parent, pid = 3246, i = -65
child, pid = 3247, i = 14
parent, pid = 3246, i = -66
child, pid = 3247, i = 15
parent, pid = 3246, i = -67
child, pid = 3247, i = 16
parent, pid = 3246, i = -68
child, pid = 3247, i = 17
parent, pid = 3246, i = -69
child, pid = 3247, i = 18
parent, pid = 3246, i = -70
child, pid = 3247, i = 19
parent, pid = 3246, i = -71
child, pid = 3247, i = 20
parent, pid = 3246, i = -72
child, pid = 3247, i = 21
parent, pid = 3246, i = -73
child, pid = 3247, i = 22
parent, pid = 3246, i = -74
child, pid = 3247, i = 23
parent, pid = 3246, i = -75
child, pid = 3247, i = 24
parent, pid = 3246, i = -76
child, pid = 3247, i = 25
parent, pid = 3246, i = -77
child, pid = 3247, i = 26
parent, pid = 3246, i = -78
child, pid = 3247, i = 27
parent, pid = 3246, i = -79
child, pid = 3247, i = 28
parent, pid = 3246, i = -80
child, pid = 3247, i = 29
parent, pid = 3246, i = -81
child, pid = 3247, i = 30
parent, pid = 3246, i = -82
child, pid = 3247, i = 31
parent, pid = 3246, i = -83
child, pid = 3247, i = 32
parent, pid = 3246, i = -84
child, pid = 3247, i = 33
parent, pid = 3246, i = -85
child, pid = 3247, i = 34
parent, pid = 3246, i = -86
child, pid = 3247, i = 35
parent, pid = 3246, i = -87
child, pid = 3247, i = 36
parent, pid = 3246, i = -88
child, pid = 3247, i = 37
parent, pid = 3246, i = -89
child, pid = 3247, i = 38
parent, pid = 3246, i = -90
child, pid = 3247, i = 39
parent, pid = 3246, i = -91
child, pid = 3247, i = 40
parent, pid = 3246, i = -92
child, pid = 3247, i = 41
parent, pid = 3246, i = -93
child, pid = 3247, i = 42
parent, pid = 3246, i = -94
child, pid = 3247, i = 43
parent, pid = 3246, i = -95
child, pid = 3247, i = 44
parent, pid = 3246, i = -96
child, pid = 3247, i = 45
parent, pid = 3246, i = -97
child, pid = 3247, i = 46
parent, pid = 3246, i = -98
child, pid = 3247, i = 47
parent, pid = 3246, i = -99
child, pid = 3247, i = 48
child, pid = 3247, i = 49
child, pid = 3247, i = 50
child, pid = 3247, i = 51
child, pid = 3247, i = 52
child, pid = 3247, i = 53
child, pid = 3247, i = 54
child, pid = 3247, i = 55
child, pid = 3247, i = 56
child, pid = 3247, i = 57
child, pid = 3247, i = 58
child, pid = 3247, i = 59
child, pid = 3247, i = 60
child, pid = 3247, i = 61
child, pid = 3247, i = 62
child, pid = 3247, i = 63
child, pid = 3247, i = 64
child, pid = 3247, i = 65
child, pid = 3247, i = 66
child, pid = 3247, i = 67
child, pid = 3247, i = 68
child, pid = 3247, i = 69
child, pid = 3247, i = 70
child, pid = 3247, i = 71
child, pid = 3247, i = 72
child, pid = 3247, i = 73
child, pid = 3247, i = 74
child, pid = 3247, i = 75
child, pid = 3247, i = 76
child, pid = 3247, i = 77
child, pid = 3247, i = 78
child, pid = 3247, i = 79
child, pid = 3247, i = 80
child, pid = 3247, i = 81
child, pid = 3247, i = 82
child, pid = 3247, i = 83
child, pid = 3247, i = 84
child, pid = 3247, i = 85
child, pid = 3247, i = 86
child, pid = 3247, i = 87
child, pid = 3247, i = 88
child, pid = 3247, i = 89
child, pid = 3247, i = 90
child, pid = 3247, i = 91
child, pid = 3247, i = 92
child, pid = 3247, i = 93
child, pid = 3247, i = 94
child, pid = 3247, i = 95
child, pid = 3247, i = 96
child, pid = 3247, i = 97
child, pid = 3247, i = 98
child, pid = 3247, i = 99
答案 0 :(得分:0)
父进程首先启动。
这里的要点是你正在运行多个进程,并行运行&#34;&#34;。现在,在现实生活中,他们可能会或可能不会并行运行。在只有一个核心的旧处理器中,并行执行意味着操作系统在可运行进程周围快速循环,并从它们中的每一个运行一点。这样的&#34; bit&#34;被称为时间片,通常约为10ms。
现在有了多核cpu的时代,你可能会看到事情并行运行。
所以你可以看到:
进程之间的实际调度(使用一个或多个核心,何时在进程之间切换)取决于您正在使用的操作系统。
答案 1 :(得分:0)
您应该注意到,您的进程执行了数十万条指令代码,其中大部分都是在锁内部,这些代码保护stdout流不被多个线程访问。您实际输入并在问题中显示的代码几乎没有。
进程的行为是99.9999%由stdout上的锁定进行竞争管理,因此父母和孩子开始轮流使用#39; - 完全可以预期,因为他们围绕着锁定。