【发布时间】:2010-09-29 02:38:08
【问题描述】:
Unix/Linux 提供了许多 IPC:管道、套接字、共享内存、dbus、消息队列...
最适合每个应用程序的应用程序是什么,它们的性能如何?
【问题讨论】:
-
dbus 是在其他 IPC 类型之上实现的:unix 域套接字、TCP/IP 和管道……
Unix/Linux 提供了许多 IPC:管道、套接字、共享内存、dbus、消息队列...
最适合每个应用程序的应用程序是什么,它们的性能如何?
【问题讨论】:
这是七大:
FIFO,或命名管道
与普通管道不同,两个不相关的进程可以使用 FIFO。致电mkfifo(3)。单向。
双向。用于网络通信,但也可以在本地使用。可用于不同的协议。 TCP 没有消息边界。致电socket(2)。
操作系统维护离散消息。见sys/msg.h。
信号向另一个进程发送一个整数。不能很好地与多线程啮合。致电kill(2)。
一种多进程或多线程的同步机制,类似于排队等候洗手间的人。见sys/sem.h。
做你自己的并发控制。致电shmget(2)。
选择一种方法而不是另一种方法时的一个决定因素是消息边界问题。您可能希望“消息”彼此分离,但它不适用于 TCP 或 Pipe 这样的字节流。
考虑一对回显客户端和服务器。客户端发送字符串,服务器接收并立即发送回。假设客户端发送“Hello”、“Hello”和“How about an answer?”。
使用字节流协议,服务器可以接收“Hell”、“oHelloHow”和“about an answer?”;或者更现实地说“你好你好,答案怎么样?”。服务器不知道消息边界在哪里。
一个古老的技巧是将消息长度限制为CHAR_MAX 或UINT_MAX,并同意在char 或uint 中首先发送消息长度。因此,如果您在接收方,则必须先阅读消息长度。这也意味着一次只能有一个线程读取消息。
使用 UDP 或消息队列等离散协议,您不必担心这个问题,但以编程方式处理字节流更容易,因为它们的行为类似于文件和标准输入/输出。
【讨论】:
共享内存可能是最有效的,因为您可以在其上构建自己的通信方案,但它需要非常小心和同步。解决方案也可用于将共享内存分配给其他机器。
如今,套接字是最便携的,但比管道需要更多的开销。能够在本地或通过网络透明地使用套接字是一个很大的好处。
消息队列和信号非常适合硬实时应用程序,但它们不够灵活。
这些方法自然是为进程之间的通信而创建的,在一个进程中使用多个线程会使事情变得复杂——尤其是信号。
【讨论】:
值得注意的是,许多库在另一种之上实现了一种类型的东西。
共享内存不需要使用可怕的 sysv 共享内存函数 - 使用 mmap() 会更优雅(如果你想要命名,则将文件 mmap 到 tmpfs /dev/shm;mmap /dev/zero如果您希望分叉未执行的进程匿名继承它)。话虽如此,它仍然让您的进程需要同步以避免问题 - 通常通过使用其他一些 IPC 机制来同步访问共享内存区域。
【讨论】:
这是一个带有简单基准的网页:https://sites.google.com/site/rikkus/sysv-ipc-vs-unix-pipes-vs-unix-sockets
据我所知,各有优势:
【讨论】: