Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1745752
  • 博文数量: 335
  • 博客积分: 4690
  • 博客等级: 上校
  • 技术积分: 4341
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-08 21:38
个人简介

无聊之人--除了技术,还是技术,你懂得

文章分类

全部博文(335)

文章存档

2016年(29)

2015年(18)

2014年(7)

2013年(86)

2012年(90)

2011年(105)

分类: C/C++

2012-03-28 16:36:14


点击(此处)折叠或打开

  1. #include "apue.h"
  2. int main(void)
  3. {
  4.     int int1,int2;
  5.     char line[MAXLINE];
  6.     while ( fgets(line,MAXLINE,stdin) != NULL ) {   /*   std io type   全缓冲 */
  7.          if (sscanf(line,"%d%d",&int1,&int2) == 2 ){
  8.             if (printf("%d\n",int1+int2) == EOF)
  9.                 err_sys("printf error ");
  10.         } else {
  11.             if (printf("invalid args\n") == EOF)
  12.                 err_sys("printf error ");
  13.         }
  14.     }
  15.         exit(0);
  16.     
  17. }


点击(此处)折叠或打开

  1. #include "apue.h"
  2. static void sig_pipe(int); /* our signal handler */
  3. int main(void)
  4. {
  5.     int n,fd1[2],fd2[2];
  6.     pid_t pid;
  7.     char line[MAXLINE];

  8.     if (signal(SIGPIPE,sig_pipe) == SIG_ERR)
  9.         err_sys("signal error ");
  10.     if ( pipe(fd1) < 0 || pipe(fd2) < 0)
  11.         err_sys("pipe error ");
  12.     if (( pid = fork() ) < 0) {
  13.         err_sys("fork error ");
  14.     } else if ( pid > 0) { /* parent */
  15.         close(fd1[0]);
  16.         close(fd2[1]);
  17.         while( fgets(line,MAXLINE,stdin) != NULL ){
  18.             n = strlen(line);
  19.             if (write(fd1[1],line,n) != n)
  20.                 err_sys("write error to pipe");
  21.             if (( n = read(fd2[0],line,MAXLINE)) < 0)
  22.                 err_sys("read error form pipe ");
  23.             if ( n == 0 ){
  24.                 err_msg("child closed pipe ");
  25.                 break;
  26.             }
  27.             line[n] = 0; /* null terminate */
  28.             if (fputs(line,stdout) == EOF )
  29.                 err_sys("fputs error");
  30.              break;
  31.         }
  32.         if (ferror(stdin))
  33.             err_sys("fgets error on stdin ");
  34.         exit(0);
  35.     }else { /* child */
  36.         close(fd1[1]);
  37.         close(fd2[0]);
  38.         if (fd1[0] != STDIN_FILENO) {
  39.             if (dup2(fd1[0],STDIN_FILENO) != STDIN_FILENO)
  40.                 err_sys("dup2 error to stdin");
  41.         close(fd1[0]);
  42.      }
  43.         if (fd2[1] != STDOUT_FILENO) {
  44.             if (dup2(fd2[1],STDOUT_FILENO) != STDOUT_FILENO)
  45.                 err_sys("dup2 error to stdout ");
  46.             close( fd2[1]);
  47.         }
  48.         if (execl("./add","add",(char *) 0) < 0)
  49.             err_sys("execl error");
  50.     }
  51.         exit(0);
  52. }
  53.     
  54.     static void
  55.         sig_pipe(int signo){
  56.             printf("sigpipe caught \n");
  57.             exit(1);
  58.         }
如果这时直接编译程序,程序陷入死循环,
修改如下

点击(此处)折叠或打开

  1. #include "apue.h"
  2. int main(void)
  3. {
  4.     int int1,int2;
  5.     char line[MAXLINE];
  6.     if (setvbuf(stdin,NULL,_IOLBF,0) != 0)
  7.         err_sys("setvbuf error");
  8.     if (setvbuf(stdout,NULL,_IOLBF,0) != 0)
  9.         err_sys("servbuf error");
  10.     while ( fgets(line,MAXLINE,stdin) != NULL ) {     /* std io  buffer */
  11.         if (sscanf(line,"%d%d",&int1,&int2) == 2 ){
  12.             if (printf("%d\n",int1+int2) == EOF)
  13.                 err_sys("printf error ");
  14.         } else {
  15.             if (printf("invalid args\n") == EOF)
  16.                 err_sys("printf error ");
  17.         }
  18.     }
  19.         exit(0);
  20.     
  21. }

程序恢复正常,出现问提的原因在于求个程序使用的输入的缓冲区是不同的,
对标准输入的第一个fgets一起标准I/O库分配一个缓冲区看,并选择缓冲区的类型。因为标准输入的管道式一个管道,所以标准I/O库有系统默认是全缓冲的,对标准输出也做同样的处理。当程序进行读取的时候发生阻塞,父进程从管道读时也发生阻塞。
为此需要修改协同进程的缓冲类型,即将全缓冲改为行缓冲,更改缓冲区的类型后程序运行正常。

全缓冲:
只有当缓冲区写满的时候,才执行的读写操作
行缓冲:
在输入输出遇到换行符的时候,标准I/O库执行I/O操作
不带缓冲
标准出错是不缓冲的,即错误信息可以尽快的显示出来


阅读(1601) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~