¿Son válidas las llamadas paralelas para enviar/recibir en el mismo socket?
- ¿Podemos llamar a enviar desde un hilo y recibir desde otro en el mismo socket?
- ¿Podemos llamar a varios envíos en paralelo desde diferentes subprocesos en el mismo socket?
Sé que un buen diseño debería evitar esto, pero no tengo claro cómo se comportarán estas API del sistema. No puedo encontrar una buena documentación tampoco para lo mismo.
Cualquier sugerencia en la dirección será útil.
POSIX define envío/recepción como operaciones atómicas, por lo que suponiendo que esté hablando de envío/recepción POSIX, entonces sí, puede llamarlos simultáneamente desde varios subprocesos y todo funcionará.
Esto no significa necesariamente que se ejecutarán en paralelo; en el caso de envíos múltiples, el segundo probablemente se bloqueará hasta que se complete el primero. Probablemente no notarás esto mucho, ya que el envío se completa una vez que se colocan los datos en el búfer del socket.
Si está utilizando sockets SOCK_STREAM, es menos probable que sea útil intentar hacer cosas en paralelo, ya que enviar/recibir podría enviar o recibir solo una parte de un mensaje, lo que significa que las cosas podrían dividirse.
El bloqueo de envío/recepción en sockets SOCK_STREAM solo bloquea hasta que envían o reciben al menos 1 byte, por lo que la diferencia entre bloqueo y no bloqueo no es útil.
El descriptor de socket pertenece al proceso, no a un hilo en particular. Por lo tanto, es posible enviar/recibir hacia/desde el mismo socket en diferentes subprocesos; el sistema operativo se encargará de la sincronización.
Sin embargo, si el orden de envío/recepción es semánticamente significativo, usted mismo (respectivamente su código) debe garantizar una secuencia adecuada entre las operaciones en los diferentes subprocesos, como siempre es el caso con los subprocesos.
No veo cómo recibir en paralelo podría lograr algo. Si tiene un mensaje de 3 bytes, 1 hilo podría obtener los primeros 2 bytes y otro el último byte, pero no tendría forma de saber cuál es cuál. A menos que sus mensajes tengan solo un byte de longitud, no hay manera de que pueda hacer que algo funcione de manera confiable con la recepción de múltiples subprocesos.
Es posible que funcionen varios envíos si envió el mensaje completo en una sola llamada, pero no estoy seguro. Es posible que uno pueda sobrescribir a otro. Ciertamente no habría ningún beneficio de rendimiento al hacerlo.
Si es necesario enviar varios subprocesos, debe implementar una cola de mensajes sincronizados. Tenga un hilo que realice el envío real que lea los mensajes de la cola y haga que los otros hilos pongan en cola mensajes completos. Lo mismo funcionaría para la recepción, pero el hilo de recepción tendría que conocer el formato de los mensajes para poder deserializarlos correctamente.