C 管道上的多次读取和写入

C 管道上的多次读取和写入,c,unix,operating-system,pipe,C,Unix,Operating System,Pipe,我不太清楚管道是如何工作的。对于下面的程序。父进程向管道写入两次,子进程从管道读取两次,但在第二次读取时,子进程似乎只读取一个字符。这个 程序的输出为: [2297]:我的bufin是{empty},我的bufout是{hello} [2298]:我的bufin是{a},我的bufout是{hello} 为什么子进程的bufin是a而不是//aaa #include <stdio.h> #include <string.h> #include <unistd.h&g

我不太清楚管道是如何工作的。对于下面的程序。父进程向管道写入两次,子进程从管道读取两次,但在第二次读取时,子进程似乎只读取一个字符。这个 程序的输出为:

[2297]:我的bufin是{empty},我的bufout是{hello}

[2298]:我的bufin是{a},我的bufout是{hello}

为什么子进程的bufin是a而不是//aaa

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#define BUFSIZE 10

int main( void ) {
   char bufin[ BUFSIZE ] = "empty";
   char bufout[] = "hello";
   char b[] = "//aaa";
   int bytesin;
   pid_t childpid;
   int fd[ 2 ];
   if ( pipe( fd ) == -1 ) {
      perror( "Failed to create the pipe" );
      return 1;
   }
   bytesin = strlen( bufin );
   childpid = fork();
   if ( childpid == -1 ) {
      perror( "Failed to fork" );
      return 1; 
   }
   if ( childpid ) {      /* parent code */
      // Parent node write to the pipe.       
      write( fd[ 1 ], bufout, strlen( bufout ) + 1 );
      write( fd[ 1 ], b, strlen(b) + 1 ); // Just for trying
   }
   else {                 /* child code */
      bytesin = read( fd[ 0 ], bufin, BUFSIZE );
      bytesin = read( fd[ 0 ], bufin, BUFSIZE );  // Just for trying  
   }    
   fprintf(stderr, "[%ld]:my bufin is {%.*s}, my bufout is {%s}\n",
           (long)getpid(), bytesin, bufin, bufout);
   return 0; 
}
#包括
#包括
#包括
#包括
#定义BUFSIZE 10
内部主(空){
char bufin[BUFSIZE]=“空”;
char bufout[]=“你好”;
字符b[]=“//aaa”;
int-bytesin;
pid_t childpid;
int-fd[2];
如果(管道(fd)=-1){
perror(“未能创建管道”);
返回1;
}
bytesin=strlen(bufin);
childpid=fork();
if(childpid==-1){
perror(“未能分叉”);
返回1;
}
if(childpid){/*父代码*/
//父节点写入管道。
写入(fd[1],bufout,strlen(bufout)+1);
write(fd[1],b,strlen(b)+1);//仅供尝试
}
else{/*子代码*/
bytesin=读取(fd[0],bufin,BUFSIZE);
bytesin=read(fd[0],bufin,BUFSIZE);//仅供尝试
}    
fprintf(stderr,“[%ld]:我的bufin是{%.*s},我的bufout是{%s}\n”,
(long)getpid(),bytesin,bufin,bufout);
返回0;
}

在first read中,您要求字节的大小,因此read得到“hello\0//aa”(正好10个字符)。当您打印此文件时,您只会看到“hello”,因为后面有空字符。唯一剩下的要读的字符是一个“a”字母,您在第二次阅读后会看到它。此外,您还忘记了关闭父级和子级中未使用的管道末端。请参阅关于管道的非常好的指南:

在first read中,您要求字节的大小,因此read得到“hello\0//aa”(正好10个字符)。当您打印此文件时,您只会看到“hello”,因为后面有空字符。唯一剩下的要读的字符是一个“a”字母,您在第二次阅读后会看到它。此外,您还忘记了关闭父级和子级中未使用的管道末端。请参阅关于管道的非常好的指南:

如果您打印两次读取的结果,这将更有意义。当你不明白发生了什么时,故意对自己隐藏信息可能不是一个好主意。(也就是说,如果你把NULs写到管道的一端,你应该期望在另一端读它们。这意味着你读的缓冲区可能有中间的NULs,而不是NUL终止的。这也是一个提示。)如果你打印两个读的结果,这将更有意义。当你不明白发生了什么时,故意对自己隐藏信息可能不是一个好主意。(也就是说,如果你把NULs写到管道的一端,你应该期望在另一端读它们。这意味着你读到的缓冲区可能有中间的NULs,而不是NUL终止的。这也是一个提示。)