【发布时间】:2016-11-15 20:20:48
【问题描述】:
我正在尝试为我的 Linux 守护进程编写一些 IPC 机制以与其他进程通信。我一直在研究主要是管道来执行此操作,因为它比套接字更可靠。但是现在我有一个问题,是否可以通过管道进行数据报连接?
目前我正在做这样的事情(为了清楚起见,删除了错误处理):
mkfifo("path/to/named/pipe1", 0660);
int ret_fd = open("path/to/named/pipe1", O_RDONLY | O_NONBLOCK);
对于套接字,我可以这样做:
sockaddr_un sock;
sock.sun_family = AF_UNIX;
sprintf(sock.sun_path, "path/to/named/pipe1");
unlink(sock.sun_path);
int ret_fd = socket(AF_UNIX, SOCK_DGRAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0); //maybe SOCK_SEQPACKET is better/more reliable
bind(ret_fd, (sockaddr*)(&sock), sizeof(sock));
为了清楚起见,我主要关心消息边界,以确保在收到读取和读取信号时收到完整的数据包。
【问题讨论】:
-
Unix 域套接字是可靠的。管道比套接字更可靠是什么意思?
-
主要是从我看到的阅读和对话中看到的。我认为这与套接字的丢包和缓冲区大小限制有关。
-
在实际网络上可能会出现这种情况,但在本地计算机上,套接字应该非常可靠。您还考虑过使用共享内存或其他 IPC 解决方案吗?
-
我做了,但归结为使用管道或套接字进行设计。
-
@davmac - Linux
man 7 pipe说:POSIX.1 说小于 PIPE_BUF 字节的 write(2)s 必须是原子的: 输出数据是作为连续序列写入管道。。重点补充。以下句子阐明了此处“原子”的含义:超过 PIPE_BUF 字节的写入可能是非原子的:内核可能将数据与其他进程写入的数据交错。