【问题标题】:Break a while loop that reads from fifo channel中断从 fifo 通道读取的 while 循环
【发布时间】:2012-10-11 10:51:38
【问题描述】:

我必须在 UNIX 中模拟 C 程序中的 shell 行为,记住一件重要的事情:父进程接收所有命令并将它们发送给子进程。然后孩子执行收到的命令,然后将输出发送给父亲。 这个想法是我从父母和我的主要孩子 fork() 收到命令,以便他自己的孩子可以执行命令并将输出发送到 fifo 管道。问题是我无法打破 while 循环(打印正确的输出):

mkfifo("output",S_IFIFO|0644);
while(read(fifod2,&c,1))
      printf("%c",c);

我意识到fifo的大小是可变的,但是第二个孩子在终止时必须发送一个EOF,所以当读取到达它时,返回0。但这似乎没有发生。 如果需要,请向我索取更多代码部分。 谢谢

【问题讨论】:

  • read() 可能会失败,状态 -1 表示错误。这不会打破循环。在这种情况下,您应该测试while (read(fifod, &c, 1) == 1),尽管您可能应该使用批量输入:while ((nbytes = read(fifod, buffer, sizeof(buffer)) > 0) 来一次处理尽可能多的数据。这不会等待 FIFO 填满;如果这就是所有可用的,它将返回一个“短读”(比指定的最大值少的字节)。它将减少系统负载——单字节 I/O 是可行的,但效率不高(尽管效率也不是低得离谱)。
  • 另外,请注意mkfifo() 创建了一个特殊类型的文件;它不会打开它进行阅读或写作。正如 bdonlan 建议的那样,如果在任何进程中的 FIFO 上打开了可写文件文件描述符,则可能会出现无法在 FIFO 上获取 EOF 的问题。要非常小心 FIFO 的实际打开位置以及打开方式。

标签: c unix while-loop fifo


【解决方案1】:

因为父进程用O_RDWR打开了fifo的末尾,所以总是有一个进程对fifo有一个可写的文件描述符。 EOF 仅在 fifo 没有可写 fd 时发生,因此由于父进程保持此类可写 fd 处于打开状态,因此它永远不会获得 EOF。

尝试在父级中使用O_RDONLY 打开。

【讨论】:

  • 主子代码:int fifod2=open("output",O_RDWR);次要子代码是相同的......父母不知道管道。
  • @IonutGo​​ldan,这还不够。为了确定这是否真的是这种情况,我需要查看从第一次调用 open 通过 fork 到您在上面打印的循环的整个代码路径。如果您不知道出了什么问题,请不要删除 99% 的程序,因为您完全有可能删除过程中的错误。
  • dup2(fifod2,1); execvp(*argum,argum);这就是第二个孩子所做的
  • 我不能把我的代码放到网上,因为它是一个家庭作业项目。上面的代码让我很困惑:在 execvp 之后,第二个孩子是否发送 EOF?解析命令或执行命令绝对没有问题......只是读取继续进行而不停止,只返回严格的正值......
  • 并在所有写入文件句柄关闭时发送 EOF。或者更准确地说,如果您在没有数据等待且没有写入文件句柄的情况下尝试读取,则会得到 EOF。
猜你喜欢
  • 2013-05-14
  • 2017-09-12
  • 2013-07-01
  • 2011-11-10
  • 2021-05-22
  • 1970-01-01
  • 2022-01-21
  • 2014-06-26
  • 2011-03-05
相关资源
最近更新 更多