使用 fork() 生成进程树
Generating a process tree with fork()
我需要创建一个进程树,其关系如图所示。
问题是我必须按字母顺序创建所有“节点”。我已经走到这一步了,但我的订单并不一致。我相信我使用 waitpid
不正确?
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int main(int argc, char **argv)
{
pid_t pidA, pidB, pidC, pidD, pidE, pidF, pidG, pidI;
pidA = fork();
if (pidA < 0)
{
perror("A");
exit(1);
}
else if (pidA == 0)
{
printf("%d: A\n", getpid());
pidB = fork();
if (pidB < 0)
{
perror("B");
exit(1);
}
else if (pidB == 0)
{
printf("%d: B\n", getpid());
waitpid(pidD, NULL, 0);
pidE = fork();
if (pidE < 0)
{
perror("E");
exit(1);
}
else if (pidE == 0)
{
printf("%d: E\n", getpid());
waitpid(pidG, NULL, 0);
pidI = fork();
if (pidI < 0)
{
perror("E");
exit(1);
}
else if (pidI == 0)
{
printf("%d: I\n", getpid());
}
else
{
;
}
}
else
{
pidF = fork();
if (pidF < 0)
{
perror("F");
exit(1);
}
else if (pidF == 0)
{
printf("%d: F\n", getpid());
}
else
{
;
}
}
}
else
{
pidC = fork();
if (pidC < 0)
{
perror("B");
exit(1);
}
else if (pidC == 0)
{
printf("%d: C\n", getpid());
waitpid(pidF, NULL, 0); // !
pidG = fork();
if (pidG < 0)
{
perror("G");
exit(1);
}
else if (pidG == 0)
{
printf("%d: G\n", getpid());
}
else
{
;
}
}
else
{
pidD = fork();
if (pidD < 0)
{
perror("B");
exit(1);
}
else if (pidD == 0)
{
printf("%d: D\n", getpid());
}
else
{
;
}
}
}
}
else
{
;
}
return 0;
}
输出不一致,所以我认为这部分帮助不大。
5644: A
5645: B
5646: C
5647: D
5648: G
5650: F
5649: E
5651: I
这里的主要问题是 waitpid
仅当所有进程线性相关(即父进程、子进程、“孙子”进程等)时才足以同步。
但是,如图所示,您的过程不是线性相关的。当您从 B 进程中调用 waitpid(pidD, NULL, 0);
时,您会看到出现此问题。不仅 pidD
没有在此上下文中定义,而且 D 进程也不是 B 进程的子进程,因此 waitpid
是不合适的。
@EOF 提出了一个很好的观点,即尝试 运行 串联多个进程会破坏拥有多个进程的目的。然而,如果你只是想把这个练习当作一个有趣的脑筋急转弯来做,我建议在原来的进程中设置 pipe
s ,然后在适当的进程想要发出它已经退出的信号时关闭写入端。正在等待第一个进程结束的进程可以在读取端调用select
。
我需要创建一个进程树,其关系如图所示。
问题是我必须按字母顺序创建所有“节点”。我已经走到这一步了,但我的订单并不一致。我相信我使用 waitpid
不正确?
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int main(int argc, char **argv)
{
pid_t pidA, pidB, pidC, pidD, pidE, pidF, pidG, pidI;
pidA = fork();
if (pidA < 0)
{
perror("A");
exit(1);
}
else if (pidA == 0)
{
printf("%d: A\n", getpid());
pidB = fork();
if (pidB < 0)
{
perror("B");
exit(1);
}
else if (pidB == 0)
{
printf("%d: B\n", getpid());
waitpid(pidD, NULL, 0);
pidE = fork();
if (pidE < 0)
{
perror("E");
exit(1);
}
else if (pidE == 0)
{
printf("%d: E\n", getpid());
waitpid(pidG, NULL, 0);
pidI = fork();
if (pidI < 0)
{
perror("E");
exit(1);
}
else if (pidI == 0)
{
printf("%d: I\n", getpid());
}
else
{
;
}
}
else
{
pidF = fork();
if (pidF < 0)
{
perror("F");
exit(1);
}
else if (pidF == 0)
{
printf("%d: F\n", getpid());
}
else
{
;
}
}
}
else
{
pidC = fork();
if (pidC < 0)
{
perror("B");
exit(1);
}
else if (pidC == 0)
{
printf("%d: C\n", getpid());
waitpid(pidF, NULL, 0); // !
pidG = fork();
if (pidG < 0)
{
perror("G");
exit(1);
}
else if (pidG == 0)
{
printf("%d: G\n", getpid());
}
else
{
;
}
}
else
{
pidD = fork();
if (pidD < 0)
{
perror("B");
exit(1);
}
else if (pidD == 0)
{
printf("%d: D\n", getpid());
}
else
{
;
}
}
}
}
else
{
;
}
return 0;
}
输出不一致,所以我认为这部分帮助不大。
5644: A
5645: B
5646: C
5647: D
5648: G
5650: F
5649: E
5651: I
这里的主要问题是 waitpid
仅当所有进程线性相关(即父进程、子进程、“孙子”进程等)时才足以同步。
但是,如图所示,您的过程不是线性相关的。当您从 B 进程中调用 waitpid(pidD, NULL, 0);
时,您会看到出现此问题。不仅 pidD
没有在此上下文中定义,而且 D 进程也不是 B 进程的子进程,因此 waitpid
是不合适的。
@EOF 提出了一个很好的观点,即尝试 运行 串联多个进程会破坏拥有多个进程的目的。然而,如果你只是想把这个练习当作一个有趣的脑筋急转弯来做,我建议在原来的进程中设置 pipe
s ,然后在适当的进程想要发出它已经退出的信号时关闭写入端。正在等待第一个进程结束的进程可以在读取端调用select
。