Comparando el IPC de Unix / Linux

Lotes de IPCs son ofrecidos por Unix / Linux: pipes, sockets, memoria compartida, dbus, colas de mensajes …

¿Cuáles son las aplicaciones más adecuadas para cada uno y cómo funcionan?

Unix IPC

Aquí están los siete grandes:

  1. Tubo

    Útil solo entre procesos relacionados como padre / hijo. Llamar a la pipe(2) y a la fork(2) . Unidireccional

  2. FIFO , o tubería con nombre

    Dos procesos no relacionados pueden usar FIFO a diferencia de la tubería simple. Llamar a mkfifo(3) . Unidireccional

  3. Zócalo y zócalo del dominio de Unix

    Bidireccional Significa para la comunicación de red, pero también se puede usar localmente. Puede ser utilizado para diferentes protocolos. No hay límite de mensajes para TCP. socket(2) llamada socket(2) .

  4. Cola de mensajes

    OS mantiene un mensaje discreto. Ver sys / msg.h.

  5. Señal

    La señal envía un entero a otro proceso. No se combina bien con multi-hilos. Call kill(2) .

  6. Semáforo

    Un mecanismo de sincronización para múltiples procesos o hilos, similar a una cola de personas esperando el baño. Ver sys / sem.h.

  7. Memoria compartida

    Haz tu propio control de concurrencia. Llamar a shmget(2) .

Problema de límite de mensaje

Un factor determinante al elegir un método sobre el otro es el problema del límite del mensaje. Puede esperar que los “mensajes” sean discretos entre sí, pero no para las secuencias de bytes como TCP o Pipe.

Considere un par de echo cliente y servidor. El cliente envía cadena, el servidor la recibe y la envía de vuelta. Supongamos que el cliente envía “Hola”, “Hola” y “¿Qué tal una respuesta?”.

Con los protocolos de transmisión de bytes, el servidor puede recibir como “Infierno”, “oHelloHow” y “¿sobre una respuesta?”; o más realista “HelloHelloHow sobre una respuesta?”. El servidor no tiene idea de dónde está el límite del mensaje.

Un viejo truco es limitar la longitud del mensaje a CHAR_MAX o UINT_MAX y aceptar enviar la longitud del mensaje primero en char o uint . Entonces, si está en el lado de recepción, primero debe leer la longitud del mensaje. Esto también implica que solo un hilo debería estar haciendo el mensaje leyendo a la vez.

Con protocolos discretos como UDP o colas de mensajes, no tiene que preocuparse por este problema, pero las secuencias de bytes programáticamente son más fáciles de tratar porque se comportan como archivos y stdin / out.

La memoria compartida puede ser la más eficiente ya que usted construye su propio esquema de comunicación, pero requiere mucho cuidado y sincronización. También hay soluciones disponibles para distribuir memoria compartida a otras máquinas.

Los sockets son los más portátiles en estos días, pero requieren más gastos generales que las tuberías. La posibilidad de utilizar de forma transparente sockets localmente o en una red es una gran ventaja.

Las colas de mensajes y las señales pueden ser geniales para aplicaciones duras en tiempo real, pero no son tan flexibles.

Estos métodos fueron creados naturalmente para la comunicación entre procesos, y el uso de múltiples hilos dentro de un proceso puede complicar las cosas, especialmente con las señales.

Aquí hay una página web con un punto de referencia simple: https://sites.google.com/site/rikkus/sysv-ipc-vs-unix-pipes-vs-unix-sockets

Por lo que puedo decir, cada uno tiene sus ventajas:

  • Pipe I / O es el más rápido pero necesita una relación padre / hijo para funcionar.
  • Sysv IPC tiene un límite de mensaje definido y puede conectar procesos dispares localmente.
  • Los sockets de UNIX pueden conectar procesos dispares localmente y tienen mayor ancho de banda pero no límites de mensajes inherentes.
  • Los zócalos TCP / IP pueden conectar cualquier proceso, incluso a través de la red, pero tienen una sobrecarga mayor y no tienen límites de mensajes inherentes.

Vale la pena señalar que muchas bibliotecas implementan un tipo de cosa sobre otra.

La memoria compartida no necesita utilizar las horribles funciones de memoria compartida sysv: es mucho más elegante usar mmap () (mmap un archivo en un tmpfs / dev / shm si lo quiere con nombre; mmap / dev / zero si lo desea procesos bifurcados no ejecutados para heredarlo anónimamente). Habiendo dicho eso, todavía deja sus procesos con alguna necesidad de sincronización para evitar problemas, generalmente mediante el uso de algunos de los otros mecanismos de IPC para sincronizar el acceso a un área de memoria compartida.