Qué vimos la clase pasada?

48
14-6-2004 1 Qué vimos la clase pasada? Hoare introdujo CSP como lenguaje formal que sigue el modelo de pasaje de mensajes sincrónicos, como un modelo de especificación, sin una implementación real. OCCAM es un lenguaje real, que implementa lo esencial de CSP sobre una arquitectura “modelo” que físicamente se ha desarrollado y que son los trasputers. Trasputers + OCCAM constituyen una combinación que permite hablar de “sistema multiprocesador para procesamiento concurrente”, donde aparecen los conceptos de CSP (comunicación guardada half duplex, no determinismo, especificación del paralelismo, timers, canales estáticos). Programación Concurrente 2004 - Clase 9

description

Qué vimos la clase pasada?. Hoare introdujo CSP como lenguaje formal que sigue el modelo de pasaje de mensajes sincrónicos, como un modelo de especificación, sin una implementación real. - PowerPoint PPT Presentation

Transcript of Qué vimos la clase pasada?

Page 1: Qué vimos la clase pasada?

14-6-2004 1

Qué vimos la clase pasada?

Hoare introdujo CSP como lenguaje formal que sigue el modelo de pasaje de mensajes sincrónicos, como un modelo de especificación, sin una implementación real.

OCCAM es un lenguaje real, que implementa lo esencial de CSP sobre una arquitectura “modelo” que físicamente se ha desarrollado y que son los trasputers.

Trasputers + OCCAM constituyen una combinación que permite hablar de “sistema multiprocesador para procesamiento concurrente”, donde aparecen los conceptos de CSP (comunicación guardada half duplex, no determinismo, especificación del paralelismo, timers, canales estáticos).

Programación Concurrente 2004 - Clase 9

Page 2: Qué vimos la clase pasada?

14-6-2004 2

Qué vimos la clase pasada?

Una técnica muy utilizada es el desarrollo de bibliotecas de funciones que permiten comunicar/sincronizar procesos.

Las soluciones basadas en bibliotecas (tales como LINDA, MPI, PVM) tienden a ser menos eficientes que los lenguajes “reales”de programación concurrente, aunque tienen la facilidad de “agregarse”al código secuencial con bajo costo de desarrollo.

LINDA explota el paradigma de “bag of tasks” y en nuestros días las redes han potenciado las soluciones basadas en PVM o MPI (que son básicamente bibliotecas de comunicaciones). Programación Concurrente 2004 - Clase 9

Page 3: Qué vimos la clase pasada?

14-6-2004 3

Comentarios sobre las preguntas para la promoción

Ud. tiene una red (por ejemplo móvil) conectada sin cables. Debe hacer un análisis para que todos sepan quienes están conectados en la red. Usaría mensajes sincrónicos o asincrónicos? Por qué?Si no existe un nodo distinguido y todos deben aprender la topología, es conveniente trabajar con mensajes asincrónicos y un timer general.Si intentamos con mensajes sincrónicos, es muy complicado por la naturaleza bloqueante del SEND.

Si se tratara de hacer un broadcast en una red conectada en anillo, qué diferencias ve entre SMP y AMP?Los tiempos que se pierden en los SEND bloqueantes si el siguiente nodo en el anillo no está haciendo RECEIVE.

Programación Concurrente 2004 - Clase 9

Page 4: Qué vimos la clase pasada?

14-6-2004 4

Servidor / Servidores replicados y el caso de los Filósofos.

Programación Concurrente 2004 - Clase 11

Page 5: Qué vimos la clase pasada?

14-6-2004 5

Paradigma de servidores replicados. Modelos de solución de filósofos.

El primer modelo de solución que hemos visto, es el centralizado. En este caso los procesos Filósofo se comunican con un proceso Waiter (SERVIDOR) que decide el acceso o no a los recursos.

