2009-12-30 10 views
96
  1. ¿Podemos llamar a send desde un hilo y recv desde otro en el mismo socket?
  2. ¿Podemos llamar múltiples envíos de forma paralela 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 también para el mismo.¿Son válidas las llamadas en paralelo para enviar/recv en el mismo zócalo?

Cualquier puntero en la dirección será útil.

+0

¿por qué afirma que hacerlo es una mala práctica ?. Me parece bien porque escuchas y recibes de diferentes hilos. – TheMathNoob

Respuesta

72

POSIX define send/recv como operaciones atómicas, por lo tanto, suponiendo que esté hablando de POSIX send/recv, entonces sí, puede llamarlos simultáneamente desde múltiples hilos y las cosas funcionarán.

Esto no significa necesariamente que se ejecutarán en paralelo: en el caso de envíos múltiples, el segundo bloqueará probablemente hasta que el primero finalice. Probablemente no se dará cuenta de esto, ya que un envío finaliza una vez que coloca sus datos en el búfer del zócalo.

Si está utilizando sockets SOCK_STREAM, es menos probable que intente hacer las cosas de forma paralela ya que send/recv podría enviar o recibir solo parte de un mensaje, lo que significa que las cosas podrían dividirse.

Bloqueo de envío/recv en SOCK_STREAM Los sockets solo bloquean hasta que envían o recv al menos 1 byte, por lo que la diferencia entre bloqueo y no bloqueo no es útil.

+0

¿Qué pasa con el bloqueo de envío/recepción? ¿Son atómicos? – Jay

+0

este artículo (http://www.almaden.ibm.com/cs/people/marksmith/sendmsg.html) parece confirmar lo que usted dice sobre SOCK_STREAM pero no está claro acerca de SOCK_DGRAM, ¿de dónde exactamente obtuvo su información? –

+1

@Joao: SOCK_DGRAM socket están documentados como "preservar límites de mensajes", lo cual no es muy claro. Al observar las fuentes del kernel de Linux, al menos puede ver que cada envío y recepción se relaciona con un único paquete de forma atómica (al menos para udp). –

2

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 decir cuál fue cuál. A menos que sus mensajes sean solo de un byte, no hay manera de que pueda hacer que algo funcione de manera confiable con la recepción de múltiples hilos.

Envío múltiple podría funcionar, si envió el mensaje completo en una sola llamada, pero no estoy seguro. Es posible que uno pueda sobrescribir otro. Ciertamente no habría ningún beneficio en el rendimiento al hacerlo.

Si es necesario enviar varios subprocesos, debe implementar una cola de mensajes sincronizados. Tiene un hilo que hace el envío real que lee mensajes de la cola y tiene los otros hilos en cola mensajes enteros. Lo mismo funcionaría para recibir, pero el hilo de recepción debería conocer el formato de los mensajes para poder deserializarlos adecuadamente.

+6

Si está utilizando sockets SOCK_DGRAM, cada recv recibirá un solo datagrama; nunca se dividirá entre los recvs –

+2

@noah, acepto que los recvs paralelos no pueden lograr nada. Es por eso que no lo he preguntado. Mi pregunta es send/recv de forma paralela y luego envía múltiples envíos de forma paralela. Tu respuesta da una idea de los envíos paralelos. Gracias por lo mismo. – Jay

+1

@Chris buen punto. Estaba asumiendo TCP. @Jay Puede aclarar la pregunta "¿Podemos llamar enviar/recv en paralelo?" Suena como si quisiera recibir en paralelo. – noah

11

El descriptor de socket pertenece al proceso, no a un hilo en particular. Por lo tanto, es posible enviar/recibir desde/hacia el mismo socket en diferentes subprocesos, el SO manejará la sincronización.

Sin embargo, si el orden de envío/recepción es semánticamente significativo, usted mismo (o su código) debe garantizar la secuencia correcta entre las operaciones en los diferentes subprocesos, como siempre ocurre con los subprocesos.

Cuestiones relacionadas