比较Unix / Linux IPC

Unix / Linux提供了许多IPC:pipe道,套接字,共享内存,dbus,消息队列…

什么是最合适的应用程序,他们如何执行?

Unix IPC

大七:

  1. pipe

    仅在与父母/子女相关的过程中有用。 呼叫pipe(2)fork(2) 。 单向。

  2. FIFO或命名pipe道

    不同于普通pipe道,两个不相关的进程可以使用FIFO。 致电mkfifo(3) 。 单向。

  3. 套接字和Unix域套接字

    双向的。 意味着networking通信,但也可以在本地使用。 可以用于不同的协议。 TCP没有消息边界。 调用socket(2)

  4. 消息队列

    操作系统维护离散消息 请参阅sys / msg.h。

  5. 信号

    信号发送一个整数到另一个进程。 不能很好地与multithreading配合。 致电kill(2)

  6. 信号

    多进程或线程的同步机制,类似于等待浴室的人员队列。 请参阅sys / sem.h。

  7. 共享内存

    做你自己的并发控制。 调用shmget(2)

消息边界问题

在select一种方法时,一个决定因素是消息边界问题。 你可能期望“消息”是相互分离的,但不是像TCP或Pipe这样的字节stream。

考虑一对回声客户端和服务器。 客户端发送string,服务器收到它并马上发送。 假设客户端发送“你好”,“你好”和“如何回答?”。

使用字节stream协议,服务器可以接收“地狱”,“你好”,“关于答案? 或更现实的“HelloHelloHow有关答案?”。 服务器不知道消息边界的位置。

一个古老的技巧是将消息长度限制为CHAR_MAXUINT_MAX并同意首先在charuint发送消息长度。 所以,如果你在接收方,你必须先读取消息长度。 这也意味着一次只能有一个线程正在读取消息。

对于像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机制来访问共享内存区域的同步。