2010-02-10 11 views
8

He notado dos métodos para "enviar mensajes". Uno que he visto usar Erlang y el otro es de Stackless Python. Por lo que entiendo aquí está la diferenciacanales de bloqueo vs mensaje asíncrono que pasa

Erlang Style - Los mensajes se envían y se ponen en cola en el buzón del proceso de recepción. A partir de ahí, se eliminan en una base FIFO. Una vez que el primer proceso envía el mensaje, es gratis continuar.

Estilo de Python - Proceso A hace colas hasta enviar al proceso B. B está realizando actualmente otra acción, por lo que A se congela hasta que B esté listo para recibir. Una vez que B abre un canal de lectura, A envía los datos, luego ambos continúan.

Ahora veo que las ventajas del método Erlang radican en que no tiene ningún proceso bloqueado. Si B nunca puede recibir, A todavía puede continuar. Sin embargo, he notado en algunos programas que he escrito, que es posible que los buzones de mensajes de Erlang se llenen de cientos (o miles) de mensajes, ya que la entrada de mensajes es mayor que la salida.

Ahora no he escrito un programa extenso en framework/language, así que me pregunto qué experiencia tiene con esto, y si es algo de lo que debería preocuparme.

Sí, sé que esto es abstracto, pero también estoy buscando respuestas bastante abstractas.

Respuesta

6

Mi experiencia en la programación de Erlang es que cuando espera una alta tasa de mensajes (es decir, un productor más rápido que el consumidor), agrega su propio control de flujo. Un escenario simple

  • El consumidor: enviará un mensaje, esperará la confirmación y luego repetirá.
  • El productor: esperará el mensaje, enviará una confirmación cuando se reciba y procese el mensaje, luego repetirá.

También se puede invertir, el productor espera a que el consumidor venga y tome los siguientes N mensajes disponibles.

Estos enfoques y otros controles de flujo se pueden ocultar detrás de las funciones, el primero ya está disponible en su mayoría en gen_server:call/2,3 contra un proceso de comportamiento gen_server OTP.

Veo la mensajería asíncrona como en Erlang como el mejor enfoque, ya que cuando las latencias son altas, es posible que desee evitar una sincronización al enviar mensajes entre computadoras. Uno puede entonces componer formas inteligentes de implementar control de flujo. Digamos, requiriendo una confirmación del consumidor por cada N mensajes que el productor le ha enviado, o envíe un mensaje especial "ping me cuando ha recibido este" de vez en cuando, para contar el tiempo de ping.

3

En líneas generales, se trata de colas ilimitadas vs colas limitadas. Un canal sin pila se puede considerar un caso especial de una cola con tamaño 0.

Las colas limitadas tienen una tendencia a interbloqueo. Dos hilos/procesos que intentan enviarse un mensaje, ambos con una cola completa.

Las colas sin límite tienen fallas más sutiles. Un buzón grande no cumplirá con los requisitos de latencia, como usted mencionó. Ir lo suficientemente lejos y eventualmente se desbordará; no existe la memoria infinita, por lo que en realidad es solo una cola limitada con un límite enorme que aborta el proceso cuando está lleno.

¿Cuál es la mejor? Eso es difícil de decir. No hay respuestas fáciles aquí.

Cuestiones relacionadas