[英]C in Unix: fork, waitpid and pipes
我的问题是关于如何控制与管道有关的进程执行,尤其是wait
/ waitpid
函数的实现。
当我对下面的命令创建一个管道ls | head -3
ls | head -3
,我执行以下操作:
head -3
命令,关闭孩子中管道的输出端 ls
命令,关闭父级中管道的输入端 我的问题: 基于此讨论 ,我确实需要等待孩子完成执行,即head -3
的执行。 但是,如何/在何处实现waitpid
函数,使其与close[]
命令不冲突?
基于此出色的文字 ,说明如下:
如果父母希望从孩子那里接收数据,则应关闭fd1,然后孩子应关闭fd0。 如果父母希望将数据发送给孩子,则应关闭fd0,然后孩子应关闭fd1。 由于描述符是在父级和子级之间共享的,因此,我们始终应确保关闭无关的管道末端。 从技术上讲,如果未显式关闭管道不必要的末端,则EOF将永远不会返回。
因此,子级必须在执行前等待父级完成管道。
我还看到了为管道的一个过程制作两个叉子的示例。 就像我在《 APUE ch.8》副本中的描述一样,这是否是避免僵尸进程的目的?
考虑以下代码实现:
#include <stdlib.h>
#include <stdio.h>
#include <sys/wait.h>
#include <sys/types.h>
int main()
{
int pid, status;
int fd[2];
char *com1[2];
char *com2[3];
com1[0] = "ls";
com1[1] = NULL;
com2[0] = "head";
com2[1] = "-3";
com2[2] = NULL;
pipe(fd);
if((pid = fork()) == -1)
{
printf("fork error");
exit(1);
}
if(pid == 0)
{
/* Child process closes up output side of pipe */
dup2(fd[0], 0);
close(fd[1]);
execvp(com2[0], com2);
}
else
{
/* if(waitpid(0, WIFEXITED(&status), 0) != pid)
{
printf("wait error");
}
is this even needed here? */
/* Parent process closes up input side of pipe */
dup2(fd[1], 1);
close(fd[0]);
execvp(com1[0], com1);
}
exit(0);
}
我必须承认,我在StackExchange上浏览了许多类似的问题。 但是,几乎所有这些内容都具有特定的内容。 我正在寻找的是原理的解释和功能的组合。 感谢您的时间!
你们不能都想等孩子和高管。 所以你需要有两个孩子。 有两种常见的方法可以执行此操作:要么有一个父进程创建两个直接子进程,然后可以/必须等待两个进程; 或有一个自己创建第二个孩子的孩子,这样父孩子只需要等待一个过程终止即可。
选项1 (继承的管道)
pipe(pi);
pid1 = fork();
if (pid1==0) { // child1
// make redirections
exec("head"...);
}
pid2 = fork();
if (pid2==0) { // child2
// make redirections
exec("ls"...);
}
// parent process
// close unuseful pipe
waitpid(pid1...);
waitpid(pid2...);
选项2 (管道仅对相关过程可见)
pid1 = fork();
if (pid1==0) { // child
pipe(pi);
pid2 = fork();
if (pid2==0) { // gran child
// make redirections
exec("ls"...);
}
// make redirections
exec("head"...);
}
// parent process
waitpid(pid1...);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.