C 中子进程之间的 exec() 和 pipe()
exec() and pipe() between child process in C
我正在尝试使用 pipe()
和 fork()
来实现:
ls | wc
首先我检查了管道是否工作正常,这是代码。
#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()
无效?
你不需要在每次创建新进程时都等待并关闭父进程中的描述符,比如:
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==-1){ // fork failed
exit(1);
}
close(p[1]); // no need for writing in the parent
if((process2=fork())==0){ // child 2
dup2(p[0],0); // get stdin from pipe
char buff[1000]={0};
read(STDIN_FILENO,buff,250);
printf("---- in process2 -----\n%s\n",buff);
}
else if(process2==-1){ // second fork failed
close(p[0]); // ensure there is no reader to the pipe
wait(NULL); // wait for first chidren
exit(1);
}
close(p[0]); // no need for reading in the parent
wait(NULL);
wait(NULL); // wait for the two children
我正在尝试使用 pipe()
和 fork()
来实现:
ls | wc
首先我检查了管道是否工作正常,这是代码。
#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()
无效?
你不需要在每次创建新进程时都等待并关闭父进程中的描述符,比如:
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==-1){ // fork failed
exit(1);
}
close(p[1]); // no need for writing in the parent
if((process2=fork())==0){ // child 2
dup2(p[0],0); // get stdin from pipe
char buff[1000]={0};
read(STDIN_FILENO,buff,250);
printf("---- in process2 -----\n%s\n",buff);
}
else if(process2==-1){ // second fork failed
close(p[0]); // ensure there is no reader to the pipe
wait(NULL); // wait for first chidren
exit(1);
}
close(p[0]); // no need for reading in the parent
wait(NULL);
wait(NULL); // wait for the two children