FIFO(命名管道)消息传递障碍
我打算使用Unix命名管道(mkfifo)来进行简单的多进程消息传递。消息就是一行简单的文本。
你会建议我不要这样做吗?我应该预期会遇到哪些困难呢?
我注意到了一些限制:
- 发送方在消息被接收之前不能继续发送。
- 接收方在没有数据到达之前会被阻塞。我们需要使用非阻塞输入输出,这样才能在需要停止读取时处理。例如,另一个线程可能会请求停止。
- 接收方在一次读取中可能会获取到很多消息。这些消息必须在退出之前处理完。
- 一个原子消息的最大长度限制为4096字节。这是Linux上的PIPE_BUF限制(可以查看man 7 pipe了解更多)。
我会用Python来实现这个消息传递功能。但这些困难是普遍存在的。
2 个回答
4
在发送方和接收方都可能出现的阻塞问题,可以通过非阻塞输入输出(I/O)来解决。
关于FIFO(先进先出队列)的进一步限制:
- 一次只能有一个客户端连接。
- 当客户端关闭FIFO后,服务器需要重新打开它的端点。
- 数据传输是单向的。
我会推荐使用UNIX域套接字,因为它没有上述的这些限制。
另外一个好处是,如果你想让它能够在多台机器之间进行通信,几乎不需要做任何改动。比如,只需在Python的文档页面上找到socket的例子,把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。)