【问题标题】:Processes hang on read进程挂起读取
【发布时间】:2011-11-15 02:52:26
【问题描述】:

以下代码通过管道从其他进程读取消息。所有进程都正确打印出所有消息,但它们将永远不会经过 while 循环。尝试在Eclipse中调试,读取所有消息后,它会在那个while循环处停止。

索引是分配给每个进程的数字。第一个进程的索引 == 0。 消息本身就是发送消息的进程的索引。

while((n = read(fd[index][0], &mymsg, sizeof(int))) == sizeof(int))
        printf("process%d  has received a message from process%d\n", index, mymsg);

任何想法为什么会发生这种情况?

这是每个进程写入另一个进程的方式:

// Write to other process
if(write(fd[index2][1], &index, sizeof(int)) != sizeof(int))
    sys_error(2);

这个过程做了五次。 fd 是每个进程的读写端表。

【问题讨论】:

  • 不清楚为什么这不是您所期望的行为。代码应该在什么条件下通过while 循环?
  • @DavidSchwartz 如果它没有读取任何字节或返回错误。
  • 您是否有任何特别的理由期望这些事情发生?如果不是,那为什么要退出while循环呢? (文件描述符是非阻塞的吗?)
  • @DavidSchwartz 每个进程通过管道向随机选择的进程发送 5 条消息。我已经发布了发生写入的代码。
  • 再一次,您是否有任何特殊原因希望它不读取任何字节或返回错误?我还没有听到它应该退出while 循环的任何理由。您的代码似乎完全按照它的编码去做,继续从连接中读取,直到出现错误。没有错误发生,所以它一直在读。 (它怎么知道另一个进程不会向它发送消息?)

标签: c linux unix process ipc


【解决方案1】:

read() 的调用被阻塞,直到出现更多数据。来自man page for pipe

如果一个进程试图从一个空管道中读取,那么 read(2) 将 阻塞直到数据可用。如果一个进程试图写入一个 完整的管道(见下文),然后 write(2) 阻塞,直到有足够的数据 从管道中读取以允许写入完成。非阻塞 I/O 可以通过使用 fcntl(2) F_SETFL 操作来启用 O_NONBLOCK 打开文件状态标志。

在打开每个文件描述符之后,在进入该 while 循环之前对每个文件执行此操作:

fcntl(fd, F_SETFL, O_NONBLOCK);

但是,您确实应该阅读阻塞与非阻塞 I/O,包括阅读管道、读取、fcntl 等的手册页。

【讨论】:

  • 我可以提供一些示例代码吗?我对那个功能不太熟悉。
  • @seljuq70:你试过 fctntl 手册页了吗?我刚刚在 Google 中输入了“fcntl F_SETFL O_NONBLOCK”,并获得了一些示例代码。无论如何,我编辑了我的答案以添加更多信息。
  • 我在阅读之前试过这个:fcntl(fd[index][0], F_SETFL, O_NONBLOCK);由于某种原因,进程 0 不再打印任何内容?
  • 当您切换到非阻塞 I/O 时,您必须不断检查数据。切换到非阻塞 I/O 会影响输入和输出。在继续之前,您真的需要阅读非阻塞 I/O。这不是一个超级复杂的主题,但它不应该在 cmets 上解释
  • 试过了。进程不再挂起,但其中一个进程提前退出。
猜你喜欢
  • 1970-01-01
  • 2016-01-21
  • 1970-01-01
  • 2013-04-13
  • 2023-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多