0

我们正在尝试从提供给多个子进程的管道中读取 char* 数据。
每个子进程将 char* 写入共享管道,父进程从中读取。
我们要做的是解析在 xv6 中运行的子进程的信息。
当解析单个进程时,我们没有任何问题,但是当解析一个对“runcmd”递归调用的管道进程时,会出现以下问题:
我们在父端使用了以下代码:

while(read(p[0],buff,sizeof(buff)) > 0){
  printf(1,"\nprocess from pipe in main: " );
  printf(1,buff);
  printf(1,"\n");
}

在孩子们的最后:

char * name = ecmd->argv[0];
char * data=(char*)malloc(strlen(name)*sizeof(char)+strlen(pidc2)*sizeof(char)+3);
strcpy(data,name);
char* delimiter="#";
strcpy(data+strlen(name),delimiter);
strcpy(data+strlen(name)+strlen(delimiter),pidc2);
strcpy(data+strlen(name)+strlen(delimiter)+strlen(pidc2),"\0");
write(pp[1],data,sizeof(char)*(strlen(data)));

当我们用“ls|cat”运行这段代码时,它会打印:

ls#*some_pid*cat#*some_pid*

而不是从每个孩子那里阅读并打印

ls#*some_pid*
cat#*some_pid*

为什么不单独发送?

4

1 回答 1

0

因为这就是管道的工作方式。在内部,操作系统将来自所有写入器的数据组合成一个流。正如上面的评论所暗示的,您可以让每个写入者插入某种记录分隔符('\0' 或 '\n'),然后让读取过程在分隔符处查找并拆分记录。

我不具体了解 xv6,但传统上类似 unix 的系统已经保证(实际上这是 posix.1 要求)任何低于特定指定长度的消息的写入都是原子的(即,如果两个进程都写入'foo ',读者将看到 'foo foo ' 而不是 'ffooo o ' 或任何其他排列)。

于 2015-03-27T10:50:12.520 回答