我有一个看起来像这样的C文件:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main ()
{
pid_t child_pid;
printf ("The PID is %d\n", (int) getpid ());
child_pid = fork ();
if (child_pid != 0)
{
printf ("this is the parent process, with PID %d\n",
(int)getpid());
printf ("the child's PID is %d\n", (int) child_pid);
}
else
printf ("this is the child process, with PID %d\n",
(int)getpid());
return 0;
}
我需要修改它以产生一个看起来像
的层次结构parent (0)
|
+---> child (1)
|
+---> child (2)
|
+----> child (3)
|
+----> child (4)
|
+----> child (5)
|
基本上是一个树形结构,每个第二个孩子生两个新孩子。据我了解,当我fork()
进程时,每个进程将同时运行。在fork()
语句中添加if
似乎可以正常工作并正确创建进程0到2,因为只有父进程才会创建新的分支。但我不知道如何制作进程2 fork而不是1.任何想法?
答案 0 :(得分:2)
嗯,第一个分叉将创建进程1。进程2将由if语句中的fork创建。因此,为了让进程2 fork也是如此,如果第二个fork没有返回0,则在if语句中再次进行fork。
插图:
if(fork) {
// Inside process 0
if(fork) {
// still in process 0
} else {
// in process 2
if(fork) {
// still in process 2
} else {
// in prcess 3
}
// and so on
}
} else {
// Inside process 1
}
答案 1 :(得分:2)
儿童在分叉时获得父母的州的副本。
因此,如果父母有一个计数器或其他属性,那么孩子们将在分叉时看到该值(但如果父母随后改变它,则不会)。
答案 2 :(得分:2)
我不知道你为什么要这样做,但通常只有父进程执行fork。这也可能更容易设计。当你在for循环中执行fork()时,你可以直接控制所创建的进程。
请注意,fork()是一项相对昂贵的操作,特别是如果您想创建许多进程。可以使用更轻量级的替代品vfork和螺纹,但我无法判断它们是否也符合您的需求。
答案 3 :(得分:1)
一个老问题,但仍然是一个有趣的问题。 fork()
的{{3}}告诉我们返回值:
成功时,子进程的PID在父进程中返回,并在子进程中返回0。失败时,在父项中返回-1,不创建子进程,并正确设置errno。
所以我们知道fork()
向孩子返回0,我们可以用它作为控制机制:
int main()
{
// Here we're in the parent (0) process
if(fork()) // This starts the chain, only the parent will do this
if(!fork()) //the child will pass this, the parent will skip it
for(count = 0; counter < number_of_processes; counter++) //now the 2nd child loops
{
if(fork())
if(!fork());
else
break;
}
让我们给它一些数字:
//parent (18402)
if(fork()) // spawns 18403, parent 18402 keeps going
if(!fork()) // spawns 18404, parent 18402 drops to the end of main()
for(count = 0; count < number_of_processes; conter++) // 18404 enters here
if(fork()) // 18404 forks 18405 and then goes on
if(!fork()); // 18404 spawns 18406 before leaving, 18406 restarts the loop
else
break; // 18404 breaks out there
else
break; //18405 leaves the loop here
所以经过一次迭代我们得到了:
18402
|
+---> 18403
|
+---> 18404
|
+----> 18405
|
+----> 18406
|
在此之后,我们将继续循环两个新进程,其中第二个进程将继续迭代,直到您按需要进行多次传递。