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