- 论坛徽章:
- 0
|
进程间通信的方式之一------管道,我想咨询一下:
管道模式:父进程从文件中读取数据写管道,子进程将标准输入作为管道的读端;
实现过程:父进程fork出子进程后,由于系统先执行父进程还是子进程是未知的,那么怎么能保证子进程在读取管道的时候,管道中已经有了父进程写入的数据呢? 程序代码:
#include <sys/wait.h>;
#include <unistd.h>;
#include <stdio.h>;
#define DEF_PAGER "/usr/bin/more"
#define MAXLINE 100
int main(int argc,char *argv[]){
int n,fd[2];
pid_t pid;
char line[MAXLINE], *pager, *argv0;
FILE *fp;
if (argc!=2){
printf("usage : a.out <pathname>;" ;
}
if ((fp=fopen(argv[1],"r" )==NULL){
printf("cant open %s\n",argv[1]);
}
if (pipe(fd)<0){
printf("pipe error\n" ;
}
if ((pid=fork())<0){
printf("fork error\n" ;
}
/*这里的pid是父进程还是子进程是随机的,由系统内核的调度算法决定*/
if (pid>;0){/*如果是父进程,从文件中读取,写入管道*/
close(fd[0]);
if (fgets(line,3,fp)!=NULL){
n=strlen(line);
if(write(fd[1],line,n)!=n){
printf("write to pipe error\n" ;
}
}
if (ferror(fp)){
printf("fgets error" ;
}
close(fd[1]);
if (waitpid(pid,NULL,0)<0){
printf("waitpid error\n" ;
}
exit(0);
}
else {/*如果是子进程,标准输入作为子进程的管道读取端*/
close(fd[1]);
if(fd[0]!=STDIN_FILENO){
if(dup2(fd[0],STDIN_FILENO)){
printf("dup2 error to stdin\n" ;
}
close(fd[0]);
}
/*下面这一段与我的问题关系不大,是取more命令的*/
if ((pager=(char *)getenv(" AGER" )==NULL){
pager=DEF_PAGER;
}
if ((argv0=(char *)strrchr(pager,'/'))!=NULL){
argv0++;
}
else argv0=pager;
/*这里execl执行more的时候,标准输入是如何作为管道输入端的呢?*/
if (execl(pager,argv0,(char *)0)<0){
printf("execl error for %s\n",pager);
}
}
}
不知道我有没有讲清楚,总结一下问题:
1。管道作为进程间通信的方式,父进程和子进程之间如何保证一致性呢?即:子进程会不会出现读空管道的情况呢?
2。上述的例程是《Unix环境下的高级编程》中关于进程间通信管道的例子,有兴趣的可以试着运行一下, 我运行了以后,每次execl都没有出现文件中的内容;用dbx跟踪,在fgets部分就core了;
3。将标准输入作为子进程管道的读取端,execl命令执行的时候不要加参数吗? |
|