首页 文章

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

提问于
浏览
2

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

你会劝阻我吗?我应该期待什么障碍?

我注意到了这些限制:

  • 在收到消息之前,发件人无法继续 .

  • 接收器被阻塞,直到有一些数据 . 当我们需要停止读取时,将需要非阻塞IO . 例如,另一个线程可能会要求这样做 .

  • 接收器可以在一次读取中获得许多消息 . 这些必须在退出之前处理 .

  • 原子消息的最大长度限制为4096字节 . 这是Linux上的PIPE_BUF限制(参见man 7 pipe) .

我将在Python中实现消息传递 . 但总体上存在障碍 .

2 回答

  • 5
    • 缺乏可移植性 - 它们主要是Unix的东西 . 套接字更便于携带 .

    • 难以扩展到多个系统(另一个套接字)

    • 另一方面,我认为管道比同一台机器上的进程的套接字更快(通信开销更少) .

    至于你的局限,

    • 你可以在管道上“select”进行非阻塞读取 .

    • 我通常(在perl中)在"\n"分隔的管道上打印我的消息,并从中读取一行以一次获得一条消息 .

    • 小心原子长度 .

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

  • 3

    发送方和接收方都可以通过非阻塞I / O解决阻塞问题 .

    FIFO的进一步限制:

    • 一次只能有一个客户 .

    • 客户端关闭FIFO后,服务器需要重新打开其 endpoints .

    • 单向 .

    我会改用UNIX domain sockets,它没有上述限制 .

    作为一个额外的好处,如果你想扩展它以在多台机器之间进行通信,那几乎没有任何变化 . 例如,只需使用socket上的Python文档页面,将 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 . )

相关问题