La segunda solución que llamaremos distribuida supone cinco procesos Waiter cada uno de los cuales maneja un tenedor. Para este problema un Filósofo puede comunicarse con dos Waiters (SERVIDOR izquierdo y derecho), solicitando y devolviendo el recurso. Los Waiters NO se comunican entre ellos.

En la tercer solución que llamaremos descentralizada, cada Filósofo ve un único Waiter. En cambio los Waiters (SERVIDORES) se comunican entre ellos (de hecho cada uno con sus dos vecinos) para decidir el manejo del recurso asociado a “su” Filósofo.

Programación Concurrente 2004 - Clase 11

Page 6: Qué vimos la clase pasada?

14-6-2004 6

Recordemos Filósofos centralizados.

Waiter:: var eating[1:5] := ([5] false) { EAT: ( i: 1 i 5: eating[i] (eating[i1] eating[i1]) }

DO (i: 1..5) not (eating [i1] or eating[i1]); Phil[i]?getforks( ) eating[i] := true (i: 1..5) Phil[i]?relforks( ) eating[i] := false OD

Phil[i: 1..5]:: DO true Waiter ! getforks( ) come Waiter ! relforks( ) piensa OD

Programación Concurrente 2004 - Clase 11

Page 7: Qué vimos la clase pasada?

14-6-2004 7

Paradigma de servidores replicados: Filósofos distribuidos.

Process Philosopher[i=0 to 4] { INT first=i, second= i+1; IF (i == 4) { first=0; second=4;}

WHILE (true) { Call Waiter[first]. Getfork ( ); Call Waiter[second]. Getfork ( ); COMER;

Send Waiter[first]. Relfork ( ); Send Waiter[second].Relfork ( ); PENSAR; }}

Programación Concurrente 2004 - Clase 11

Page 8: Qué vimos la clase pasada?

14-6-2004 8

Paradigma de servidores replicados: Filósofos distribuidos.

Module Waiter[5] op Getforks( ), Relfork( );

BODY Process The_Waiter { WHILE (true) receive getfork ( ); receive relfork ( ); } }End Waiter;

Programación Concurrente 2004 - Clase 11

Page 9: Qué vimos la clase pasada?

14-6-2004 9

Paradigma de servidores replicados: Filósofos descentralizados.

Module Waiter[ t=0 to 4] OP Getforks(int), Relforks(int); #usadas por los filósofos OP NeedL( ), NeedR( ), PassL ( ), PassR( ); # para los Waiters OP Forks (bool, bool, bool, bool); #para inicializar

BODY OP Hungry( ), Eat ( ) ; #operaciones locales BOOL haveL, dirtyL, haveR, dirtyR; #status de los tenedores INT left = (t-1) MOD 5; #vecino a izquierda INT right = (t +1) MOD 5; # vecino a derecha

