procesos para mensajes entre comunicacion comandos cola c++ linux performance ipc latency

c++ - para - comunicacion entre procesos linux



¿La técnica más rápida para pasar mensajes entre procesos en Linux? (7)

Al etiquetar esta pregunta con C ++, recomendaría Boost.Interprocess :

La memoria compartida es el mecanismo de comunicación entre procesos más rápido. El sistema operativo asigna un segmento de memoria en el espacio de direcciones de varios procesos, de modo que varios procesos pueden leer y escribir en ese segmento de memoria sin llamar a las funciones del sistema operativo. Sin embargo, necesitamos algún tipo de sincronización entre los procesos que leen y escriben memoria compartida.

Source

Una advertencia que he encontrado son las limitaciones de portabilidad para las primitivas de sincronización . Ni OS X, ni Windows tienen una implementación nativa para las variables de condición entre procesos, por ejemplo, por lo que las emula con los bloqueos de giro.

Ahora, si usa un * nix que admita primitivas compartidas de proceso POSIX, no habrá problemas.

La memoria compartida con sincronización es un buen enfoque cuando se trata de datos considerables.

¿Cuál es la tecnología más rápida para enviar mensajes entre procesos de aplicaciones C ++ en Linux? Soy vagamente consciente de que las siguientes técnicas están sobre la mesa:

  • TCP
  • UDP
  • Enchufes
  • Tubería
  • Tuberías con nombre
  • Archivos mapeados en memoria

¿Hay más formas y cuál es la más rápida?



NetOS Systems Research Group de la Universidad de Cambridge, Reino Unido ha realizado algunos puntos de referencia de IPC (de código abierto).

El código fuente se encuentra en https://github.com/avsm/ipc-bench .

Página del proyecto: http://www.cl.cam.ac.uk/research/srg/netos/projects/ipc-bench/ .

Resultados: http://www.cl.cam.ac.uk/research/srg/netos/projects/ipc-bench/results.html

Esta investigación se ha publicado utilizando los resultados anteriores: http://anil.recoil.org/papers/drafts/2012-usenix-ipc-draft1.pdf


Si bien todas las respuestas anteriores son muy buenas, creo que tendríamos que discutir qué es "más rápido" [y ¿tiene que ser "más rápido" o simplemente "lo suficientemente rápido para"?]

Para los mensajes GRANDES, no hay duda de que la memoria compartida es una técnica muy buena y muy útil de muchas maneras.

Sin embargo, si los mensajes son pequeños, hay inconvenientes de tener que crear su propio protocolo de paso de mensajes y el método para informar al otro proceso que hay un mensaje.

Las canalizaciones y las canalizaciones con nombre son mucho más fáciles de usar en este caso: se comportan de manera muy parecida a un archivo, usted solo escribe los datos en el lado de envío y lee los datos en el lado de recepción. Si el remitente escribe algo, el lado del receptor se activa automáticamente. Si el tubo está lleno, el lado de envío se bloquea. Si no hay más datos del remitente, el lado receptor se bloquea automáticamente. Lo que significa que esto se puede implementar en pocas líneas de código con una buena garantía de que funcionará en todo momento, todo el tiempo.

La memoria compartida, por otro lado, se basa en algún otro mecanismo para informar al otro hilo que "tienes un paquete de datos para procesar". Sí, es muy rápido si tiene GRANDES paquetes de datos para copiar, pero me sorprendería si realmente hay una gran diferencia en una canalización. El beneficio principal sería que la otra parte no tiene que copiar los datos de la memoria compartida, pero también depende de que haya suficiente memoria para contener todos los mensajes "en vuelo", o que el remitente tenga la capacidad de retener cosas .

No estoy diciendo "no use la memoria compartida", solo digo que no existe tal cosa como "una solución que resuelva todos los problemas" de la mejor manera ".

Para aclarar: Empezaría por implementar un método simple utilizando una tubería o una tubería con nombre [dependiendo de lo que se adapte a los propósitos], y mediría el rendimiento de eso. Si se dedica un tiempo significativo a copiar los datos, entonces consideraría utilizar otros métodos.

Por supuesto, otra consideración debería ser "si alguna vez vamos a utilizar dos máquinas separadas [o dos máquinas virtuales en el mismo sistema] para resolver este problema. En ese caso, una solución de red es una mejor opción, incluso si no es la más rápida. , He ejecutado una pila TCP local en mis máquinas en el trabajo para propósitos de referencia y obtuve unos 20-30 Gbit / s (2-3GB / s) con tráfico sostenido. Un memcpy sin procesar en el mismo proceso obtiene alrededor de 50-100GBit / s (5-10 GB / s) (a menos que el tamaño del bloque sea REALMENTE pequeño y quepa en el caché L1). No he medido una tubería estándar, pero espero que esté aproximadamente en el medio de esos dos números. que son las adecuadas para una gran cantidad de PCs bastante modernas de tamaño mediano, obviamente, en un ARM, MIPS u otro controlador de estilo integrado, espere un número menor para todos estos métodos]


También sugeriría ver esto: Cómo usar la memoria compartida con Linux en C.

Básicamente, eliminaría los protocolos de red como TCP y UDP al hacer IPC en una sola máquina. Estos tienen sobrecarga de paquetes y están vinculados a incluso más recursos (por ejemplo, puertos, interfaz de bucle invertido).



Bueno, simplemente podría tener un segmento de memoria compartida entre sus procesos, utilizando la memoria compartida de Linux, también conocida como SHM .

Es bastante fácil de usar, mira el enlace para ver algunos ejemplos.