首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >多个子级之间的C++管道

多个子级之间的C++管道
EN

Stack Overflow用户
提问于 2011-11-02 05:41:51
回答 2查看 3K关注 0票数 0

我正在做一个项目,除了一个小问题(大问题),我基本上解决了这个问题。我似乎想不出如何在任意数量的孩子之间创建管道。

例如,我接受命令行参数来确定将生成多少子对象。第一个孩子没有输入,但有输出,最后一个孩子输出到STD输出。我需要按顺序将值传递给第一个子代和之后的每个子代。下面是我得到的信息:

代码语言:javascript
复制
#include <errno.h>
#include <cstdio>
#include <iostream>
#include <sys/wait.h>

using namespace std;

int main(int argc, char *argv[]) {
    pid_t childpid;
    int x2ypipe[2];
    pipe(x2ypipe);
    if(x2ypipe==0) {
        cout<<"ERROR:"<<errno<<endl;
    }
    int y2zpipe[2];
    pipe(y2zpipe);
    if(y2zpipe==0) {
        cout<<"ERROR:"<<errno<<endl;
    }
    pid_t xchild =fork();
    if(xchild==0) {
        dup2(x2ypipe[1],STDOUT_FILENO);
        close(x2ypipe[0]);
        close(x2ypipe[1]);
        int a=execl(argv[1],argv[1], (char*)NULL);
        if(a==-1) {
            perror("The following error occurred at A");
        }
    }
    for(int i=2; i<(argc-1); i++) {
        childpid =fork();
        if(childpid==0) {
            dup2(x2ypipe[0],STDIN_FILENO);
            close(x2ypipe[0]);
            close(x2ypipe[1]);
            //direct y2z pipe to standard output and replace the child with the program part2
            dup2(x2ypipe[1],y2zpipe[1]);
            dup2(y2zpipe[1],STDOUT_FILENO);
            close(y2zpipe[0]);
            close(y2zpipe[1]);
            int b=execl(argv[i],argv[i],(char *)NULL);
            if(b==-1) {
                perror("The following error occurred at B");
            }
        }
    }
    pid_t zchild =fork();
    if(zchild==0) {
        dup2(y2zpipe[0],STDIN_FILENO);
        close(y2zpipe[0]);
        close(y2zpipe[1]);
        int c=execl(argv[argc-1],argv[argc-1],(char *)NULL);
        if(c==-1) {
            perror("The following error occurred at C");
        }
    }
    close(x2ypipe[0]);
    close(x2ypipe[1]);
    wait(NULL);
    wait(NULL);
    wait(NULL);
}

现在,我只向argv[]传入了三个程序,它工作得很好。我将不得不在我的for循环中添加一个if语句来检查最后一个/最高可能的i值,以便将y2z管道连接到zchild。在for循环中,我在连接子对象时遇到了问题。我该如何为最后一个孩子中的每个孩子创建一个新管道呢?

EN

回答 2

Stack Overflow用户

发布于 2011-11-02 06:27:01

也许这会有帮助。注意我是如何在for循环中调用pipe()的,这样我就不必为管道对想出新的"x2y“、"y2z”、"z2omega“等名称了。

还要注意我是如何从for循环外部使用变量prevfd将前一次迭代的管道文件描述符携带到下一次迭代中的。以及它是如何指向"/dev/null“的。

最后,请注意我是如何在一个循环中尽可能多次地调用wait(),而不是编写3次(或4次、5次或... 1,397次)。

代码语言:javascript
复制
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <cstdlib>
#include <cstdio>
#include <sys/wait.h>

int main(int argc, char *argv[]) {

  int prevfd;

  prevfd = open("/dev/null", O_RDONLY);

  if(prevfd < 0) {
    perror("/dev/null");
    exit(1);
  }

  for(int i = 1; i < argc; ++i) {
    int pipefd[2];
    int kid;

    if(i != argc-1 && pipe(pipefd)) {
      perror("pipe");
      break;
    }

    if(!fork()) {
      dup2(prevfd, 0);
      close(prevfd);
      if(i != argc-1) {
        dup2(pipefd[1], 1);
        close(pipefd[0]);
        close(pipefd[1]);
      }
      execl(argv[i], argv[i], (char*)0);
      perror(argv[i]);
      exit(1);
    }

    close(prevfd);
    prevfd = pipefd[0];
    close(pipefd[1]);
  }
  while(wait((int*)0) != -1)
    ;
  return 0;
}
票数 1
EN

Stack Overflow用户

发布于 2011-11-02 06:05:08

您需要在每对连接的进程之间使用单独的管道。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7973289

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档