比较Unix / Linux IPC
Unix / Linux提供了许多IPC:pipe道,套接字,共享内存,dbus,消息队列…
什么是最合适的应用程序,他们如何执行?
Unix IPC
大七:
-
pipe
仅在与父母/子女相关的过程中有用。 呼叫
pipe(2)
和fork(2)
。 单向。 -
FIFO或命名pipe道
不同于普通pipe道,两个不相关的进程可以使用FIFO。 致电
mkfifo(3)
。 单向。 -
套接字和Unix域套接字
双向的。 意味着networking通信,但也可以在本地使用。 可以用于不同的协议。 TCP没有消息边界。 调用
socket(2)
。 -
消息队列
操作系统维护离散消息 请参阅sys / msg.h。
-
信号
信号发送一个整数到另一个进程。 不能很好地与multithreading配合。 致电
kill(2)
。 -
信号
多进程或线程的同步机制,类似于等待浴室的人员队列。 请参阅sys / sem.h。
-
共享内存
做你自己的并发控制。 调用
shmget(2)
。
消息边界问题
在select一种方法时,一个决定因素是消息边界问题。 你可能期望“消息”是相互分离的,但不是像TCP或Pipe这样的字节stream。
考虑一对回声客户端和服务器。 客户端发送string,服务器收到它并马上发送。 假设客户端发送“你好”,“你好”和“如何回答?”。
使用字节stream协议,服务器可以接收“地狱”,“你好”,“关于答案? 或更现实的“HelloHelloHow有关答案?”。 服务器不知道消息边界的位置。
一个古老的技巧是将消息长度限制为CHAR_MAX
或UINT_MAX
并同意首先在char
或uint
发送消息长度。 所以,如果你在接收方,你必须先读取消息长度。 这也意味着一次只能有一个线程正在读取消息。
对于像UDP或消息队列这样的离散协议,您不必担心这个问题,但是通过编程方式,字节stream更容易处理,因为它们的行为与文件和stdin / out相同。
共享内存可以是最有效的,因为你build立自己的通信scheme,但它需要很多的照顾和同步。 解决scheme也可用于将共享内存分发给其他机器。
现在套接字是最便携的,但是比pipe道需要更多的开销。 透明地在本地或通过networking使用套接字的能力是一个巨大的好处。
消息队列和信号对于硬实时应用程序来说可能很好,但它们并不灵活。
这些方法自然是为进程之间的通信创build的,在进程中使用多个线程会使事情复杂化,特别是对于信号。
这是一个简单的基准网页: https : //sites.google.com/site/rikkus/sysv-ipc-vs-unix-pipes-vs-unix-sockets
据我所知,每个人都有自己的优势:
- pipe道I / O是最快的,但需要父母/子女关系才能工作。
- Sysv IPC具有已定义的消息边界,可以在本地连接不同的进程。
- UNIX套接字可以在本地连接不同的进程,并具有更高的带宽,但没有固有的消息边界。
- 即使通过networking,TCP / IP套接字也可以连接任何进程,但开销较高,没有固有的消息边界。
值得注意的是,许多图书馆将一种事物放在另一种事物的上面。
共享内存不需要使用可怕的sysv共享内存函数 – 使用mmap()(如果需要的话,可以使用mmap在tmpfs / dev / shm中的文件;如果你想要的话,可以使用mmap / dev / zero分支不exec'd进程匿名inheritance)。 话虽如此,它仍然留下您的进程需要同步,以避免问题 – 通常通过使用其他一些IPC机制来访问共享内存区域的同步。