我正在做一个项目,除了一个小问题(大问题),我基本上解决了这个问题。我似乎想不出如何在任意数量的孩子之间创建管道。
例如,我接受命令行参数来确定将生成多少子对象。第一个孩子没有输入,但有输出,最后一个孩子输出到STD输出。我需要按顺序将值传递给第一个子代和之后的每个子代。下面是我得到的信息:
#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循环中,我在连接子对象时遇到了问题。我该如何为最后一个孩子中的每个孩子创建一个新管道呢?
发布于 2011-11-02 06:27:01
也许这会有帮助。注意我是如何在for循环中调用pipe()的,这样我就不必为管道对想出新的"x2y“、"y2z”、"z2omega“等名称了。
还要注意我是如何从for循环外部使用变量prevfd将前一次迭代的管道文件描述符携带到下一次迭代中的。以及它是如何指向"/dev/null“的。
最后,请注意我是如何在一个循环中尽可能多次地调用wait(),而不是编写3次(或4次、5次或... 1,397次)。
#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;
}发布于 2011-11-02 06:05:08
您需要在每对连接的进程之间使用单独的管道。
https://stackoverflow.com/questions/7973289
复制相似问题