PROC Getforks ( ) { send Hungry ( ); receive Eat( ); # espera el permiso para comer }

Programación Concurrente 2004 - Clase 11

Page 10: Qué vimos la clase pasada?

14-6-2004 10

Filósofos descentralizados. Proceso Waiter

Process the_Waiter { receive forks (haveL, dirtyL, haveR, dirtyR); WHILE (true) { IN hungry ( ) ---> # preguntar por los tenedores que no se tienen IF (Not HaveR) send Waiter[right].needL( ); IF (Not HaveL) send Waiter[left].needR( ); # esperar hasta tener ambos tenedores WHILE ( Not haveL OR Not haveR) IN passR( ) ----> haveR=true; dirtyR=false; [ ] passL( ) -----> haveL=true; dirtyL=false; [ ] needR( ) st dirtyR ---> haveR=false; dirtyR=false; send waiter[rigth].passL( ); send waiter[rigth].needL( ); [ ] needL( ) st dirtyL ---> haveL=false; dirtyL=false; send waiter[left].passR( ); send waiter[left].needR( ); NI Programación Concurrente 2004 - Clase 11

Page 11: Qué vimos la clase pasada?

14-6-2004 11

Filósofos descentralizados. Proceso Waiter

# Al salir del lazo WHILE el Waiter tiene los dos tenedores para# su filosofo. Debe dejarlo comer y esperar que los libere send Eat ( ); dirtyL=true; dirtyR=true; receive Relforks( );

[ ] needR ( ) ----> # Waiter vecino requiere mi tenedor derecho (su izquierdo) haveR=false; dirtyR=false; send waiter[rigth].passL( );[ ] needL ( ) ----> # Waiter vecino requiere mi tenedor izquierdo (su derecho) haveL=false; dirtyL=false; send waiter[left].passR( );NI}End Waiter

Programación Concurrente 2004 - Clase 11

Page 12: Qué vimos la clase pasada?

14-6-2004 12

Filósofos descentralizados. Procesos Filósofo y Main

Process Philosopher [i=0 to 4] { WHILE (true) Call Waiter[i].Getforks ( ); COMER; Call Waiter[i].Relforks( ); PENSAR; }}Process Main { send Waiter[0].forks(true, true, true, true); send Waiter[1].forks(false,false, true, true); send Waiter[2].forks(false, false, true, true); send Waiter[3].forks(false, false, true, true); send Waiter[4].forks(false, false, false, false);}

Programación Concurrente 2004 - Clase 11

Page 13: Qué vimos la clase pasada?

14-6-2004 13

Conceptos de RPC y Rendezvous.

El pasaje de mensajes (sincrónico o asincrónico) se ajusta muy bien a los problemas de filtros y pares que interactúan. Siempre se plantea la comunicación unidireccional. Cuando resolvemos C/S la comunicación bi-direccional obliga a especificar 2 tipos de canales (requerimientos y respuestas).

RPC (Remote Procedure Call) y Rendezvous son técnicas de comunicación y sincronización entre procesos que suponen un canal bidireccional. Por esto son ideales para programar aplicaciones Cliente-Servidor.

Programación Concurrente 2004 - Clase 9

Page 14: Qué vimos la clase pasada?

14-6-2004 14

Conceptos de RPC y Rendezvous.

Supongamos una arquitectura multiprocesador con tareas o procesos que serán “servidores” de otras tareas o procesos que funcionan como clientes.

RPC y Rendezvous combinan una interfaz “tipo monitor” con operaciones que se exportan a través de llamadas externas (CALL) con mensajes sincrónicos (demoran al llamador).

Programación Concurrente 2004 - Clase 9

Page 15: Qué vimos la clase pasada?

14-6-2004 15

Conceptos de RPC y Rendezvous. Diferencias

En RPC la idea es que existe alguna forma de “sistema operativo” o administrador de procesos que “controla” los procesos servidores.

Ante un pedido de un servicio activa (“crea”) el servidor y entrega el servicio al cliente.

Para el cliente, durante la ejecución del servicio, es como si tuviera en su sitio el proceso remoto que lo sirve.(Ejemplo: JAVA)

Programación Concurrente 2004 - Clase 9

Page 16: Qué vimos la clase pasada?

14-6-2004 16

Conceptos de RPC y Rendezvous. Diferencias

Programación Concurrente 2004 - Clase 9

EL Rendezvous supone un modelo de tareas (procesos) concurrentes que existen y pueden jugar el rol de clientes o servidores.

Es el modelo de CSP extendido para soportar procesos dinámicos y canales bidireccionales. (Ejemplo típico: ADA).

Un proceso servidor reside siempre en un dado procesador físico.

Page 17: Qué vimos la clase pasada?

14-6-2004 17

Conceptos de Rendezvous.

El concepto básico es que un programa concurrente se compone de procesos independientes que se pueden sincronizar.

La sincronización “acopla” las tareas concurrentes, estableciendo un link bidireccional donde el proceso que llama se demora hasta recibir la respuesta del proceso llamado.

El rol de servidor o cliente puede alternarse entre los procesos (tareas) e incluso una misma tarea puede ser servidor para algunos procesos y cliente para otros.

Programación Concurrente 2004 - Clase 9

Page 18: Qué vimos la clase pasada?

14-6-2004 18

Lenguaje ADA y Rendezvous.

Desde el punto de vista de la concurrencia, un programa Ada tiene “tasks” (procesos) que se pueden ejecutar independientemente (sobre distintos procesadores) y que contienen primitivas de sincronización.

Los puntos de invocación (es decir de "entrada") a un proceso concurrente o task se denominan ENTRYs y están especificados en la parte visible del TASK.

Un TASK puede decidir si "acepta" la comunicación con otro proceso,mediante la primitiva ACCEPT.Un aspecto muy importante de ADA es que podemos declarar un TIPO TASK, y luego crear instancias del proceso identificado con dicho tipo que se necesiten en la ejecuciòn.

Programación Concurrente 2004 - Clase 9

Page 19: Qué vimos la clase pasada?

14-6-2004 19

TASKs en lenguaje ADA.

La forma más común de una especificación de task es:TASK identifier IS declaraciones de ENTRYsend;

La forma más común de un cuerpo de task es:

TASK body identifier IS declaraciones locales

BEGIN sentenciasEND identifier;

Programación Concurrente 2004 - Clase 9

Page 20: Qué vimos la clase pasada?

14-6-2004 20

TASKs en lenguaje ADA.

Una especificación de TASK define una única tarea. Una instancia del correspondiente task body se crea en el bloque en el cual se declara el TASK.

Ada también soporta arreglos de tareas, pero de manera distinta a la de la mayoría de otros lenguajes.

En particular, el programador primero declara un task type y luego declara un arreglo de instancias de ese tipo.

Programación Concurrente 2004 - Clase 9

Page 21: Qué vimos la clase pasada?

14-6-2004 21

TASKs en lenguaje ADA.

También se puede usar task types en conjunción con punteros (access types) para crear tasks dinámicamente.

Ada no provee ningún mecanismo para asignar tasks a procesadores y por lo tanto para controlar el layout de un programa distribuido.

Si fuera necesario, tiene que ser expresado en un lenguaje de configuración específico de la implementación.

Programación Concurrente 2004 - Clase 9

Page 22: Qué vimos la clase pasada?

14-6-2004 22

Constructores del lenguaje ADA para sincronización.

El rendezvous es el único mecanismo de sincronización en Ada y también es el mecanismo de comunicación primario.Las declaraciones de entry son muy similares a las declaraciones op. entry identifier(formales)

Los parámetros del entry en Ada pueden ser IN, OUT o IN OUT.Ada también soporta arreglos de entries, llamados familias de entry.

Si el task T declara el entry E, otras tasks en el alcance de la especificación de T pueden invocar a E por una sentencia call:

call T.E(reales)

Como es usual, la ejecución de call demora al llamador hasta que la operación E terminó (o abortó o alcanzó una excepción).

Programación Concurrente 2004 - Clase 9

Page 23: Qué vimos la clase pasada?

14-6-2004 23

TASKs en lenguaje ADA.

Por ejemplo un mailbox único para mensajes de un tipo mensaje puede ser implementado por una task. La parte visible exporta dos entries: depositar y retirar:TASK TYPE Mailbox IS ENTRY Depositar(msg: IN mensaje); ENTRY Retirar(msg: OUT mensaje);END Mailbox;A, B, C : Mailbox; -- Se declaran 3 instancias del tipo Mailbox.

TASK BODY Mailbox IS-- DeclaracionesBEGIN -- Implementación de los entries Depositar y Retirar

END Mailbox;Podemos utilizar estos mailbox para manejar mensajes del siguiente modo:call A.Depositar(x1);call B.Depositar(x2);call C.Retirar(x3);

Programación Concurrente 2004 - Clase 9

Page 24: Qué vimos la clase pasada?

14-6-2004 24

Sincronización en ADA.

La task que declara un entry sirve llamados de ese entry por medio de la sentencia accept.

accept E(formales) do lista de sentenciasend;

La ejecución de accept demora la tarea hasta que haya una invocación de E, copia los argumentos de entrada en los formales de entrada, luego ejecuta la lista de sentencias. Cuando la lista de sentencias termina, los formales de salida son copiados a los argumentos de salida. En ese punto, tanto el llamador como el proceso ejecutante continúan.

Una sentencia accept es como una input statement con una guarda.

Programación Concurrente 2004 - Clase 9

Page 25: Qué vimos la clase pasada?

14-6-2004 25

Sentencia ACCEPT en ADA.

Si ponemos:

ACCEPT E1(parámetros formales) DO cuerpo de E1 END E1;ACCEPT E2(parámetros formales) DO cuerpo de E2 END E2;ACCEPT E3(parámetros formales) DO cuerpo de E3 END E3;

Se especifica que se espera un pedido por el entry E1, luego de atendido se espera un pedido por el entry E2 y luego de atendido un pedido por el entry E3 que será atendido. NOTAR que el orden es fundamental para no tener un deadlock.

Programación Concurrente 2004 - Clase 9

Page 26: Qué vimos la clase pasada?

14-6-2004 26

La sentencia ACCEPT en ADA.

Podemos ejecutar repetidamente una secuencia de atención de pedidos como la anterior, mientras se dé una condición lógica:WHILE (condicion booleana) LOOP ACCEPT E1(parámetros ) DO cuerpo de E1 END E1; ACCEPT E2(parámetros ) DO cuerpo de E2 END E2; ACCEPT E3(parámetros ) DO cuerpo de E3 END E3;END LOOP

Aplicado a nuestro ejemplo anterior, supondría un lazo como éste:LOOP ACCEPT Depositar (msg: IN mensaje) DO ... END Depositar; ACCEPT Retirar (msg: OUT mensaje) DO ... END Depositar;END LOOP;

Notar que esta manera de escribir el código supone una secuencia exacta: a cada Depositar le seguirá un Retirar.

Programación Concurrente 2004 - Clase 9

Page 27: Qué vimos la clase pasada?

14-6-2004 27

Waiting selectivo en ADA (Select).

La sentencia wait selectiva soporta comunicación guardada. select when B1 sentencia accept; sentenciasor ...or when Bn sentencia accept; sentenciasend select

Cada línea (salvo la última) se llama alternativa. Las Bi son expresiones booleanas, y las cláusulas when son opcionales. Una alternativa se dice que está abierta si Bi es true o se omite la cláusula when.

Esta forma de wait selectivo demora al proceso ejecutante hasta que la sentencia accept en alguna alternativa abierta pueda ser ejecutada, es decir, haya una invocación pendiente del entry nombrado en la sentencia accept.

Programación Concurrente 2004 - Clase 9

Page 28: Qué vimos la clase pasada?

14-6-2004 28

Un ejemplo de waiting selectivo en ADA.

LOOP SELECT WHEN numero < capacidad => ACCEPT Depositar (msg: IN mensaje) DO -- Acciones -- Incrementar numero END Depositar; OR WHEN numero > 0 => ACCEPT Retirar (msg: OUT mensaje) DO -- Acciones -- Decrementar numero END Retirar; END SELECT;END LOOP;

Programación Concurrente 2004 - Clase 9

Page 29: Qué vimos la clase pasada?

14-6-2004 29

Lectores-Escritores en ADA.

Implementación de Lectores-Escritores TASK TYPE Scheduler IS ENTRY InicioLeer; ENTRY FinLeer; ENTRY InicioEscribir; ENTRY FinEscribir;END Scheduler; TASK BODY Scheduler IS NumLectores: INTEGER:=0; 

Programación Concurrente 2004 - Clase 9

Page 30: Qué vimos la clase pasada?

14-6-2004 30

Lectores-Escritores en ADA.

BEGIN LOOP SELECT WHEN InicioEscribir'COUNT = 0 => ACCEPT InicioLeer DO NumLectores:= NumLectores+1; END InicioLeer; OR ACCEPT FinLeer DO NumLectores:= NumLectores -1 ; END FinLeer;

Programación Concurrente 2004 - Clase 9

Page 31: Qué vimos la clase pasada?

14-6-2004 31

Lectores-Escritores en ADA.

OR WHEN NumLectores=0 => ACCEPT InicioEscribir; ACCEPT FinEscribir; FOR i IN 1..InicioLeer'COUNT LOOP ACCEPT InicioLeer DO NumLectores:= NumLectores +1; END InicioLeer; END LOOP; END SELECT; END LOOP;END Scheduler;

Programación Concurrente 2004 - Clase 9

Page 32: Qué vimos la clase pasada?

14-6-2004 32

Remote Procedure Call

En RPC los programas se descomponen en módulos que contienen procesos y procedimientos. Los módulos pueden residir en espacios de direcciones distintos.

Los procesos de un módulo pueden compartir variables y llamar a procedures declarados en ese módulo.

Un proceso en un módulo puede comunicarse con procesos de otro módulo invocando procedimientos de éste.

Los módulos tienen especificación e implementación de procedimientos.

Programación Concurrente 2004 - Clase 9

Page 33: Qué vimos la clase pasada?

14-6-2004 33

Remote Procedure Call

module Mname headers de procedures visibles

body declaraciones de variables código de inicialización cuerpos de procedures visibles procedures y procesos localesend

Programación Concurrente 2004 - Clase 9

Page 34: Qué vimos la clase pasada?

14-6-2004 34

Remote Procedure Call

El header de un procedure visible tiene la forma:op opname (formales) returns result

El cuerpo de un procedure visible es contenido en una declaración proc:proc opname(identif. formales) returns identificador resultado variables locales instruccionesend

Un proceso (o procedure) en un módulo llama a un procedure en otro ejecutando:

call Mname.opname (argumentos)

Para un llamado local, el nombre del módulo se puede omitir.

Programación Concurrente 2004 - Clase 9

Page 35: Qué vimos la clase pasada?

14-6-2004 35

Sincronización en RPC

La implementación de un llamado intermódulo es distinta que para un llamado local: un nuevo proceso sirve el llamado.El proceso llamador se demora mientras el proceso servidor ejecuta el cuerpo del procedure que implementa opname.

Si el proceso llamador y el procedure están en el mismo espacio de direcciones, es posible evitar crear un nuevo proceso.

En general, un llamado será remoto se debe crear un proceso server o alocarlo de un pool preexistente de servers.

Programación Concurrente 2004 - Clase 9

Page 36: Qué vimos la clase pasada?

14-6-2004 36

Sincronización en RPC

Por sí mismo, RPC es solo un mecanismo de comunicación.

Aunque un proceso llamador y su server sincronizan, el único rol del server es actuar por invocación del llamador (es como si el llamador mismo estuviera ejecutando el llamado, y así la sincronización entre el llamador y el server es implícita).

Necesitamos que los procesos en un módulo sincronicen (procesos server ejecutando llamados remotos y procesos del módulo). Esto comprende exclusión mutua y sincronización por condición.

Programación Concurrente 2004 - Clase 9

Page 37: Qué vimos la clase pasada?

14-6-2004 37

Sincronización en RPC

Existen dos enfoques para proveer sincronización, dependiendo de si los procesos en un módulo ejecutan con exclusión mútua (un solo proceso por vez) o concurrentemente.

Si ejecutan con exclusión mútua las variables compartidas son protegidas automáticamente contra acceso concurrente, pero los procesos necesitan programar sincronización por condición.

Si pueden ejecutar concurrentemente necesitamos mecanismos para programar exclusión mutua y sincronización por condición(cada módulo es en sí mismo un programa concurrente podemos usar cualquier método ya descripto (semáforos, monitores, o incluso rendezvous).

Programación Concurrente 2004 - Clase 9

Page 38: Qué vimos la clase pasada?

14-6-2004 38

Sincronización en RPC

Es más general asumir que los procesos pueden ejecutar concurrentemente (puede ser mucho más eficiente en un multiprocesador de memoria compartida).

Asumiremos que los procesos dentro de un módulo ejecutan concurrentemente, utilizando por ejemplo time slicing.

Por ahora, usamos semáforos para programar exclusión mutua y sincronización por condición; Se verá luego el agregado de rendezvous y comunicación guardada.

Programación Concurrente 2004 - Clase 9

Page 39: Qué vimos la clase pasada?

14-6-2004 39

Ejemplo con RPC: Time Server

Módulo que provee servicios de timing a módulos cliente.Dos operaciones visibles: get_time y delay( interval )Un proceso interno que continuamente inicia un timer por hardware, luego incrementa el tiempo al ocurrir la interrupción de timer.

module TimeServer op get_time( ) returns INT; #recupera la hora del día op delay(INT interval ); #intervalo entre ticksbody INT tod = 0; #hora del día SEM m= 1; # semáforo para exclusión mútua SEM d[n] = ([n] 0); # semáforos de demora privados QUEUE of (INT waketime, INT proces_id) napQ; proc get_time ( ) returns time { time := tod; }

Programación Concurrente 2004 - Clase 9

Page 40: Qué vimos la clase pasada?

14-6-2004 40

Ejemplo en RPC: Timer Server

proc delay(interval) { # asumimos interval > 0INT waketime = tod + interval;P(m)insert (waketime, myid) en el lugar apropiado de napQ;V(m);P(d[myid]); # espera a ser despertado

}Process Clock { Inicia timer por hardware; WHILE (true) { Esperar interrupción, luego rearrancar timer;

tod := tod + 1; P(m); WHILE tod menor waketime en napQ { remove (waketime, id) de napQ; V(d[id]); #despierta el proceso Id } V(m);}

}end TimeServer;

Programación Concurrente 2004 - Clase 9

Page 41: Qué vimos la clase pasada?

14-6-2004 41

Ejemplo en RPC: Timer Server

Múltiples clientes pueden llamar a get_time y a delay a la vez múltiples procesos “servidores” estarían atendiendo los llamados concurrentemente.

Los pedidos de get_time se pueden atender concurrentemente porque sólo significan leer la variable tod.

delay y clock necesitan ejecutarse con exclusión mutua porque ambos manipulan napQ, la cola de procesos cliente "durmiendo”.

El valor de myid en delay se supone que es un entero único entre 0 y n-1. Se usa para indicar el semáforo privado sobre el cual está esperando un cliente.

Programación Concurrente 2004 - Clase 9

Page 42: Qué vimos la clase pasada?

14-6-2004 42

Manejo de caches en un sistema de archivos distribuidos con RPC.

Supongamos un sistema distribuido con n workstations ejecutando procesos, y una base de datos con archivos en un file server. Los programas de aplicación que quieren acceder a datos del file server, llaman procedimientos read y write de un módulo local que llamaremos FileCache. Se supone que se leen o escriben arreglos de caracteres.

Los archivos están almacenados en el FileServer en bloques de 1024 bytes, fijos. El módulo FileServer provee el servicio de lectura y escritura de bloques con los procedimientos ReadBlk y WriteBlk.

El módulo FileCache mantiene en memoria los bloques recientemente leídos. Un read puede ser atendido “localmente” o no. Idem con las operaciones de Write. Cuando no se pueden atender localmente se produce la comunicación con FileServer.

Programación Concurrente 2004 - Clase 9

Page 43: Qué vimos la clase pasada?

14-6-2004 43

File Cache con RPC.

Module FileCache # ubicado en cada workstation op read (INT count ; result CHAR buffer[ *] ); op write (INT count; CHAR buffer[*] );body declaración del cache de N bloques de archivo; variables para la descripción de los registros de cada file; declaración de los semáforos para sincronización de acceso al cache; proc read (count, buffer) { IF (los datos pedidos no están en el cache) { seleccionar los bloques del cache a usar; IF (se necesita vaciar parte del cache); FileServer.writeblk(....); FileServer.readblk(....); } buffer= número de bytes requeridos del cache; }

Programación Concurrente 2004 - Clase 9

Page 44: Qué vimos la clase pasada?

14-6-2004 44

File Cache con RPC.

proc write(count, buffer) { IF (los datos apropiados no están en el cache) { seleccionar los bloques del cache a usar; IF (se necesita vaciar parte del cache); FileServer.writeblk(....); } bloquedeCache= número de bytes desde buffer; } end FileCache;

Notar que los llamados de los programas de aplicación de las Workstations son locales a su FileCache, pero desde estos módulos se invocan los procesos remotos de FileServer. FileServer tiene UN cliente por workstation.

Programación Concurrente 2004 - Clase 9

Page 45: Qué vimos la clase pasada?

14-6-2004 45

Manejo de caches en un sistema de archivos distribuidos con RPC.

Si existe un FileCache por programa de aplicación, no se requiere sincronización interna entre los read y write, porque sólo uno puede estar activo. Si múltiples programas de aplicación usaran el mismo FileCache, tendríamos que usar semáforos para implementar la exclusión mútua en el acceso a FileCache.

En cambio en el FileServer (atiende múltiples FileCache) requeriremos sincronización interna. También con el proceso DiskDriver.

A continuación se ve el código (simplificado) del FileServer con RPC.

Programación Concurrente 2004 - Clase 9

Page 46: Qué vimos la clase pasada?

14-6-2004 46

File Server con RPC.

Module FileServer # ubicado en el servidor op readblk (INT fileid, offset; result CHAR blk[1024] ); op writeblk (INT fileid, offset; CHAR blk[1024] );body declaración del cache de bloques del disco; cola de pedidos pendientes de acceso al disco; declaración de semáforos para acceso al cache y a la cola; # a continuación no se ve el código de sincronización. proc readblk (fileid, offset, blk) { IF (los datos pedidos no están en el cache) { almacenar el pedido de lectura en la cola del disco; esperar que la operación de lectura sea procesada; } blk= bloques pedidos del disco; }

Programación Concurrente 2004 - Clase 9

Page 47: Qué vimos la clase pasada?

14-6-2004 47

File Server con RPC.

proc writeblk (fileid, offset, blk) { Ubicar el bloque en el cache; IF (es necesario grabar físicamente en el disco) { almacenar el pedido de escritura en la cola del disco; esperar que la operación de escritura sea procesada; } bloque cache = blk; }process DiskDriver { WHILE (true) { wait por un pedido de acceso físico al disco; arrancar una operación física; esperar interrupción; despertar el proceso que está esperando completar el request; }}end FileServer;

Programación Concurrente 2004 - Clase 9

Page 48: Qué vimos la clase pasada?

14-6-2004 48

RPC programando filtros o interacción entre pares

El problema de construir una red de filtros (por ejemplo para el sorting by merging) es algo más complicado con RPC que con mensajes.Esto se debe a que no es un problema “tipo Cliente-Servidor”. Pueden analizar la solución en el texto de Andrews.

El intercambio de valores entre pares, por ejemplo el problema que resolvimos en clases anteriores con mensajes asincrónicos resulta algo más “pesado” con RPC. Queda para el alumno pasar la solución con AMP a RPC.

Programación Concurrente 2004 - Clase 9