- #include "apue.h"
- int main(void)
- {
- int int1,int2;
- char line[MAXLINE];
- while ( fgets(line,MAXLINE,stdin) != NULL ) { /* std io type 全缓冲 */
- if (sscanf(line,"%d%d",&int1,&int2) == 2 ){
- if (printf("%d\n",int1+int2) == EOF)
- err_sys("printf error ");
- } else {
- if (printf("invalid args\n") == EOF)
- err_sys("printf error ");
- }
- }
- exit(0);
-
- }
- #include "apue.h"
- static void sig_pipe(int); /* our signal handler */
- int main(void)
- {
- int n,fd1[2],fd2[2];
- pid_t pid;
- char line[MAXLINE];
- if (signal(SIGPIPE,sig_pipe) == SIG_ERR)
- err_sys("signal error ");
- if ( pipe(fd1) < 0 || pipe(fd2) < 0)
- err_sys("pipe error ");
- if (( pid = fork() ) < 0) {
- err_sys("fork error ");
- } else if ( pid > 0) { /* parent */
- close(fd1[0]);
- close(fd2[1]);
- while( fgets(line,MAXLINE,stdin) != NULL ){
- n = strlen(line);
- if (write(fd1[1],line,n) != n)
- err_sys("write error to pipe");
- if (( n = read(fd2[0],line,MAXLINE)) < 0)
- err_sys("read error form pipe ");
- if ( n == 0 ){
- err_msg("child closed pipe ");
- break;
- }
- line[n] = 0; /* null terminate */
- if (fputs(line,stdout) == EOF )
- err_sys("fputs error");
- break;
- }
- if (ferror(stdin))
- err_sys("fgets error on stdin ");
- exit(0);
- }else { /* child */
- close(fd1[1]);
- close(fd2[0]);
- if (fd1[0] != STDIN_FILENO) {
- if (dup2(fd1[0],STDIN_FILENO) != STDIN_FILENO)
- err_sys("dup2 error to stdin");
- close(fd1[0]);
- }
- if (fd2[1] != STDOUT_FILENO) {
- if (dup2(fd2[1],STDOUT_FILENO) != STDOUT_FILENO)
- err_sys("dup2 error to stdout ");
- close( fd2[1]);
- }
- if (execl("./add","add",(char *) 0) < 0)
- err_sys("execl error");
- }
- exit(0);
- }
-
- static void
- sig_pipe(int signo){
- printf("sigpipe caught \n");
- exit(1);
- }
如果这时直接编译程序,程序陷入死循环,
修改如下
- #include "apue.h"
- int main(void)
- {
- int int1,int2;
- char line[MAXLINE];
- if (setvbuf(stdin,NULL,_IOLBF,0) != 0)
- err_sys("setvbuf error");
- if (setvbuf(stdout,NULL,_IOLBF,0) != 0)
- err_sys("servbuf error");
- while ( fgets(line,MAXLINE,stdin) != NULL ) { /* std io buffer */
- if (sscanf(line,"%d%d",&int1,&int2) == 2 ){
- if (printf("%d\n",int1+int2) == EOF)
- err_sys("printf error ");
- } else {
- if (printf("invalid args\n") == EOF)
- err_sys("printf error ");
- }
- }
- exit(0);
-
- }
程序恢复正常,出现问提的原因在于求个程序使用的输入的缓冲区是不同的,
对标准输入的第一个fgets一起标准I/O库分配一个缓冲区看,并选择缓冲区的类型。因为标准输入的管道式一个管道,所以标准I/O库有系统默认是全缓冲的,对标准输出也做同样的处理。当程序进行读取的时候发生阻塞,父进程从管道读时也发生阻塞。
为此需要修改协同进程的缓冲类型,即将全缓冲改为行缓冲,更改缓冲区的类型后程序运行正常。
全缓冲:
只有当缓冲区写满的时候,才执行的读写操作
行缓冲:
在输入输出遇到换行符的时候,标准I/O库执行I/O操作
不带缓冲
标准出错是不缓冲的,即错误信息可以尽快的显示出来
阅读(1664) | 评论(0) | 转发(0) |