如何使用 Fork() 只创建 2 个子进程?
Posted
技术标签:
【中文标题】如何使用 Fork() 只创建 2 个子进程?【英文标题】:How to use Fork() to create only 2 child processes? 【发布时间】:2012-06-10 03:52:44 【问题描述】:我开始学习一些 C 语言,在学习 fork、wait 函数时,我得到了一个意想不到的输出。至少对我来说。
有没有办法从父进程中只创建 2 个子进程?
这是我的代码:
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main ()
/* Create the pipe */
int fd [2];
pipe(fd);
pid_t pid;
pid_t pidb;
pid = fork ();
pidb = fork ();
if (pid < 0)
printf ("Fork Failed\n");
return -1;
else if (pid == 0)
//printf("I'm the child\n");
else
//printf("I'm the parent\n");
printf("I'm pid %d\n",getpid());
return 0;
这是我的输出:
I'm pid 6763
I'm pid 6765
I'm pid 6764
I'm pid 6766
请忽略管道部分,我还没有走到那一步。我只是试图只创建 2 个子进程,所以我希望 3 个“我是 pid ...”为我将等待的父进程和 2 个将通过管道通信的子进程输出只有 1 个。
如果您发现我的错误在哪里,请告诉我。
【问题讨论】:
fork (2)
既非常简单,也是 unix API 中最容易被误解的调用之一。只需查看“相关”侧边栏。您是否希望在两个孩子之间而不是在父母和孩子之间进行交流?
对于 fork() 调用,为什么要检查 pid == 0?我怎么知道哪个是父母,哪个是孩子?
@TwilightSparkleTheGeek man fork
状态:返回值成功时,子进程的 PID 在父进程中返回,在子进程中返回 0。失败时,在父进程中返回-1,不创建子进程,并适当设置errno。
发布的代码正在从父级和子级调用第二个fork()
,之后(假设对fork()
的调用都没有失败)将有4 个进程。 IE。 parent, child1 从第一次调用 fork() 然后 parent, child1, child2, child1a 从第二次调用 fork()
【参考方案1】:
创建流程后,您应该检查返回值。如果不这样做,则第二个fork()
将由父进程和子进程执行,因此您有四个进程。
如果你想创建 2 个子进程,只需:
if (pid = fork())
if (pid = fork())
;
你可以像这样创建 n 个子进程:
for (i = 0; i < n; ++i)
pid = fork();
if (pid > 0) /* I am the parent, create more children */
continue;
else if (pid == 0) /* I am a child, get to work */
break;
else
printf("fork error\n");
exit(1);
【讨论】:
【参考方案2】:您可以在子进程中创建子进程。这样您就可以拥有原始父进程的 2 个副本。
int main (void)
pid_t pid, pid2;
int status;
pid = fork();
if (pid == 0) //child process
pid2 = fork();
int status2;
if (pid2 == 0) //child of child process
printf("friends!\n");
else
printf("my ");
fflush(stdout);
wait(&status2);
else //parent process
printf("Hello ");
fflush(stdout);
wait(&status);
return 0;
这将打印以下内容:
Hello my friends!
【讨论】:
【参考方案3】:您可以将值检查为 如果 ( pid
【讨论】:
【参考方案4】:当父进程执行一个 fork 语句时,一个子进程就会如您所愿创建。您可以说子进程也执行 fork 语句但返回 0,而父进程返回 pid。 fork 语句之后的所有代码都由父和子两者执行。
在您的情况下,发生的事情是第一个 fork 语句创建了一个子进程。所以现在有一个父母,P1,和一个孩子,C1。
现在 P1 和 C1 都遇到了第二个 fork 语句。如您所料,父进程创建了另一个子进程 (c2),但即使是子进程,c1 也会创建一个子进程 (c3)。所以实际上你有 P1、C1、C2 和 C3,这就是你得到 4 个打印语句输出的原因。
考虑这一点的一个好方法是使用树,每个节点代表一个进程,根节点是最顶层的父节点。
【讨论】:
【参考方案5】:pid = fork (); #1
pidb = fork (); #2
假设父进程 id 为 100,第一个 fork 创建另一个进程 101。现在 100 和 101 在 #1 之后继续执行,因此它们执行第二个 fork。 pid 100 到达 #2 创建另一个进程 102。pid 101 到达 #2 创建另一个进程 103。所以我们最终有 4 个进程。
你应该做的是这样的。
if(fork()) # parent
if(fork()) #parent
else # child2
else #child1
【讨论】:
这绝对有效。但是,我建议改用 switch 语句。 fork 函数可以返回 -1,我们可以在 switch 语句中使用 case -1 来处理这个错误。 我认为父母在 else 语句之后。为什么 if 语句中有父项?我很困惑。 因为 fork 在子节点上返回 0,而不是父节点。在父进程上它返回你刚刚创建的子进程的 PID,这更有用。 @tuxuday 你能举个例子吗?我不知道如何为此编写代码以上是关于如何使用 Fork() 只创建 2 个子进程?的主要内容,如果未能解决你的问题,请参考以下文章
fork 和 signal:如何将信号从父进程发送到特定的子进程
如何使用 fork() 将数字与父进程和子进程相加 [重复]