在以下代码中,我希望子c1
阻止(通过管道),直到孩子c2
完成(通过pipe_close()
中的c2
)。但它不起作用。 c1
会永远阻止。如果我将pipe_close()
移出c2
并将其放在父级中,它就会起作用。
这是因为从父级创建的管道在兄弟子进程之间不可共享吗?
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdarg.h>
static void pipe_close(int *);
static void pipe_read(int *);
int
main(void)
{
int pp_main[2] = {-1, -1};
pipe(pp_main);
int ppid = getpid();
int pgid = getpgrp();
int pid_c1 = fork();
if (pid_c1 == 0)
{ // in child c1
int cpid_c1 = getpid();
int gid = getpgrp();
printf("[c1][%d][%d] is made, wait pipe ready\n", cpid_c1, gid);
pipe_read(pp_main);
printf("[c1][%d][%d] done\n", cpid_c1, gid);
}
else
{ // in parent
printf("[main][%d][%d] created child c1: %d\n", ppid, pgid, pid_c1);
int pid_c2 = fork();
if (pid_c2 == 0)
{ // in child c2
int cpid_c2 = getpid();
int gid = getpgrp();
printf("[c2][%d][%d] is made\n", cpid_c2, gid);
for (int i = 2; i > 0; --i)
{
printf("[c2][%d][%d] count down %d\n", cpid_c2, gid, i);
sleep(1);
}
pipe_close(pp_main);
printf("[c2][%d][%d] done\n", cpid_c2, gid);
}
else
{ // in parent
printf("[main][%d][%d] created child c2: %d\n", ppid, pgid, pid_c2);
}
int status;
waitpid(pid_c2, &status, 0);
}
int status;
waitpid(pid_c1, &status, 0);
return 0;
}
static void
pipe_read(int *pp)
{
char ch;
if (pp[1] >= 0)
{
close (pp[1]);
pp[1] = -1;
}
if (pp[0] >= 0)
{
while (read (pp[0], &ch, 1) == -1 && errno == EINTR);
}
}
static void
pipe_close(int *pp)
{
if (pp[0] >= 0)
close (pp[0]);
if (pp[1] >= 0)
close (pp[1]);
pp[0] = pp[1] = -1;
}
答案 0 :(得分:1)
如果我将pipe_close()移出c2并将其放在父级中,它就可以工作。
这是预期的行为。在关闭所有引用之前,管道未完全关闭。在您的代码中,pipe
是在fork
之前创建的。因此,父进程和子进程都打开了该管道。 c2子进程将退出,以便关闭对管道的引用。但是,父进程阻止等待c1退出。这将永远不会发生,因为父进程没有显式或隐式(通过退出)关闭管道。