我正在尝试选择pipes and Unix 套接字对于IPC机制。
两者都支持select()
and epoll()
功能很棒。
现在,管道具有 4kB(截至今天)的“原子”写入,这是由 Linux 内核保证的。
unix 套接字是否存在这样的功能?我找不到任何文件明确说明这一点。
假设我使用 UNIX 套接字并从客户端写入 x 字节的数据。我确定当我的服务器启动时,这些 x 字节将被写入套接字的服务器端吗?select()
cracks?
在同一主题上,使用 SOCK_DGRAM 确保写入是原子的(如果这样的保证是可能的),因为数据报应该be单个明确定义的消息?
那么使用 SOCK_STREAM 作为传输模式会有什么区别呢?
提前致谢。
Pipes
是的,非阻塞容量通常为 4KB,但为了获得最大的可移植性,您可能最好使用PIPE_BUF
持续的。另一种方法是使用非阻塞 I/O。
比您想了解的更多信息man 7 pipe
.
Unix 数据报套接字
写入使用send
数据报套接字上的函数系列确实可以保证atomic。对于 Linux,它们也很可靠,并且保留顺序。 (这使得最近推出的SOCK_SEQPACKET
对我来说有点困惑)有关此的很多信息man 7 unix
.
The 最大数据报大小是套接字相关的。它的访问使用getsockopt/setsockopt
on SO_SNDBUF
。在 Linux 系统上,它的范围在 2048 到wmem_max
,默认为wmem_default
。例如在我的系统上,wmem_default = wmem_max = 112640
。 (你可以从/proc/sys/net/core
)与此相关的最相关文档位于man 7 socket
周围的SO_SNDBUF
选项。我建议您自己阅读它,因为它描述的容量加倍行为一开始可能会有点令人困惑。
流和数据报之间的实际差异
流套接字仅在连接状态下工作。这主要意味着他们一次只能与一个同伴通信。作为流,它们不能保证保留“消息边界”。
数据报套接字已断开。他们(理论上)可以同时与多个对等方进行通信。它们保留消息边界。
[我认为新SOCK_SEQPACKET
介于:连通和边界保持之间。]
在 Linux 上,两者都是可靠的并且保留消息顺序。如果您使用它们来传输流数据,它们的性能往往相似。因此,只需使用与您的流程相匹配的那个,并让内核为您处理缓冲。
比较流、数据报和管道的粗略基准:
# unix stream 0:05.67
socat UNIX-LISTEN:u OPEN:/dev/null &
until [[ -S u ]]; do :;done
time socat OPEN:large-file UNIX-CONNECT:u
# unix datagram 0:05.12
socat UNIX-RECV:u OPEN:/dev/null &
until [[ -S u ]]; do :;done
time socat OPEN:large-file UNIX-SENDTO:u
# pipe 0:05.44
socat PIPE:p,rdonly=1 OPEN:/dev/null &
until [[ -p p ]]; do :;done
time socat OPEN:large-file PIPE:p
这里没有任何统计意义。我的瓶颈可能是读取大文件。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)