2009-05-29 192 views
2

我打算使用Unix命名管道(mkfifo)进行简单的多进程消息传递。 消息将只是一行文本。FIFO(命名管道)消息障碍

你会让我感到厌恶吗?我应该期待什么障碍?

我已经注意到了这些限制:

  1. 发送方无法继续进行直到收到消息。
  2. 接收器被阻塞,直到有一些数据。当我们需要停止阅读时,非阻塞IO将需要 。例如,另一个线程可以要求。
  3. 接收器可以在一次读取中获得许多消息。这些在退出前必须被处理 。
  4. 原子消息的最大长度受限于4096个字节。这是Linux上的PIPE_BUF限制(请参见man 7 pipe)。

我将在Python中实现消息传递。但是障碍总的来说是一样的。

+0

您希望同时使用多少个进程?如果您有多个读者,则只有其中一位读者可以看到书面信息,AFAIR。 (在这一个不是100%肯定) – rodion 2009-05-29 17:50:53

+0

@rodion - 是的,它只是在一个阅读器中看到一条消息。 FIFO以这种方式工作。 – 2009-05-29 18:09:30

+0

为什么要阻止问题?我可以看到一个非阻塞写入。当你在等待工作时,我看不到无阻塞的阅读。 – 2009-05-29 18:29:15

回答

5
  1. 缺乏可移植性 - 它们主要是Unix的东西。套接字更便携。
  2. 难以扩展到多个系统(另一个插座+)
  3. 另一方面,我相信管道比同一台机器上的进程的套接字更快(通信开销更少)。

至于你的限制,

  1. 可以 “select” 的管道,做非阻塞读。
  2. 我通常(在perl中)打印出由“\ n”分隔的管道上的消息,并从中读取一行消息以获得一条消息。
  3. 请注意原子长度。

我发现perlipc是各种选项之间的一个很好的讨论,虽然它有Perl特定的代码。

3

发送方和接收方的阻塞都可以通过非阻塞I/O来解决。

的FIFO的进一步限制:

  • 在同一时间只有一个客户端。
  • 客户端关闭FIFO后,服务器需要重新打开其端点。
  • 单向。

我会用UNIX domain sockets代替,它没有上述限制。

作为一个额外的好处,如果你想扩展它在多台机器之间进行通信,它几乎没有任何改变。例如,只需参阅socket上的Python文档页面,并用socket.AF_UNIX,(HOST, PORT)filename替换socket.AF_INET,并且它仅适用于

SOCK_STREAM会给你流式的行为;也就是说,两次发送可能合并为一次接收,反之亦然。 AF_UNIX也支持SOCK_DGRAM:数据报被保证发送和阅读所有作为一个单位或根本没有。 (类似地,AF_INET + SOCK_STREAM = TCP,AF_INET + SOCK_DGRAM = UDP。)