繁体   English   中英

Unix中的C:fork,waitpid和管道

[英]C in Unix: fork, waitpid and pipes

我的问题是关于如何控制与管道有关的进程执行,尤其是wait / waitpid函数的实现。

当我对下面的命令创建一个管道ls | head -3 ls | head -3 ,我执行以下操作:

  • 我创建管道,分叉创建子进程
  • 对于孩子,我为标准输入调用dup2,执行head -3命令,关闭孩子中管道的输出端
  • 对于父级,我为标准输出调用dup2,执行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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM