FIFO(命名管道)消息传送障碍

发布于 2024-07-22 17:17:07 字数 400 浏览 5 评论 0原文

我计划使用 Unix 命名管道 (mkfifo) 进行简单的多进程消息传递。 消息只是一行文本。

你会阻止我这样做吗? 我应该期待哪些障碍?

我注意到了这些限制:

  1. 发送者在收到消息之前无法继续。
  2. 接收器被阻塞,直到有一些数据为止。 需要非阻塞 IO 当我们需要停止阅读时。 例如,另一个线程可能会要求这样做。
  3. 接收者可以在一次读取中获得许多消息。 这些都需要处理 在戒烟之前。
  4. 原子消息的最大长度限制为 4096 字节。 这是 Linux 上的 PIPE_BUF 限制(请参阅 man 7 pipeline)。

我将用 Python 实现消息传递。 但总体而言,障碍依然存在。

I plan to use Unix named pipes (mkfifo) for simple multi-process messaging.
A message would be just a single line of text.

Would you discourage me from that? What obstacles should I expect?

I have noticed these limitations:

  1. A sender cannot continue until the message is received.
  2. A receiver is blocked until there are some data. Nonblocking IO would be needed
    when we need to stop the reading. For example, another thread could ask for that.
  3. The receiver could obtain many messages in a single read. These have to be processed
    before quiting.
  4. The max length of an atomic message is limited by 4096 bytes. That is the PIPE_BUF limit on Linux (see man 7 pipe).

I will implement the messaging in Python. But the obstacles hold in general.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

执手闯天涯 2024-07-29 17:17:07
  1. 缺乏可移植性——它们主要是 Unix 的东西。 插座更加便携。
  2. 更难扩展到多个系统(另一个套接字+)
  3. 另一方面,我相信对于同一台机器上的进程来说,管道比套接字更快(通信开销更少)。

至于您的限制,

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

我发现 perlipc 是一个很好的讨论各种选项,尽管它有 perl 特定代码。

  1. Lack of portability - they are mainly a Unix thing. Sockets are more portable.
  2. Harder to scale out to multiple systems (another sockets+)
  3. On the other hand, I believe pipes are faster than sockets for processes on the same machine (less communication overhead).

As to your limitations,

  1. You can "select" on pipes, to do a non-blocking read.
  2. I normally (in perl) print out my messages on pipes seperated by "\n", and read a line from them to get one message at a time.
  3. Do be careful with the atomic length.

I find perlipc to be a good discussion between the various options, though it has perl specific code.

老旧海报 2024-07-29 17:17:07

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

FIFO 的进一步限制:

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

我会使用 UNIX 域套接字 来代替,它没有上述限制。

作为一个额外的好处,如果您想扩展它以在多台机器之间进行通信,则几乎不需要任何更改。 例如,只需查看 socket 上的 Python 文档页面并替换 < code>socket.AF_INET 与 socket.AF_UNIX(HOST, PORT)filename,并且它可以正常工作

SOCK_STREAM 将为您提供类似流的行为; 也就是说,两个发送可以合并为一个接收,反之亦然。 AF_UNIX 还支持 SOCK_DGRAM:保证数据报全部作为一个单元发送和读取,或者根本不发送和读取。 (类似地,AF_INET+SOCK_STREAM=TCP,AF_INET+SOCK_DGRAM=UDP。)

The blocking, both on the sender side and the receiver side, can be worked around via non-blocking I/O.

Further limitations of FIFOs:

  • Only one client at a time.
  • After the client closes the FIFO, the server need to re-open its endpoint.
  • Unidirectional.

I would use UNIX domain sockets instead, which have none of the above limitations.

As an added benefit, if you want to scale it to communicate between multiple machines, it's barely any change at all. For example, just take the Python documentation page on socket and replace socket.AF_INET with socket.AF_UNIX, (HOST, PORT) with filename, and it just works.

SOCK_STREAM will give you stream-like behavior; that is, two sends may be merged into one receive or vice versa. AF_UNIX also supports SOCK_DGRAM: datagrams are guaranteed to be sent and read all as one unit or not at all. (Analogously, AF_INET+SOCK_STREAM=TCP, AF_INET+SOCK_DGRAM=UDP.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文