Unix 上 fork() 多个进程的问题
所以我有这个函数可以分叉 N 个子进程。然而,它的分叉似乎超出了指定的范围。你能告诉我我做错了什么吗? 谢谢
void forkChildren(int nChildren){
int i;
for(i = 1; i <= nChildren; i++){
pid = fork();
if(pid == 0)
printf("I'm a child: %d PID: %d\n",i, getpid());
}
}
在主要我打电话:
forkChildren(5);
我期待以下输出:
I'm a child: 1 PID: 2990
I'm a child: 2 PID: 2991
I'm a child: 3 PID: 2992
I'm a child: 4 PID: 2993
I'm a child: 5 PID: 2994
但我得到以下结果:
I'm a child: 1 PID: 2990
I'm a child: 2 PID: 2991
I'm a child: 3 PID: 2992
I'm a child: 4 PID: 2993
I'm a child: 5 PID: 2994
user@computer:~/directory/$ I'm a child: 2 PID: 2999
I'm a child: 3 PID: 3000
I'm a child: 3 PID: 3001
I'm a child: 4 PID: 3002
I'm a child: 5 PID: 3003
I'm a child: 5 PID: 3004
I'm a child: 4 PID: 3005
I'm a child: 5 PID: 3006
I'm a child: 4 PID: 3007
I'm a child: 5 PID: 3008
I'm a child: 3 PID: 3011
I'm a child: 4 PID: 3012
I'm a child: 4 PID: 3010
I'm a child: 5 PID: 3013
I'm a child: 5 PID: 3014
I'm a child: 5 PID: 3015
I'm a child: 4 PID: 3018
I'm a child: 5 PID: 3019
I'm a child: 5 PID: 3020
I'm a child: 5 PID: 3021
I'm a child: 5 PID: 3023
I'm a child: 5 PID: 3025
I'm a child: 5 PID: 3024
I'm a child: 4 PID: 3022
I'm a child: 5 PID: 3026
I'm a child: 5 PID: 3027
So I have this function that forks N number of child processes. However it seems to be forking more than specified. Can you tell me what I'm doing wrong?
Thanks
void forkChildren(int nChildren){
int i;
for(i = 1; i <= nChildren; i++){
pid = fork();
if(pid == 0)
printf("I'm a child: %d PID: %d\n",i, getpid());
}
}
In main I call:
forkChildren(5);
I am expecting the following output:
I'm a child: 1 PID: 2990
I'm a child: 2 PID: 2991
I'm a child: 3 PID: 2992
I'm a child: 4 PID: 2993
I'm a child: 5 PID: 2994
But instead I get the following:
I'm a child: 1 PID: 2990
I'm a child: 2 PID: 2991
I'm a child: 3 PID: 2992
I'm a child: 4 PID: 2993
I'm a child: 5 PID: 2994
user@computer:~/directory/$ I'm a child: 2 PID: 2999
I'm a child: 3 PID: 3000
I'm a child: 3 PID: 3001
I'm a child: 4 PID: 3002
I'm a child: 5 PID: 3003
I'm a child: 5 PID: 3004
I'm a child: 4 PID: 3005
I'm a child: 5 PID: 3006
I'm a child: 4 PID: 3007
I'm a child: 5 PID: 3008
I'm a child: 3 PID: 3011
I'm a child: 4 PID: 3012
I'm a child: 4 PID: 3010
I'm a child: 5 PID: 3013
I'm a child: 5 PID: 3014
I'm a child: 5 PID: 3015
I'm a child: 4 PID: 3018
I'm a child: 5 PID: 3019
I'm a child: 5 PID: 3020
I'm a child: 5 PID: 3021
I'm a child: 5 PID: 3023
I'm a child: 5 PID: 3025
I'm a child: 5 PID: 3024
I'm a child: 4 PID: 3022
I'm a child: 5 PID: 3026
I'm a child: 5 PID: 3027
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
fork() 调用会生成一个新进程,该进程在分叉发生的同一点开始执行。因此,看起来 fork “返回两次”
这里发生的情况是,您的 fork() 调用返回两次,因此父进程和子进程都继续循环并生成新进程。然后,每个子进程(原始父进程和子进程)再次分叉,反复将进程数量加倍……
The fork() call spawns a new process which begins its execution at the exact same point where the fork occurred. So, it looks like fork "returns twice"
What's happening here is that your fork() call returns twice, so both the parent and child process continue looping and spawning new processes. Each child (of both the original parent and child) then forks again, repeatedly doubling the number of processes...
当您
fork
一个进程时,您基本上最终会得到该进程的两个(几乎)完全相同的副本,并且它们都将继续运行。因此,发生的情况是,子进程本身在自己的进程空间中继续循环(在打印输出之后), 父进程也这样做。事实上,因为这些孩子也在分叉,所以孙子也将从这一点继续下去。我确信有一个公式可以实际计算出您最终会有多少个孩子(可能像 N!),但我现在没有精力计算出来。最好使用以下解决方案。
区分父级和子级的方法是通过
fork
的返回值。fork
失败。等待
)。这是一些测试代码:
以及一些向您展示发生了什么的输出:
When you
fork
a process, you basically end up with two (almost) exact copies of the process and both of them will continue running.So what's happening is that the children themselves are continuing the loop in the own process space (after they print their output) as well as the parent doing it. And, in fact, because these children are also forking, the grandchildren will also carry on from that point. I'm sure there's a formula for actually figuring out how many children you end up with (probably something like N!) but I don't have the energy to figure it out at the moment. Better to use the following solution.
The way to tell the difference between parent and child is the return value from
fork
.fork
failed.wait
for it).Here's some test code:
and some output to show you what's happening:
每个子进程都会继续循环。
换句话说,子进程 1 被生成并继续循环的迭代 #2 等。
当进程被分叉时,会生成当前进程的副本:生成的子进程在 fork() 调用后继续执行。这就是为什么您必须注意逻辑中的返回代码。
Each child process picks up and continues the loop.
In other words, child 1 is spawned and continues with iteration #2 of loop etc.
When a process is forked, a copy of the current process is made: the resulting child process continues execution after the fork() call. That's why you must take care of the return code in your logic.
在本练习中,我将使用递归而不是 for 循环。这样,您就可以多次调用 fork() 指令,但仅在进程的两个副本之一上调用。您可以使子进程生成另一个子进程,从而拥有祖父母、曾祖父母等,或者您可以在父进程上调用 fork() ,拥有一个“父亲”和多个子进程。这是实现后一种解决方案的代码示例:
In this exercise I'd use recursion rather than a for loop. This way you can have the fork() instruction called multiple times but just on one of the two copies of the process. You can make the child process spawn another child process, thus having grandparents, grand-grandparents etc. or you can call the fork() on the parent side, having a single "father" and multiple children. This is a sample of code which implements the latter solution: