【发布时间】:2018-03-13 16:43:49
【问题描述】:
我的 shell 的特定命令行出现问题:
base64 /dev/urandom | head -c 1000
如您所见,第一个进程 base64 将永无止境的字符写入管道,head 将读取前 1000 个字符,然后正确退出。
我知道管道的 fd 在每个子进程中都是重复的,并且如果您在父进程中关闭它们,它们将不会在子进程中关闭,从而导致我遇到的问题。在父进程中关闭管道的读取端时,它不会发送终止第一个进程的 SIGPIPE 信号,因为它在子进程中仍然是打开的。
因此,基本上,在一个永无止境的过程中,它会尝试成功写入管道,因为在fork中,管道的读取端永远不会关闭。
那么,当第二个进程完成管道中的读取后,如何才能成功退出第一个进程,换句话说,如何在子进程之间共享 SIGPIPE 信号。
这段代码是我进行管道、分叉和等待的部分:
void exec_process(t_shell *sh, t_job *job, int *iofile)
{
t_parse *parse;
parse = init_parse(sh, job->process->cmd);
if (check_builtins(parse->argv[0]))
{
if (iofile[0] != 0)
job->process->stdio[0] = iofile[0];
if (iofile[1] != 1)
job->process->stdio[1] = iofile[1];
launch_builtin(sh, parse, job);
}
else if ((job->process->pid = fork()) == 0)
{
if (iofile[0] != 0)
job->process->stdio[0] = iofile[0];
if (iofile[1] != 1)
job->process->stdio[1] = iofile[1];
launch_bin(parse, job);
}
free_parse(&parse);
if (iofile[0] != 0)
close(iofile[0]);
if (iofile[1] != 1)
close(iofile[1]);
}
static void launch_process(t_shell *sh, t_job *job)
{
t_process *process;
int iofile[2];
int pipefd[2];
int i;
process = job->process;
iofile[0] = 0;
i = get_num_process(job->process);
while (job->process)
{
if (job->process->next)
{
pipe(pipefd);
iofile[1] = pipefd[1];
}
else
iofile[1] = 1;
exec_process(sh, job, iofile);
iofile[0] = pipefd[0];
job->process = job->process->next;
}
job->process = process;
wait_for_job(sh, job, i);
}
我有一个父母和两个孩子,他们只链接到父母。
有什么建议吗?谢谢
【问题讨论】: