进程间通信共享内存 - 比较Unix/Linux IPC




进程间通信信号 (3)

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

每个应用程序最适合哪些应用程序?它们如何执行?


Unix IPC

以下是大七:

  1. Pipe

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

  2. FIFO或命名管道

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

  3. SocketUnix域套接字

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

  4. 消息队列

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

  5. Signal

    信号发送一个整数到另一个进程。 与多线程不匹配。 致电kill(2)

  6. Semaphore

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

  7. 共享内存

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

消息边界问题

在选择一种方法时,一个决定因素是消息边界问题。 您可能希望“消息”彼此不相关,但不适用于像TCP或Pipe这样的字节流。

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

使用字节流协议,服务器可以接收“地狱”,“oHelloHow”和“关于答案?”; 或更现实的“HelloHelloHow如何回答?”。 服务器不知道消息边界在哪里。

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

对于像UDP或消息队列这样的离散协议,您不必担心这个问题,但编程字节流更容易处理,因为它们的行为与文件和stdin / out相同。


值得注意的是,许多库实现了另一种类型的事物。

共享内存不需要使用可怕的sysv共享内存函数 - 使用mmap()会更加优雅(如果需要,可以使用mmap在tmpfs / dev / shm中创建一个文件;如果需要,可以使用mmap / dev / zero)而不是可执行进程匿名继承)。 话虽如此,它仍然会让您的进程需要一些同步以避免出现问题 - 通常通过使用某些其他IPC机制来同步访问共享内存区域。


这是一个简单基准的网页: https://sites.google.com/site/rikkus/sysv-ipc-vs-unix-pipes-vs-unix-socketshttps://sites.google.com/site/rikkus/sysv-ipc-vs-unix-pipes-vs-unix-sockets

据我所知,每个人都有自己的优势:

  • 管道I / O最快,但需要父母/子女关系才能工作。
  • Sysv IPC具有定义的消息边界,可以在本地连接不同的进程。
  • UNIX套接字可以在本地连接不同的进程,并具有更高的带宽,但没有固有的消息边界。
  • 即使通过网络,TCP / IP套接字也可以连接任何进程,但开销较高,并且没有固有的消息边界。




ipc