Comparando IPC Unix / Linux

78

Unix / Linux ofrece muchos IPC: canalizaciones, sockets, memoria compartida, dbus, colas de mensajes ...

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

user27424
fuente
1
dbus se implementa sobre los otros tipos de IPC: sockets de dominio unix, TCP / IP y tuberías hacen mucho ...
Juez Maygarden

Respuestas:

100

Unix IPC

Aquí están los siete grandes:

  1. Tubo

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

  2. FIFO o tubería con nombre

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

  3. Socket y Socket de dominio Unix

    Bidireccional. Destinado a la comunicación en red, pero también se puede utilizar localmente. Se puede utilizar para diferentes protocolos. No hay límite de mensaje para TCP. Llame socket(2).

  4. Cola de mensajes

    El sistema operativo mantiene un mensaje discreto. Ver sys / msg.h .

  5. Señal

    Signal envía un número entero a otro proceso. No encaja bien con hilos múltiples. Llame kill(2).

  6. Semáforo

    Un mecanismo de sincronización para multiprocesos o subprocesos, similar a una cola de personas esperando el baño. Ver sys / sem.h .

  7. Memoria compartida

    Haga su propio control de concurrencia. Llame shmget(2).

Problema de límite de mensaje

Un factor determinante a la hora de elegir un método sobre el otro es la cuestión de los límites del mensaje. Puede esperar que los "mensajes" sean distintos entre sí, pero no es para flujos de bytes como TCP o Pipe.

Considere un par de cliente y servidor de eco. El cliente envía una cadena, el servidor la recibe y la envía de vuelta. Suponga que el cliente envía "Hola", "Hola" y "¿Qué tal una respuesta?".

Con los protocolos de flujo de bytes, el servidor puede recibir como "Hell", "oHelloHow" y "about a answer?"; o más realista "Hola, hola, ¿qué tal una respuesta?". El servidor no tiene ni idea de dónde está el límite del mensaje.

Un truco antiguo consiste en limitar la longitud del mensaje a CHAR_MAXo UINT_MAXy aceptar enviar la longitud del mensaje primero en charo uint. Entonces, si está en el lado receptor, primero debe leer la longitud del mensaje. Esto también implica que solo un hilo debería estar leyendo el mensaje a la vez.

Con protocolos discretos como UDP o colas de mensajes, no tiene que preocuparse por este problema, pero los flujos de bytes mediante programación son más fáciles de manejar porque se comportan como archivos y stdin / out.

Eugene Yokota
fuente
Supongo que podría incluir semáforos allí, pero lo veo más como una herramienta de concurrencia que como una herramienta de comunicación entre procesos.
Eugene Yokota
2
Por cierto, puede enviar descriptores de archivos a través de un socket de dominio Unix [ linux.die.net/man/7/unix]
Hasturkun
2
Una nit menor: tubería (2) también se puede usar en procesos hermanos; por ejemplo, el shell es padre de todos los procesos en la tubería.
Hudson
5
Tenga en cuenta que puede tener sockets de dominio Unix orientados a mensajes. A diferencia de los de Internet, son confiables.
Tom Anderson
2
¿Existe un punto de referencia o una comparación de desempeño cualitativa de estos enfoques?
kakyo
17

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

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

Las colas de mensajes y las señales pueden ser excelentes para aplicaciones difíciles en tiempo real, pero no son tan flexibles.

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

Juez Maygarden
fuente
En mi experiencia, las canalizaciones con nombre pueden ser tan rápidas y más seguras que casi cualquier otro método.
Erik Aronesty
10

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 UNIX pueden conectar procesos dispares localmente y tienen un mayor ancho de banda pero sin límites de mensajes inherentes.
  • Los sockets TCP / IP pueden conectar cualquier proceso, incluso a través de la red, pero tienen una sobrecarga más alta y no tienen límites de mensajes inherentes.
Phillip Whelan
fuente
tal vez esto. sites.google.com/site/rikkus/…
scythargon
¿Cómo se compara dbus con otros?
BЈовић
DBUS utiliza uno o varios de estos mecanismos. Hay un trabajo de larga data en su propio mecanismo de IPC llamado DBUS1 (o KDBUS ...) pero aún no se ha fusionado con el núcleo principal.
Phillip Whelan
8

Vale la pena señalar que muchas bibliotecas implementan un tipo de cosas sobre otras.

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

MarkR
fuente
Nunca había oído hablar de mmaping / dev / zero antes. ¡Ingenioso! Mencionas que solo se puede compartir con niños, pero ¿puedes enviar el descriptor de archivo que estás usando a un proceso no relacionado usando cmsg / SCM_RIGHTS sobre un socket de dominio Unix y terminar con un mapeo compartido allí? ¿O es la asignación que hereda, no el descriptor de archivo? Incluso si funciona, todavía necesita el socket en algún lugar del sistema de archivos para hacerlo, por lo que incluso si el mapeo es anónimo, el socket utilizado para configurarlo no lo es. Guh. IPC es difícil. ¡Vamos de compras!
Tom Anderson
En realidad, algunos tipos de asignación de memoria utilizan mmaping / dev / zero. Pero la ventaja es que si usa MAP_SHARED, se comparte con sus procesos secundarios de fork () ed (normalmente la memoria se copia lógicamente). ¿Puedes compartirlo con un proceso no relacionado? No lo creo. Sospecho que la llamada mmap () debe compartirse, no el descriptor de archivo.
MarkR