#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
/*利用 管道,写一个类似 ls -l |grep fork|grep 2的程序 , */
void exec(){
int fd[2];
int fd2[2];
pid_t pid;
char str[10];
char* cmd[3]={"ls","grep","grep"};
char* params[3][3]={{"ls","-l",NULL},{"grep","fork",NULL},{"grep","2",NULL}};
int i;
pipe(fd);
pipe(fd2);
pid=fork();
if(pid==0){ /* child */
dup2(fd[1],STDOUT_FILENO);
close(fd[0]);
close(fd2[0]);
close(fd2[1]);
execvp(cmd[0],params[0]); /* ls -l */
exit(1);
}
if(pid>0){
pid=fork();
if(pid==0){
dup2(fd[0],STDIN_FILENO);
close(fd[1]);
dup2(fd2[1],STDOUT_FILENO);
close(fd2[0]);
execvp(cmd[1],params[1]); /* grep fork */
exit(1);
}
/* dup2(0,STDIN_FILENO); */
/* dup2(1,STDOUT_FILENO); */
pid=fork();
if(pid==0){
dup2(fd2[0],STDIN_FILENO);
close(fd2[1]);
/* printf ("%s\n",cmd[2]); */
execvp(cmd[2],params[2]); /* grep 2 */
exit(1);
}
close(fd[0]);
close(fd[1]);
close(fd2[0]);
close(fd2[1]);
}
}
int main(int argc, char *argv[]){
exec();
return 0;
}
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
/*利用 管道,写一个类似 ls -l |grep fork|grep 2的程序 , */
void exec(){
int fd[2];
int fd2[2];
pid_t pid;
char str[10];
char* cmd[3]={"ls","grep","grep"};
char* params[3][3]={{"ls","-l",NULL},{"grep","fork",NULL},{"grep","2",NULL}};
int i;
pipe(fd);
pipe(fd2);
pid=fork();
if(pid==0){ /* child */
dup2(fd[1],STDOUT_FILENO);
close(fd[0]);
close(fd2[0]);
close(fd2[1]);
execvp(cmd[0],params[0]); /* ls -l */
exit(1);
}
if(pid>0){
pid=fork();
if(pid==0){
dup2(fd[0],STDIN_FILENO);
close(fd[1]);
dup2(fd2[1],STDOUT_FILENO);
close(fd2[0]);
execvp(cmd[1],params[1]); /* grep fork */
exit(1);
}
/* dup2(0,STDIN_FILENO); */
/* dup2(1,STDOUT_FILENO); */
pid=fork();
if(pid==0){
dup2(fd2[0],STDIN_FILENO);
close(fd2[1]);
/* printf ("%s\n",cmd[2]); */
execvp(cmd[2],params[2]); /* grep 2 */
exit(1);
}
close(fd[0]);
close(fd[1]);
close(fd2[0]);
close(fd2[1]);
}
}
int main(int argc, char *argv[]){
exec();
return 0;
}
10 个解决方案
#1
先关掉STDOUT_FILENO,否则dup2会复制到比STDOUT_FILENO大的最小的空闲fd
#2
有关系吗?
#3
否则标准输入输出就没变
#4
修改了一下代码 ,在第三个进程里加了
close(fd[0])
close(fd[1])就可以了,
很不解, 似乎 这个进程没用到fd这对管道 , 即不向里写也不从那读。
它只从fd2[2]里面读写数据
关不关fd[0],fd[1].怎么会影响到fd2[0] fd2[1]呢
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
/*利用 管道,写一个类似 ls -l |grep fork|grep 2的程序 , */
void exec(){
int fd[2];
int fd2[2];
pid_t pid;
char str[10];
char* cmd[3]={"ls","grep","grep"};
char* params[3][3]={{"ls","-l",NULL},{"grep","fork",NULL},{"grep","2",NULL}};
int i;
pipe(fd);
pipe(fd2);
pid=fork();
if(pid==0){ /* child */
dup2(fd[1],STDOUT_FILENO);
close(fd[0]);
close(fd2[0]);
close(fd2[1]);
execvp(cmd[0],params[0]); /* ls -l */
exit(1);
}
if(pid>0){
pid=fork();
if(pid==0){
dup2(fd[0],STDIN_FILENO);
close(fd[1]);
dup2(fd2[1],STDOUT_FILENO);
close(fd2[0]);
execvp(cmd[1],params[1]); /* grep fork */
exit(1);
}
/* dup2(0,STDIN_FILENO); */
/* dup2(1,STDOUT_FILENO); */
pid=fork();
if(pid==0){
dup2(fd2[0],STDIN_FILENO);
close(fd2[1]);
//这两行是新加的dddddddddddddddddddddddddddddddddddddddddddddddddddd
close(fd[0]);;
close(fd[1]);;
/* printf ("%s\n",cmd[2]); */
execvp(cmd[2],params[2]); /* grep 2 */
exit(1);
}
close(fd[0]);
close(fd[1]);
close(fd2[0]);
close(fd2[1]);
}
}
int main(int argc, char *argv[]){
exec();
return 0;
}
close(fd[0])
close(fd[1])就可以了,
很不解, 似乎 这个进程没用到fd这对管道 , 即不向里写也不从那读。
它只从fd2[2]里面读写数据
关不关fd[0],fd[1].怎么会影响到fd2[0] fd2[1]呢
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
/*利用 管道,写一个类似 ls -l |grep fork|grep 2的程序 , */
void exec(){
int fd[2];
int fd2[2];
pid_t pid;
char str[10];
char* cmd[3]={"ls","grep","grep"};
char* params[3][3]={{"ls","-l",NULL},{"grep","fork",NULL},{"grep","2",NULL}};
int i;
pipe(fd);
pipe(fd2);
pid=fork();
if(pid==0){ /* child */
dup2(fd[1],STDOUT_FILENO);
close(fd[0]);
close(fd2[0]);
close(fd2[1]);
execvp(cmd[0],params[0]); /* ls -l */
exit(1);
}
if(pid>0){
pid=fork();
if(pid==0){
dup2(fd[0],STDIN_FILENO);
close(fd[1]);
dup2(fd2[1],STDOUT_FILENO);
close(fd2[0]);
execvp(cmd[1],params[1]); /* grep fork */
exit(1);
}
/* dup2(0,STDIN_FILENO); */
/* dup2(1,STDOUT_FILENO); */
pid=fork();
if(pid==0){
dup2(fd2[0],STDIN_FILENO);
close(fd2[1]);
//这两行是新加的dddddddddddddddddddddddddddddddddddddddddddddddddddd
close(fd[0]);;
close(fd[1]);;
/* printf ("%s\n",cmd[2]); */
execvp(cmd[2],params[2]); /* grep 2 */
exit(1);
}
close(fd[0]);
close(fd[1]);
close(fd2[0]);
close(fd2[1]);
}
}
int main(int argc, char *argv[]){
exec();
return 0;
}
#5
关闭fd[1]就可以了。可能是同时两个管道在STDOUT_FILENO上导致的问题。
#6
fd2对于ls进程就没用,应该在grep fork进程创建,逻辑关系本来就是ls关联grep fork,grep fork关联grep 2,你倒写成了ls关联grep fork & grep 2,有悖逻辑吧。
另外ls进程没有close(fd[1]),grep进程始终读不到EOF。
另外ls进程没有close(fd[1]),grep进程始终读不到EOF。
#7
我最初的想法是,
主进程先建好 fd,fd2 两个管道 。然后,在分别fork 出 "ls" ,"grep fork", "grep 2" 3 个进程时,
这两个管道都是打开的, 各进程将自己的stdin ,stdout 与相应的管道关联,用不到的管道则关闭之。
主进程因用不到管道 ,在fork 完所有进程时,关闭所有pipe .
#8
以前修改过一个类似的问题,参考一下吧
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main()
{
pid_t pid[3];
int pipe_fd[2];
int pipe_fd2[2];
int status;
char *prog1[3] = {"/bin/ls", "-l", NULL};
char *prog2[3] = {"/bin/grep", "cpp", NULL};
char *prog3[3] = {"/bin/grep", "2", NULL};
if (pipe(pipe_fd) < 0) {
perror("pipe 1 failed");
}
if (pipe(pipe_fd2) < 0) {
perror("pipe 2 failed");
}
if ((pid[0] = fork()) < 0) {
perror("fork failed");
}
if (pid[0] == 0) {
close(pipe_fd[0]);
dup2(pipe_fd[1], 1);
close(pipe_fd[1]);
close(pipe_fd2[0]);
close(pipe_fd2[1]);
execvp(prog1[0], prog1);
}
if (pid[0] > 0) {
pid[1] = fork();
if (pid[1] == 0) {
close(pipe_fd[1]);
dup2(pipe_fd[0], 0);
close(pipe_fd[0]);
close(pipe_fd2[0]);
dup2(pipe_fd2[1], 1);
close(pipe_fd2[1]);
execvp(prog2[0], prog2);
}
if (pid[1]>0) {
pid[2] = fork();
if (pid[2] == 0) {
close(pipe_fd2[1]);
dup2(pipe_fd2[0], 0);
close(pipe_fd2[0]);
close(pipe_fd[0]);
close(pipe_fd[1]);
execvp(prog3[0], prog3);
}
}
close(pipe_fd[0]);
close(pipe_fd[1]);
close(pipe_fd2[0]);
close(pipe_fd2[1]);
waitpid(pid[1], &status, 0);
}
return 0;
}
#9
按照 你的思路,似乎 ,fd由 ls 进程创建,fd2由 "grep fork"进程创建,
假如仍然由主进程创建这3个进程,那么岂不出现, "grep fork"进程里的fd ,根本就没打开 。
因为它只继续了主进程里打开的管道吧。
另外, ls 进程 如何close (fd[1]),
我的意思 是 dup2(fd[1],stdout_fileno)后,需要关闭fd[1]吗,
dup2后,fd[1],stdout_fileno ,fd[1] 跟stdout_fileno ,应该代表同一个“文件”吧,关了fd[1],不就代表关了stdout了吗?
#10
不同的fd共享同一个文件表项,只有所有共享同一表项的fd全部close,才会令read该fd的返回0,否则子进程就是无限的等待read。
#1
先关掉STDOUT_FILENO,否则dup2会复制到比STDOUT_FILENO大的最小的空闲fd
#2
有关系吗?
#3
否则标准输入输出就没变
#4
修改了一下代码 ,在第三个进程里加了
close(fd[0])
close(fd[1])就可以了,
很不解, 似乎 这个进程没用到fd这对管道 , 即不向里写也不从那读。
它只从fd2[2]里面读写数据
关不关fd[0],fd[1].怎么会影响到fd2[0] fd2[1]呢
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
/*利用 管道,写一个类似 ls -l |grep fork|grep 2的程序 , */
void exec(){
int fd[2];
int fd2[2];
pid_t pid;
char str[10];
char* cmd[3]={"ls","grep","grep"};
char* params[3][3]={{"ls","-l",NULL},{"grep","fork",NULL},{"grep","2",NULL}};
int i;
pipe(fd);
pipe(fd2);
pid=fork();
if(pid==0){ /* child */
dup2(fd[1],STDOUT_FILENO);
close(fd[0]);
close(fd2[0]);
close(fd2[1]);
execvp(cmd[0],params[0]); /* ls -l */
exit(1);
}
if(pid>0){
pid=fork();
if(pid==0){
dup2(fd[0],STDIN_FILENO);
close(fd[1]);
dup2(fd2[1],STDOUT_FILENO);
close(fd2[0]);
execvp(cmd[1],params[1]); /* grep fork */
exit(1);
}
/* dup2(0,STDIN_FILENO); */
/* dup2(1,STDOUT_FILENO); */
pid=fork();
if(pid==0){
dup2(fd2[0],STDIN_FILENO);
close(fd2[1]);
//这两行是新加的dddddddddddddddddddddddddddddddddddddddddddddddddddd
close(fd[0]);;
close(fd[1]);;
/* printf ("%s\n",cmd[2]); */
execvp(cmd[2],params[2]); /* grep 2 */
exit(1);
}
close(fd[0]);
close(fd[1]);
close(fd2[0]);
close(fd2[1]);
}
}
int main(int argc, char *argv[]){
exec();
return 0;
}
close(fd[0])
close(fd[1])就可以了,
很不解, 似乎 这个进程没用到fd这对管道 , 即不向里写也不从那读。
它只从fd2[2]里面读写数据
关不关fd[0],fd[1].怎么会影响到fd2[0] fd2[1]呢
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
/*利用 管道,写一个类似 ls -l |grep fork|grep 2的程序 , */
void exec(){
int fd[2];
int fd2[2];
pid_t pid;
char str[10];
char* cmd[3]={"ls","grep","grep"};
char* params[3][3]={{"ls","-l",NULL},{"grep","fork",NULL},{"grep","2",NULL}};
int i;
pipe(fd);
pipe(fd2);
pid=fork();
if(pid==0){ /* child */
dup2(fd[1],STDOUT_FILENO);
close(fd[0]);
close(fd2[0]);
close(fd2[1]);
execvp(cmd[0],params[0]); /* ls -l */
exit(1);
}
if(pid>0){
pid=fork();
if(pid==0){
dup2(fd[0],STDIN_FILENO);
close(fd[1]);
dup2(fd2[1],STDOUT_FILENO);
close(fd2[0]);
execvp(cmd[1],params[1]); /* grep fork */
exit(1);
}
/* dup2(0,STDIN_FILENO); */
/* dup2(1,STDOUT_FILENO); */
pid=fork();
if(pid==0){
dup2(fd2[0],STDIN_FILENO);
close(fd2[1]);
//这两行是新加的dddddddddddddddddddddddddddddddddddddddddddddddddddd
close(fd[0]);;
close(fd[1]);;
/* printf ("%s\n",cmd[2]); */
execvp(cmd[2],params[2]); /* grep 2 */
exit(1);
}
close(fd[0]);
close(fd[1]);
close(fd2[0]);
close(fd2[1]);
}
}
int main(int argc, char *argv[]){
exec();
return 0;
}
#5
关闭fd[1]就可以了。可能是同时两个管道在STDOUT_FILENO上导致的问题。
#6
fd2对于ls进程就没用,应该在grep fork进程创建,逻辑关系本来就是ls关联grep fork,grep fork关联grep 2,你倒写成了ls关联grep fork & grep 2,有悖逻辑吧。
另外ls进程没有close(fd[1]),grep进程始终读不到EOF。
另外ls进程没有close(fd[1]),grep进程始终读不到EOF。
#7
我最初的想法是,
主进程先建好 fd,fd2 两个管道 。然后,在分别fork 出 "ls" ,"grep fork", "grep 2" 3 个进程时,
这两个管道都是打开的, 各进程将自己的stdin ,stdout 与相应的管道关联,用不到的管道则关闭之。
主进程因用不到管道 ,在fork 完所有进程时,关闭所有pipe .
#8
以前修改过一个类似的问题,参考一下吧
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main()
{
pid_t pid[3];
int pipe_fd[2];
int pipe_fd2[2];
int status;
char *prog1[3] = {"/bin/ls", "-l", NULL};
char *prog2[3] = {"/bin/grep", "cpp", NULL};
char *prog3[3] = {"/bin/grep", "2", NULL};
if (pipe(pipe_fd) < 0) {
perror("pipe 1 failed");
}
if (pipe(pipe_fd2) < 0) {
perror("pipe 2 failed");
}
if ((pid[0] = fork()) < 0) {
perror("fork failed");
}
if (pid[0] == 0) {
close(pipe_fd[0]);
dup2(pipe_fd[1], 1);
close(pipe_fd[1]);
close(pipe_fd2[0]);
close(pipe_fd2[1]);
execvp(prog1[0], prog1);
}
if (pid[0] > 0) {
pid[1] = fork();
if (pid[1] == 0) {
close(pipe_fd[1]);
dup2(pipe_fd[0], 0);
close(pipe_fd[0]);
close(pipe_fd2[0]);
dup2(pipe_fd2[1], 1);
close(pipe_fd2[1]);
execvp(prog2[0], prog2);
}
if (pid[1]>0) {
pid[2] = fork();
if (pid[2] == 0) {
close(pipe_fd2[1]);
dup2(pipe_fd2[0], 0);
close(pipe_fd2[0]);
close(pipe_fd[0]);
close(pipe_fd[1]);
execvp(prog3[0], prog3);
}
}
close(pipe_fd[0]);
close(pipe_fd[1]);
close(pipe_fd2[0]);
close(pipe_fd2[1]);
waitpid(pid[1], &status, 0);
}
return 0;
}
#9
按照 你的思路,似乎 ,fd由 ls 进程创建,fd2由 "grep fork"进程创建,
假如仍然由主进程创建这3个进程,那么岂不出现, "grep fork"进程里的fd ,根本就没打开 。
因为它只继续了主进程里打开的管道吧。
另外, ls 进程 如何close (fd[1]),
我的意思 是 dup2(fd[1],stdout_fileno)后,需要关闭fd[1]吗,
dup2后,fd[1],stdout_fileno ,fd[1] 跟stdout_fileno ,应该代表同一个“文件”吧,关了fd[1],不就代表关了stdout了吗?
#10
不同的fd共享同一个文件表项,只有所有共享同一表项的fd全部close,才会令read该fd的返回0,否则子进程就是无限的等待read。