【问题标题】:multiple read processes of the same pipe can all read the same message [closed]同一管道的多个读取进程都可以读取相同的消息[关闭]
【发布时间】:2013-12-15 16:56:02
【问题描述】:

如果有人知道,我对管道有一些疑问,感谢帮助

一个管道可以同时被多个进程共享,允许这些进程相互交换“消息”。 当同一个管道有多个读进程时,都可以读到同一个消息(只发送一次,不能多份)?

在多线程环境中,进程发送的消息在写入管道时可能已损坏?

感谢收听

【问题讨论】:

  • 第一个问题是的,好的,只有一个答案,但第二个问题甚至不知道答案。多线程的问题.....
  • 如果消息足够长并且在多次写入中发送,那么是的,它可能已损坏。
  • 你为什么这么说?写可以存在多个重复信息或缺少信息,不明白为什么多个线程可以破坏消息?

标签: c unix process pipe


【解决方案1】:

停止思考“消息”。管道接受一个字节序列,您的应用程序完全负责将任何结构分配给该序列。写入管道的每个字节只能读取一次,而不是多次。如果对管道的每次写入都是固定大小并且小于系统指定的数量,则写入将是原子的,并且在写入期间数据不会“损坏”(与其他写入交错)。但是,如果任何读取器正在读取不同大小的块,则数据可能会在读取端交错。 (例如,写入器将 64 个字节作为一个“消息”写入,但读取器从管道中读取 60 个字节。期望 64 字节序列的读取器随后将从一个的尾部获得 4 个字节,从另一个的开头获得 60 个字节,并且您的数据可能会出现“损坏”)。在多线程环境中很容易得到“损坏”的数据。可以确保没有任何写入是交错的,但很难做到正确。保持消息小且大小固定,并确保使用单个 write 系统调用写入消息(例如,不要在 FILE* 上使用 fprintf,管道作为底层文件描述符。)

请注意,我始终在引号中使用“损坏”一词,因为我相信您的真正意思是交错。从系统的角度来看,您写入的字节序列不会损坏。您可能无法取回您期望的结果,但这不是数据损坏。相反,这是一个编程错误。

【讨论】:

  • 已经感谢您的帮助。我想我理解这个想法,什么时候可以读取不一致的数据。不保证数据的一致性。但是即使是现在,在这种情况下是否有多个线程或多个进程也无关紧要吗?当我们有多个进程或线程同时读取而不互斥时,就会发生此问题。
  • 如果你有两个线程,一个在两个单独的写入中写入'a','b',另一个在两个单独的写入中写入'c','d'并且你不同步,那么您可能会得到以下任何一种:abcd、acbd、acdb、cdab、cadb 或 cdab。操作系统保证从管道读取的数据按照写入的顺序读取。但是,如果线程 1 在一次写入中写入“ab”,而线程 2 在一次写入中写入“cd”,您可能会得到“abcd”或“cdab”。保证了一致性,但只有当写入小于 PIPE_BUF 字节时,才能保证原子性。
  • 你知道读者是如何知道它何时读完的吗(消息框架语义)?例如,如果我写了a,然后是b,然后是c。然后我运行cat named_pipe,它只返回a,然后关闭。它怎么知道“消息”在a 而不是abc 终止?是否使用空字符?是 EOF 字符还是其他字符?
  • @CMCDragonkai 听起来您在每次写入后都在关闭管道。
  • 你检查写入成功了吗?如果你关闭一个fifo,然后重新打开它,你应该得到所有的数据。但是没有消息框架。如果你成功地写了'a'然后'b',它与你写'ab'没有什么不同,除了在第一种情况下某些其他进程可能会写交错数据。
猜你喜欢
  • 1970-01-01
  • 2015-04-20
  • 2016-06-04
  • 2015-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-17
  • 1970-01-01
相关资源
最近更新 更多