【发布时间】:2011-01-12 13:56:59
【问题描述】:
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int main(int argc,char **argv)
{
int fd[2];
pid_t childpid;
pipe(fd);
childpid=fork();
if (childpid == -1)
{
perror("Error forking...");
exit(1);
}
if (childpid) /*parent proces*/ //grep .c
{
wait(&childpid); //waits till the child send output to pipe
close(fd[1]);
close(0); //stdin closed
dup2(fd[0],0);
execlp(argv[2],argv[2],argv[3],NULL);
}
if (childpid==0) //ls
{
close(fd[0]); /*Closes read side of pipe*/
close(1); //STDOUT closed
dup2(fd[1],1);
execl(argv[1],NULL);
}
return 0;
}
如果我将命令行参数指定为“ls grep .c”,我应该会显示所有“.c”文件。
伪代码:- 我的子进程将运行“ls”而父进程将运行“grep .c”.. 父进程等待子进程完成,以便子进程写入管道。
试运行:-
bash-3.1$ ls | grep .c
1.c
hello.c
bash-3.1$ ./a.out ls grep .c
bash-3.1$
为什么会这样?
【问题讨论】:
-
好的。我自己得到了答案。我在子进程中使用了“execl()”,它不使用 $PATH 环境变量搜索文件名....如果我更改为 execlp(),程序将按预期运行。
-
你可能也不想要那个“wait(&childpid);” (或其不准确的评论)在那里。它不会等到数据来自子进程,而是等到子进程状态发生变化 - 例如出口。如果您的子进程写入的数据超过管道的价值(可能是 8k),它将挂起等待父进程读取,而父进程仍在等待它退出。
-
那么,我应该怎么做才能让父级在子级执行后执行......?
-
read(2) 从父端将阻塞,直到有数据或 EOF。管道的全部意义在于两个程序同时运行。
-
为了更简洁的代码,不要使用三重 if 语句(不需要它并添加额外的计算)你要么是失败的 fork,要么是孩子,要么是父母,所以 if ((childpid = fork() ) == -1) {...} else if(childpid == 0) {...} else{...}