三个孩子之间的管道

时间:2016-10-02 15:15:53

标签: c linux pipe fork

我执行此命令ls -al / | tr a-j A-J | tr k-z K-Z并且我从父进程创建了三个孩子。

我知道我打开两根烟斗,让父亲等他所有的孩子(关闭所有的烟斗)和我的孩子们

  • 关闭第一个孩子的STDIN
  • 在第一个管道上关闭STDOUT,在第二个管道上关闭第二个管道上的STDIN
  • 关闭第三个孩子的STDOUT

现在,这是我的代码。如果我只用两个孩子来运行它就可以了。但是,如果我尝试用三个孩子来运行它,它就不起作用。

//  command is ls -al / | tr a-j A-J | tr k-z K-Z

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char **argv) {
int fd1[2];
int fd2[2];
pid_t pid = 0;

pipe(fd1);
pipe(fd2);

pid = fork();
if(pid == 0) {
    close(fd1[0]);
    dup2(fd1[1], 1);
    close(fd1[1]);

    execlp("ls", "ls", "-al", "/", NULL);
}

pid = fork();
if(pid == 0) {
    close(fd1[1]);
    dup2(fd1[0], 0);
    close(fd1[0]);

    close(fd2[0]);
    dup2(fd2[1], 1);
    close(fd2[1]);

    execlp("tr", "tr", "a-j", "A-J", NULL);
}

pid = fork();
if(pid == 0) {
    close(fd2[1]);
    dup2(fd2[0], 0);
    close(fd2[0]);

    execlp("tr", "tr", "k-z", "K-Z", NULL);
}

close(fd1[0]);
close(fd1[1]);
close(fd2[0]);
close(fd2[1]);

while ((pid = wait(NULL)) != -1);

exit(0);
}

提前谢谢。

1 个答案:

答案 0 :(得分:0)

您可以使用 pipe2()并设置close_on_exec标志。以下代码有效:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

int main(int argc, char **argv) {
  int fd1[2];
  int fd2[2];
  pid_t pid = 0;

  pipe2(fd1,O_CLOEXEC);
  pipe2(fd2,O_CLOEXEC);

  pid = fork();
  if(pid == 0) {
    dup2(fd1[1],1);
    execlp("ls", "ls", "-al", "/", NULL);
  }

  pid = fork();
  if(pid == 0) {
    dup2(fd1[0],0);
    dup2(fd2[1],1);
    execlp("tr", "tr", "a-j", "A-J", NULL);
  }

  pid = fork();
  if(pid == 0) {
    dup2(fd2[0],0);
    execlp("tr", "tr", "k-z", "K-Z", NULL);
  }

  close(fd1[0]);
  close(fd1[1]);
  close(fd2[0]);
  close(fd2[1]);

  while ((pid = wait(NULL)) != -1);

  exit(0);
}

也可以使用 pipe()调用,但是你应该小心手动关闭描述符,这很容易出错(你通过发布这个问题证明了这一点;-)): / p>

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char **argv) {
  int fd1[2];
  int fd2[2];
  pid_t pid = 0;

  pipe(fd1);
  pipe(fd2);

  pid = fork();
  if(pid == 0) {
    close(fd1[0]);
    dup2(fd1[1], 1);
    close(fd1[1]);

    execlp("ls", "ls", "-al", "/", NULL);
  }

  pid = fork();
  if(pid == 0) {
    close(fd1[1]);
    dup2(fd1[0], 0);
    close(fd1[0]);

    close(fd2[0]);
    dup2(fd2[1], 1);
    close(fd2[1]);

    execlp("tr", "tr", "a-j", "A-J", NULL);
  }

  pid = fork();
  if(pid == 0) {
    close(fd1[0]);
    close(fd1[1]);
    close(fd2[1]);
    dup2(fd2[0], 0);
    close(fd2[0]);

    execlp("tr", "tr", "k-z", "K-Z", NULL);
  }

  close(fd1[0]);
  close(fd1[1]);
  close(fd2[0]);
  close(fd2[1]);

  while ((pid = wait(NULL)) != -1);
}