免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2459 | 回复: 5
打印 上一主题 下一主题

[SCO UNIX] 进程间通信---管道pipe的疑问 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2004-12-27 18:47 |只看该作者 |倒序浏览
进程间通信的方式之一------管道,我想咨询一下:
    管道模式:父进程从文件中读取数据写管道,子进程将标准输入作为管道的读端;
    实现过程:父进程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命令执行的时候不要加参数吗?

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
2 [报告]
发表于 2004-12-27 21:18 |只看该作者

进程间通信---管道pipe的疑问

1. 当然,当设置了非阻塞方式read,需要自己处理read空的,
不过对于more只要你不按del退出来,它会阻塞在那里,它的read是阻塞方式
2. 没仔细看你的程序,不过fgets里的3不太好,难道你的文件每行除了\n只有2字母?
3. 不是execl不需要参数,而是要看excel执行的程序,
比如不是more而是vi,那么你不给参数,它就会打开个空文件
而more就会等待输入内容

论坛徽章:
0
3 [报告]
发表于 2004-12-28 09:18 |只看该作者

进程间通信---管道pipe的疑问

谢谢版主!
1。对于一般的情况,你说的阻塞是否要人为地设置呢,或者管道机制有没有一个默认的阻塞呢?
2。这里的fgets我用了3是因为使用dbx工具每次到这里,程序都会报内存处理错误,但是直接编译运行了却不core,我的实验的文本里面只有3个字符,所以我就看看是不是fgets的时候超出范围了,不过好像还是不行。
3。因为父进程和子进程运行的次序不能固定,会不会出现父进程运行了一段时间,子进程开始运行,出现交叉运行的情况呢?有经验的朋友能举个自己的例子吗?

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
4 [报告]
发表于 2004-12-28 13:48 |只看该作者

进程间通信---管道pipe的疑问

1. 如果你不用ioctl设定fd,那么默认就是阻塞方式
2. 你的程序dup了标准输入,而dbx调试需要标准输入,
这样资源就变成了递归申请,当然会core,这种程序在unix下只能printf调了
3. 当然会交叉运行了,分时操作系统的基本特征

论坛徽章:
0
5 [报告]
发表于 2004-12-28 16:52 |只看该作者

进程间通信---管道pipe的疑问

继续提问斑竹:
子进程read动作发现无数据可读,自动阻塞;那么父进程write动作,遇到什么情况的时候会发生阻塞呢?
父进程write后,他做什么动作呢,等待子进程的结束返回信息吗?(什么也不做?这也算一种阻塞?)

我有没有钻牛角尖?对这个父进程,子进程的执行序列总是搞不清楚!
有哪位大哥给个点拨!!!

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
6 [报告]
发表于 2004-12-28 17:17 |只看该作者

进程间通信---管道pipe的疑问

1. 如果对方关闭了读管道,则write有SIGPIPE信号中断,如果不做signal处理,程序会core掉,
正常时刻write会返回写入长度
2. 同步的办法很多,有信号灯等方式都可用
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP