gpt4 book ai didi

c - 两个 fork 和 wait 的使用

转载 作者:太空宇宙 更新时间:2023-11-04 00:08:24 24 4
gpt4 key购买 nike

目前我正在做两个分支来管道两个进程,但我认为我做的 wait(&status) 是错误的,因为在命令之后我的 shell 只是挂起并且没有返回到我的提示符。我知道我的管道正在工作,因为如果我删除等待,我可以看到结果。

有什么建议吗?

pipe(mypipe);
pid1=fork();
if(pid1==0)
{
pid2=fork();
if(pid2==0)
{
close(0);
dup(mypipe[0]);
close(mypipe[1]);
execv(foundnode2->path_dir,arv2);
exit(0);
}
close(1);
dup(mypipe[1]);
close(mypipe[0]);
pid2 = wait(&status2);
execv(foundnode1->path_dir,arv1);
exit(0);
}
pid1 = wait(&status2);

最佳答案

经验法则:如果您使用 dup()dup2()要将管道的一端映射到标准输入或标准输出,您应该 close()管道本身的两端。你没有那样做;您的等待是在等待程序完成,但程序不会完成,因为管道打开时仍有一个过程可以写入管道。此外,创建管道的进程需要关闭管道的两端,因为它本身不使用管道(子进程正在使用它)。另见 C MiniShell — Adding Pipelines .

此外,您不应该等待第一个 child 完成后再启动第二个 child (因此 pid2 = wait(&status2); 行不是一个好主意)。管道的容量相当小;如果要传输的总数据太大,写子可能会阻塞等待读子读取,但是读子还没有开始,因为它正在等待写子退出(并且需要很长时间为了让这个僵局自行解决)。您会看到没有 wait() 的输出调用是因为管道的第二部分执行并处理来自管道第一部分的数据,但它仍在等待来自 shell 的更多数据。

考虑到这些提示,您最终可能会:

pipe(mypipe);
pid1 = fork();
if (pid1 == 0)
{
pid2 = fork();
if (pid2 == 0)
{
close(0);
dup(mypipe[0]);
close(mypipe[1]);
close(mypipe[0]);
execv(foundnode2->path_dir, arv2);
fprintf(stderr, "Failed to exec %s\n", foundnode2->path_dir);
exit(1);
}
close(1);
dup(mypipe[1]);
close(mypipe[0]);
close(mypipe[1]);
execv(foundnode1->path_dir, arv1);
fprintf(stderr, "Failed to exec %s\n", foundnode1->path_dir);
exit(1);
}
close(mypipe[0]);
close(mypipe[1]);
pid1 = wait(&status1);

注意当命令失败时向标准错误报告错误 execv() .此外,0 的退出状态应保留为成功; 1 是一个方便的错误退出状态,或者你可以使用 EXIT_FAILURE来自 <stdlib.h> .

仍然省略了很多错误检查; fork()操作可能会失败; pipe()可能会失败。一个结果是,如果第二个 fork()失败,您仍然启动第二个 child (由 foundnode1->path_dir 标识)。

我注意到,通过将管道创建移动到第一个子进程中,您可以节省一些工作(这样父进程就不需要——事实上,不能——关闭管道):

int pid1 = fork();
if (pid1 == 0)
{
int mypipe[2];
pipe(mypipe);
int pid2 = fork();
if (pid2 == 0)
{
close(0);
dup(mypipe[0]);
close(mypipe[1]);
close(mypipe[0]);
execv(foundnode2->path_dir, arv2);
fprintf(stderr, "Failed to exec %s\n", foundnode2->path_dir);
exit(1);
}
close(1);
dup(mypipe[1]);
close(mypipe[0]);
close(mypipe[1]);
execv(foundnode1->path_dir, arv1);
fprintf(stderr, "Failed to exec %s\n", foundnode1->path_dir);
exit(1);
}
pid1 = wait(&status1);

关于c - 两个 fork 和 wait 的使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13654315/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com