我计划使用Unix命名管道(mkfifo)进行简单的多进程消息传递 . 消息只是一行文本 .
你会劝阻我吗?我应该期待什么障碍?
我注意到了这些限制:
-
在收到消息之前,发件人无法继续 .
-
接收器被阻塞,直到有一些数据 . 当我们需要停止读取时,将需要非阻塞IO . 例如,另一个线程可能会要求这样做 .
-
接收器可以在一次读取中获得许多消息 . 这些必须在退出之前处理 .
-
原子消息的最大长度限制为4096字节 . 这是Linux上的PIPE_BUF限制(参见man 7 pipe) .
我将在Python中实现消息传递 . 但总体上存在障碍 .
2 回答
缺乏可移植性 - 它们主要是Unix的东西 . 套接字更便于携带 .
难以扩展到多个系统(另一个套接字)
另一方面,我认为管道比同一台机器上的进程的套接字更快(通信开销更少) .
至于你的局限,
你可以在管道上“select”进行非阻塞读取 .
我通常(在perl中)在"\n"分隔的管道上打印我的消息,并从中读取一行以一次获得一条消息 .
小心原子长度 .
我发现perlipc是各种选项之间的一个很好的讨论,尽管它有perl特定的代码 .
发送方和接收方都可以通过非阻塞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 . )