【发布时间】:2018-05-25 20:46:22
【问题描述】:
我正在尝试使用 pipe() 和 fork() 来实现这一点:
ls |厕所
首先我检查了管道是否工作正常,这是代码。
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
int main(void){
char *param1[]={"ls",NULL};
char *param2[]={"wc",NULL};
int p[2];
pipe(p);
pid_t process1, process2;
if((process1=fork())==0){ // child 1
dup2(p[1],1); // redirect stdout to pipe
close(p[0]);
execvp("ls", param1);
perror("execvp ls failed");
}
else if(process1>0){ // parent
wait(NULL);
}
if((process2=fork())==0){ // child 2
dup2(p[0],0); // get stdin from pipe
close(p[1]);
char buff[1000]={0};
read(STDIN_FILENO,buff,250);
printf("---- in process2 -----\n%s\n",buff);
}
else if(process2>0){ // parent
wait(NULL);
}
return 0;
}
我检查它工作正常。我把read()和printf()换成了exec(),比如:
if((process2=fork())==0){ // child 2
dup2(p[0],0); // get stdin from pipe
close(p[1]);
execvp("wc",param2);
perror("execvp wc failed");
}
我的终端挂了。我认为wc 进程没有得到任何输入。所以我的问题是,为什么read() 和printf() 有效,而execvp() 无效?
【问题讨论】:
-
这里有什么问题?
-
如果第一个进程启动失败,您没有错误处理!此外,您是否尝试在 两个 都执行后等待进程(防止管道满载)?
-
@potato 我解决了我的问题,谢谢
-
只是一个建议:如果你使用
STDIN_FILENO来代替read,那么你也可以使用这些宏来代替dup2...如果你只提供一个大小为1000 的缓冲区还是使用 250 字节?宁愿选择以 2 的幂为单位的缓冲区大小(1024、256、...)。