【问题标题】:Multiple reads and writes on the pipe管道上的多次读取和写入
【发布时间】:2025-11-25 09:50:02
【问题描述】:

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

[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; 
}

【问题讨论】:

  • 如果您打印 both 读取的结果,这将更有意义。当您不了解发生了什么时,故意向自己隐藏信息可能不是一个好主意。 (此外,如果您将 NUL 写入管道的一端,您应该期望在另一端读取它们。这意味着您读取的缓冲区可能在中间有 NUL,而不是 NUL 终止的。这是一个提示,也是。)

标签: c unix operating-system pipe


【解决方案1】:

在第一次读取时,您要求 BUFSIZE 字节,因此读取得到 'hello\0//aa'(正好 10 个字符)。当您打印此内容时,您只会看到“你好”,因为之后有 NULL 字符。唯一要阅读的左侧字符是一个“a”字母,您在第二次阅读后会看到。您还忘记了关闭父级和子级中未使用的管道末端。请参考非常好的管道指南:http://beej.us/guide/bgipc/output/html/multipage/pipes.html

【讨论】: