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?
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?
Respuestas:
Aquí están los siete grandes:
Útil solo entre procesos relacionados como padre / hijo. Llame pipe(2)
y fork(2)
. Unidireccional.
FIFO o tubería con nombre
Dos procesos no relacionados pueden usar FIFO a diferencia de la tubería simple. Llame mkfifo(3)
. Unidireccional.
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)
.
El sistema operativo mantiene un mensaje discreto. Ver sys / msg.h .
Signal envía un número entero a otro proceso. No encaja bien con hilos múltiples. Llame kill(2)
.
Un mecanismo de sincronización para multiprocesos o subprocesos, similar a una cola de personas esperando el baño. Ver sys / sem.h .
Haga su propio control de concurrencia. Llame shmget(2)
.
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_MAX
o UINT_MAX
y aceptar enviar la longitud del mensaje primero en char
o 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.
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.
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:
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.