Paso de mensajes Motivación: sistemas distribuidos: Paso de mensajes I I I Lecturas: Burns & Wellings, Cap. ??? Transparencias y apuntes de la asignatura I I Ausencia de memoria compartida Datos repartidos entre procesos / tareas Quizás en máquinas distintas Acceso a datos mediante comunicación de procesos: paso de mensajes También para sincronización Aparecen al conectar ordenadores a una red Exclusión mutua gratis (no hay datos fı́sicamente compartidos) Problema: comunicación entre procesos Manuel Carro Universidad Politécnica de Madrid Este texto se distribuye bajo los términos de la Creative Commons License M. Carro (UPM) Paso de mensajes 1 / 42 Filosofı́a cliente-servidor M. Carro (UPM) Paso de mensajes 2 / 42 Canales de Comunicación Procesos servidor ejecutándose en un ordenador Procesos cliente se ejecutan donde resulte más conveniente al usuario Filosofı́a cliente-servidor adapta al contexto distribuido los conceptos de recursos compartidos del tema anterior Los procesos se ejecutan en espacios de memoria independientes y se comunican intercambiando mensajes, que contienen copias de variables del emisor Procesos resultantes del análisis darán lugar a procesos cliente Interacción se convierte en proceso servidor que encapsula el recurso M. Carro (UPM) Paso de mensajes 3 / 42 Lenguajes para paso de mensajes M. Carro (UPM) Paso de mensajes 4 / 42 Sincronicidad de los Canales Clasificación según las caracterı́sticas de los canales de comunicación entre procesos: Por el comportamiento dinámico de los canales (sı́ncrono o ası́ncrono) Por el nombrado de los canales (explı́cito o implı́cito) Por la cardinalidad de los esquemas de comunicación (1:1, n:1, n:m) ¡La recepción siempre es bloqueante! Ası́ncronos Envı́o no bloqueante; el emisor sigue ejecutándose sin esperar a que la comunicación tenga efecto (telegramas, emails, . . . ) Sı́ncronos Envı́o bloqueante; emisor y receptor se sincronizan para intercambiarse cada mensaje (hablar en persona, por teléfono. . . ) Ventajas: mayor concurrencia — útil si el tiempo de respuesta es elevado Inconvenientes: Necesita de colas de mensajes (puede ser costoso) Mayorı́a de lenguajes optan por canales sı́ncronos Canales ası́ncronos: protocolos de comunicaciones (TCP/IP) o computación paralela M. Carro (UPM) Paso de mensajes 5 / 42 M. Carro (UPM) Paso de mensajes 6 / 42 Esquemas de comunicación Nombrado de Canales Nombrado explı́cito: Los canales son un tipo de datos del lenguaje y el programador debe declararlos, asignarlos, destruirlos, etc. Ventajas: Pueden declararse vectores o matrices de canales Pasar canales como datos: útil en entornos cliente-servidor Inconvenientes: Más trabajo para el programador (1:1) Cada canal tiene un emisor y un receptor. (n:1) Varios procesos pueden enviar mensajes por el canal y sólo uno puede recibirlos (el habitual con admite nombrado explı́cito (ports) (n:m) Varios emisores y varios receptores (no ha tenido mucho éxito) Nombrado implı́cito: Canales ocultos al programador: se identifican proporcionando un nombre del proceso receptor Ventajas: Menos código, no es necesario declarar, ni destruir Inconvenientes: Sólo permiten comunicación 1:1 M. Carro (UPM) Paso de mensajes 7 / 42 Notación Gráfica M. Carro (UPM) Paso de mensajes 8 / 42 Ejemplo: Productor-Consumidor Versión sin buffering: Asumimos una notación de paso de mensajes con canales explı́citos sı́ncronos Canal.Send(mensaje ); Canal.Receive(mensaje ) La codificación resulta inmediata Conocimiento de Canal: aparece aquı́ como variable compartida En un verdadero entorno distribuido serı́a una dirección / nombre conocido por ambos procesos Procesos como cı́rculos Canal comunicación une procesos Tiene dirección (emisor y receptor) M. Carro (UPM) Paso de mensajes 9 / 42 Necesidad de la recepción alternativa CResp Consumidor CPet Productor ... Buffer ... Consumidor ... Producir(Dato); CDato.Send(Dato); ... CDato.Receive(MiDato); Insertar (MiBuffer,MiDato); CPet.Receive(P’); Extraer(MiBuffer,MiDato); CResp.Send(MiDato); CPet.Send(P); CResp.Receive(MiDato); Consumir(MiDato); ... Paso de mensajes loop select CanalEnt1 . Receive ( Mensaje ) do ... CanalSal1 . Send ( Mensaje2 ) ; ... end ; or Canal2 . Receive ( Mensaje ) do ... end ; end s e l e c t ; end loop También con guarda: when Cond Canal.Receive(Mens) ... Acoplamiento de velocidades M. Carro (UPM) 10 / 42 Bucle dentro de una tarea Aguarda la llegada de mensajes por varios canales Se activa la rama que recibe CData Buffer Paso de mensajes Recepción alternativa Productor es más rápido que el consumidor Evitar acoplamiento con encolado de datos Productor M. Carro (UPM) 11 / 42 M. Carro (UPM) Paso de mensajes 12 / 42 Buffer con paso de mensajes CP : Channel ; CT : Channel ; Rendez-Vous −− Para poner −− Para tomar select when not Lleno (B) = > CP. Receive (D ) do I n s e r t a r ( B , D) end ; or when not Vacio (B) = > CT . Receive (CR ) do R e t i r a r (B , D) ; CR. Send (D ) ; end ; end s e l e c t ; Disponible en Ada (la forma inicial de sincronización) Una combinación edulcorada de Send / Receive P r o d u c i r ( Dato ) ; CP. Send ( Dato ) ; accept: nombre fijo para canal accept Op (Args) do ... end Op; I “Op” como nombre de canal I “Args” pueden ser entrada y salida CT . Send ( CanResp ) ; CanResp . Receive ( Dato ) ; Consumir ( Dato ) ; Acuerdo en canales compartidos Canales privados (cada cliente proporciona el suyo) Esquema genérico CSP (no propio de Ada) M. Carro (UPM) Paso de mensajes 13 / 42 Ejemplo: Buffer con Rendez-Vous M. Carro (UPM) I 14 / 42 T.Poner(Dato); accept Poner(Dato) do Bloqueado Insertar(B, Dato); end Poner; or ... Ejecucion simultanea Tarea . Tomar ( Dato ) ; Consumir ( Dato ) ; Paso de mensajes 15 / 42 M. Carro (UPM) Paso de mensajes 16 / 42 Rendez-Vous + canales accept para recibir canales de comunicación Canales para pasar datos Adecuado para problemas simples Pero oculta caracterı́sticas propias de los sistemas basados en mensajes: I Paso de mensajes Tareas (llamante y servidora) se encuentran en accept Op y se separan en end Op; Crı́tica Rendez-Vous I M. Carro (UPM) Tarea.Op(Args) Principio y final del Rendez-Vous loop select when not Lleno ( B) = > accept Poner (D : i n T Dato ) do I n s e r t a r ( B , D) end Poner ; or when not Vacio ( B) = > accept Tomar (D : out T Dato ) do R e t i r a r (B , D) ; end Tomar ; end s e l e c t ; end loop ; P r o d u c i r ( Dato ) ; Tarea . Poner ( Dato ) ; Llamada: select when Cond => accept Op1 ( Args ) do ... end Op1 ; ... or ... end s e l e c t ; select when not Lleno (B) = > accept Poner ( Chan : i n out Channel P ) do Local Channel : = Chan ; end Poner ; Local Channel . Receive (D ) ; I n s e r t a r (B , D) ; or when not Vacio (B) = > accept Tomar ( Chan : i n out Channel P ) do Local Channel : = Chan ; end Tomar ; R e t i r a r (B , D) ; Local Channel . Send (D ) ; end s e l e c t ; Devolución explı́cita de datos mediante canales Send / Receive para sincronizar Comunicación fuera del espacio del Rendez-Vous Uso (¿artificial?) de una implementación (externa al lenguaje) de canales ¿Por qué código fuera de accept? M. Carro (UPM) Paso de mensajes 17 / 42 M. Carro (UPM) Paso de mensajes 18 / 42 Rendez-Vous y dependencia parámetros Rendez-Vous y canales (Cont.) Rendez-Vous: guardas sólo usan estado Recurso activo: when not Lleno ( B) = > accept Poner ( Chan : i n out Channel P ) do Local Channel : = Chan ; end Poner ; Local Channel . Receive (D ) ; I n s e r t a r (B , D) ; I I No hay familias de entries requeue no tiene mismo significado Pero tenemos canales: I Código del productor: I loop P r o d u c i r ( Dato ) ; T . Poner ( ChanPoner ) ; ChanPoner . Send ( Dato ) ; end loop ; I Permiten comunicación explı́cita Identifican procesos (cada canal almacenado corresponde a un proceso esperando) Deben ser manejados / planificados explı́citamente En general: canales como entidades externas que permiten realizar sincronización y paso de datos Paralelismo canal / identificador proceso Clientes esperando en Send / Receive: posibilidad de despertar explı́cito Además: más concurrencia (entre servidor y clientes) M. Carro (UPM) Paso de mensajes 19 / 42 Buffer par/impar con Rendez-Vous puro M. Carro (UPM) Paso de mensajes 20 / 42 P/I con Rendez-Vous puro (Cont.) Tras la descomposición: Dependencia estado → proyección condiciones a nivel superior: entry Tomar Par ( Item : out I n t e g e r ) ; entry Tomar Impar ( Item : out I n t e g e r ) ; when Hay Dato and then Dato mod 2 = 0 = > accept Tomar Par ( Item : out I n t e g e r ) do Item : = Dato ; −− Item : p a r t e d e l estado Hay Dato : = False ; −− Hay Dato : p a r t e d e l estado end Tomar Par ; Respetar interfaz: englobar llamadas procedure Tomar ( S : i n out Server ; Req T ; Req : i n out I n t e g e r ) i s Dato : begin −− Descomponer seg ún r e q u e r i d o i f Req = Par then Server . Tomar Par ( Dato ) ; else Server . Tomar Impar ( Dato ) ; end i f ; end Tomar ; Como en objetos protegidos, puede haber problemas: I I Muchos casos Tipo de datos no se adapta naturalmente Solución más general: pasar canales, guardarlos, aceptar parámetros, decidir según parámetros Idea idéntica a objetos protegidos M. Carro (UPM) Paso de mensajes 21 / 42 M. Carro (UPM) Paso de mensajes Esquema de un servidor Con paso de mensajes puro (sin guardas) entries siempre aceptan canal (privado a cliente) El aceptar / devolver datos permite que los clientes (re)arranquen Dos partes claramente diferenciadas en servidor: I Aceptar todas las peticiones when True => accept . . . . do Insertar ( . . . ) ; end accept ; Se requieren datos a clientes según sea necesario I 22 / 42 Con un canal asociado Recepción de peticiones y canales, almacenamiento Servicio de peticiones almacenadas Canales: vı́nculo entre clientes y recurso while C1 or C2 or . . . loop i f C1 then Extraer ( . . . , C) ; C . Send ( . . . ) ; e l s i f C2 then ... end i f ; end loop ; Escoger la polı́tica de rearranque que prefiramos M. Carro (UPM) Paso de mensajes 23 / 42 M. Carro (UPM) Paso de mensajes Analizar qué peticiones pueden atenderse Decidir entre ellas cual debe atenderse Necesario decidir: I I Desbloqueo explı́cito Análisis de vivacidad 24 / 42 Productor Consumidor Siempre pasa canal (una forma de poner de acuerdo productor y recurso) Se pasa tipo de petición y se espera dato Data Channel : C h a n n e l I n t . Channel P : = new . . . Req Channel : Channel Req . Channel P : = new . . . ... loop TheBufServer . Tomar ( Req Channel , Data Channel ) ; Req Channel . Send ( Which Type ) ; Data Channel . Receive ( Dato ) ; end loop ; Data Channel : C h a n n e l I n t . Channel P : = new C h a n n e l I n t . Channel ; loop P r o d u c i r ( Dato ) ; −− Depende d e l p r o d u c t o r TheBufServer . Poner ( Data Channel ) ; Data Channel . Send ( Dato ) ; end loop ; Tipo de petición se acepta siempre Como siempre: el recurso debe realizar Receive fuera del Rendez-Vous M. Carro (UPM) Paso de mensajes Send en el recurso cuando se dan las condiciones 25 / 42 Recepción de peticiones: Poner Paso de mensajes when True => accept Tomar ( C T : i n Ch Req . Ch P ; C D : i n out C h I n t . Ch P ) do C T Local : = C T ; C D Local : = C D ; end Tomar ; C T Local . Receive ( Pet ) ; I n s e r t a r ( Pend Tomar ( Pet ) , C D Local ) ; when True => accept Poner ( C D : i n out C h I n t . Ch P ) do I n s e r t a r ( Pend Poner , Canal Dato ) ; end Poner ; Podrı́a ser when not Hay Dato Menos peticiones a almacenar El despertar necesita precondición completa Encaja con código cliente Respuesta: no puede ser en accept (aún en Rendez-Vous) ¿Servir inmediatamente (si es posible)? Variables locales para evitar interbloqueo en accept I 26 / 42 Recepción de peticiones: Tomar Pend Poner: Cola; I M. Carro (UPM) Peticiones ya recibidas relegadas (¿inanición?) M. Carro (UPM) Paso de mensajes 27 / 42 Servicio petición en pares e impares 28 / 42 Poner depende de estado I Usar guardas en accept: when not Hay Dato => accept Poner ( . . . ) do . . . Tomar depende, adicionalmente, de parámetros Y siempre necesitamos saber el tipo de petición I Pasar dato y tipo de petición siempre when not Hay Dato => accept Poner (D : i n T Dato ) do . . . when Hay Dato => accept Tomar (P : in Req T ; Chan : i n out Chan P ) do . . . Atención: preferencia por un tipo de petición −→ inanición Paso de mensajes Paso de mensajes Una solución intermedia while ( not Hay Dato and not Es Vacia ( Pend Poner ) ) or . . . loop i f not Hay Dato and not Es Vacia ( Pend Poner ) then Primero ( Pend Poner , Canal Poner ) ; B o r r a r ( Pend Poner ) ; Canal Poner . Receive ( Dato ) ; Hay Dato : = True ; else <<e x t r a e r de pend . tomar>> <<s e r v i r >> end i f ; end loop ; M. Carro (UPM) M. Carro (UPM) 29 / 42 M. Carro (UPM) Paso de mensajes 30 / 42 Un caso particular Esquema de código A veces atender en orden de llegada es suficiente Sólo necesitamos guardar un registro de activación Similar a atención por orden de bloqueo Idea de esquema: I I I Sólo una instancia suspendida de cada operación Con parámetros/canales respuesta guardados Al recibir operación: F F Aceptar sólo si no instancia suspendida ya Si hay instancia suspendida, guardar en registro de activación, atender después M. Carro (UPM) Paso de mensajes 31 / 42 Multibuffer con doble bloqueo Aceptar número elementos a poner/tomar Aceptar elementos en sı́ Segundo paso vacı́o en este ejemplo: lo usamos para despertar cliente M. Carro (UPM) Paso de mensajes Paso de mensajes 32 / 42 loop << Produce Num datos >> Pool . Get (Num, Put Channel ) ; Put Channel . Receive ( Data ) ; end loop ; Poner, Tomar dependen de argumentos Dos pasos: 2 M. Carro (UPM) Cliente de multibuffer Multibuffer estilizado: sólo número elementos 1 when not Delayed Op 1 => accept Op 1 ( Par : i n . . . ; Ans : i n out Channel P ) do Par Op 1 : = Par ; Ans Chan 1 : = Ans ; Op 1 Delayed : = True ; end Op1 ; .. . while . . . loop i f Op 1 Delayed and then Pre Op 1 ( State , Par Op 1 ) then State : = . . . ; Ans Chan 1 . Send ( . . . ) ; Op 1 Delayed : = False ; end i f ; <<comprobaciones de o t r a s operaciones>> end loop ; 33 / 42 Servidor multibuffer: aceptar peticiones Data serı́a el vector de elementos Send en servidor despierta clientes cuando se acepta su petición M. Carro (UPM) Paso de mensajes 34 / 42 Multibuffer: atender petición almacenada Veremos esquema para el Get (Put serı́a similar) Código inmediatamente detrás de la selección alternativa Se ejecuta siempre tras aceptar una operación when not Delayed Get => accept Get ( Num Items : i n B u f f e r Q u a n t i t y ; The Get Channel : i n out Channel P ) do Num Items To Get : = Num Items ; Get Channel : = The Get Channel ; Delayed Get : = True ; end Get ; i f Delayed Get and then I t e m C o u n t e r >= Num Items To Get then I t e m C o u n t e r : = I t e m C o u n t e r − Num Items To Get ; Get Channel . Send ( Data ) ; Delayed Get : = False ; end i f ; Máx. una petición suspendida en cada momento Se ejecuta cuando: Aceptamos únicamente los datos necesarios para decidir si atender o no 1 2 Hay Get suspendido Y la llamada suspendida puede atenderse Se sirve la llamada en ese caso Data contendrı́a secuencia de elementos a devolver M. Carro (UPM) Paso de mensajes 35 / 42 M. Carro (UPM) Paso de mensajes 36 / 42 Multibuffer: atender otras peticiones Polı́ticas explı́citas Tras posible aceptación Get / Put, ver si se pueden servir otras peticiones suspendidas Puede simplificarse consulta de CPRE: I I I I (cómo despertar la operación / proceso que queramos) Fácil: I Si sabemos qué operacion acaba de ejecutarse, pueden ahorrarse comprobaciones Determinadas comprobaciones pueden llevarse a la zona de la select inmediatamente posterior al accept Podrı́an relegarse operaciones suspendidas: ¡cuidado! Código repetido (caso común) → agrupar tras select En caso general: siempre bucle I I Admitir canal en servidor (ya sea para devolver o para recibir datos) Guardar canal (quizás con datos asociados a la llamada) Escoger qué proceso (canal) servir La elección puede (debe): I I Evaluar estado recurso Evaluar parámetros asociados a la llamada Sustituye PID proceso por canal (único por cliente) Pueden despertarse varias operaciones → uso de tablas de desbloqueos M. Carro (UPM) Paso de mensajes 37 / 42 M. Carro (UPM) Paso de mensajes 38 / 42 Representación gráfica Polı́ticas explı́citas (Cont.) RECURSO Ejemplo: cuenta compartida con prioridad para petición mayor accept R e t i r a r ( Cant : i n I n t e g e r ; Aceptado : i n out Chan ) when True do <<Guardar c a n a l asociado a Cant>> end R e t i r a r ; Una tarea dentro del recurso (recurso activo) El cliente de Retirar espera en Aceptado Canales: especifican nombre de variable y tipo Al depositar: examinar canales, satisfacer la mayor petición que pueda atenderse Nombre variable: el que aparece en el servidor Ejercicio: ¿qué estructura de datos implementarı́a eficientemente esta búsqueda? Rendez-Vous: canales implı́citos bidireccionales M. Carro (UPM) Paso de mensajes 39 / 42 Representación gráfica M. Carro (UPM) Paso de mensajes Var: Tipo Sal: Tipo Ent: Tipo 40 / 42 Paso de mensajes y modularidad Canales privados creados / utilizados por una operación encapsuladora Selección alternativa (select) Recurso OP 1 CPRE OP 1 OP 2 CPRE Asociación Rendez-Vous y explı́cito Send / Receive CPRE OP 2 CPRE sobre canales M. Carro (UPM) Paso de mensajes 41 / 42 M. Carro (UPM) Paso de mensajes 42 / 42