! " # " # & ' '()*+ 0" #*



Documentos relacionados
Tema 4: Modelos Teóricos de Control de la Concurrencia

MONITORES EN JAVA. Antonio Tomeu Control de la Concurrencia en Java: API Estándar

PROGRAMACIÓN CONCURRENTE. Tema 5 Monitores

Concurrencia: deberes. Concurrencia: Exclusión Mutua y Sincronización. Concurrencia. Dificultades con la Concurrencia

CDI Exclusión mutua a nivel alto. conceptos

El problema de los Filósofos

Concurrencia: Exclusión mutua y Sincronización

Tema 3: Concurrencia de procesos

Mensajes. Interbloqueo

Concurrencia. Primitivas IPC con bloqueo

Tema 3. Monitores Programación Concurrente

Implementación de monitores POSIX

PROGRAMACION CONCURRENTE

Sistemas Operativos Temas 4, 5 y 6. Jorge García Duque Despacho: B-202 Tutorías: Lunes 16:00-18:00 y Martes 16:00-20:00

un programa concurrente

Programación Concurrente y Paralela. P(S) ; sección crítica P(S);

Concurrencia entre Procesos.

PROGRAMACION CONCURRENTE

dit UPM Tema 3: Concurrencia /ejercicios Análisis y diseño de software José A. Mañas

Práctica 2: El problema de la sección crítica

Ingeniería Superior de Informática. Curso 3º. Sistemas Operativos. Examen Final. TEORÍA. 31 de Enero de 2005

1 (2 5 puntos) Responda con brevedad y precisión a las siguientes preguntas:

I.3. Interacción entre Procesos Concurrentes.

SISTEMAS OPERATIVOS AVANZADOS

Sistemas Operativos. Características de la Multiprogramación. Interacción entre Procesos. Características de la Multiprogramación

PROGRAMACIÓN EN JAVA

1. Equivalencia de herramientas. Implemente las primitivas de las regiones críticas condicionales con semáforos. (2pt).

CAPÍTULO 8. Comunicación y sincronización basada en variables compartidas

Paso de mensajes. Lecturas: Burns & Wellings, Cap.??? Transparencias y apuntes de la asignatura. Filosofía cliente-servidor.

TEMA 5: Control de la Concurrencia en Java (API Estándar)

Programación Concurrente en Java

Multitarea en Java. Rafa Caballero - UCM

PROGRAMACION CONCURRENTE Y DISTRIBUIDA. II.5 Sincronización basada en memoria compartida: Monitores

Sistemas Operativos Práctica 4

Examen de Programación Concurrente - Clave: a Junio 2008 Departamento de Lenguajes, Sistemas Informáticos e Ingeniería del Software.

Escuela Politécnica Superior de Ingeniería Departamento de Ingeniería Informática

Memoria compartida y semáforos r/w. La página del manual que podría servir para describir estas funciones es la siguiente:

Secciones críticas y exclusión mutua

Solución Examen Febrero 2006

Threads. La plataforma JAVA soporta programas multhreading a través del lenguaje, de librerías y del sistema de ejecución. Dos.

Programación Orientada a Eventos

Receta general para resolver problemas de sincronización con semáforos

Primitivas de Sincronización (continuación) MONITORES: Primitiva de alto nivel, es a nivel de lenguajes como: ADA, PASCAL, JAVA.

Procesadores de lenguaje Tema 5 Comprobación de tipos

Java RMI. las RPC de Java. Parte I. Luis Fernando Llana Díaz. Departamento de Sistemas Informáticos y ProgramaciónUniversidad Complutense de Madrid

Mensajes. (versión preliminar)

Examen Febrero de 2012

Examen escrito de Programación 1

4. Programación Paralela

BENEMERITA UNIVERSIDAD AUTONOMA DE PUEBLA FACULTAD DE CIENCIAS DE LA COMPUTACIÓN LICENCIATURA EN CIENCIAS DE LA COMPUTACIÓN

RESUMEN DE CONCEPTOS BASICOS DE PROGRAMACION JAVA

Semántica Denotacional

Benemérita Universidad Autónoma del Estado de Puebla

Modulo 1 El lenguaje Java

ARBOLES ARBOLES BINARIOS ORDENADOS. REPRESENTACIÓN Y OPERACIONES

SIMM: TEORÍA DE LOS S.O. I.E.S. JUAN DE LA CIERVA CURSO 2007/2008

Tema 2. El lenguaje de programación Java (Parte 1)

DEFINICION. Ing. M.Sc. Fulbia Torres Asignatura: Estructuras de Datos Barquisimeto 2006

2. Estructura de un programa en Java

Sincronización de Procesos

1 HILOS (THREADS) EN JAVA

1. Ejemplo de clase : La clase Cuenta 2. Uso de la clase Cuenta. 3. Métodos y objetos receptores de mensajes (Importante)

Contenido. Qué es el interbloqueo? Cómo prevenirlo? Cómo evitarlo? Cómo detectarlo? Interbloqueo. Cruce en un Puente. Qué es?

Algorítmica y Lenguajes de Programación. Ordenación (i)

Tema 4.- Pilas y Colas

Tecnólogo Informático- Estructuras de Datos y Algoritmos- 2009

1. Descripción y objetivos

Monitores. Implementación de un Buffer con monitores

Benemérita Universidad Autónoma del Estado de Puebla

Concurrencia en.net David Jesús Horat Flotats

Programación Concurrente en Java

Comunicación y Sincronización con Monitores Resumen del Tema

Práctica sobre compartición de instancias remotas.

Asignatura: Administración de Bases de Datos. Pedro P. Alarcón Cavero

CONCEPTOS BASICOS DEL LENGUAJE JAVA

NIVEL 15: ESTRUCTURAS RECURSIVAS BINARIAS

Primer Parcial Septiembre 5 de 2009

Programación Concurrente Recopilación de teoría referente a la materia

Concurrencia en Java

Grafo acíclico orientado cuyos nodos corresponden a sentencias individuales.

Java: Programación Multithread

Repaso de las características más importantes de la programación Java y su adaptación a Android

GENERACIÓN DE CÓDIGO

Una (muy) breve introducción a la teoría de la computación

Actividades de Divulgación del Centro Atómico Bariloche. Qué hay detrás de un programa de computadora? Daniela Arnica Pablo E. Argañaras.

Árboles. Cursos Propedéuticos Dr. René Cumplido M. en C. Luis Rodríguez Flores

Introducción a Java LSUB. 15 de enero de 2015 GSYC

Elementos léxicos del lenguaje de programación Java

Examen de Fundamentos de sistemas distribuidos

FUNDAMENTOS DE PROGRAMACIÓN. SEPTIEMBRE 2005

Sincronización de Procesos. Módulo 6. Departamento de Ciencias e Ingeniería de la Computación Universidad Nacional del Sur. Sincronización de Procesos

Capítulo IV. INTERBLOQUEO E INANICIÓN

ARBOLES ARBOLES BINARIOS ORDENADOS. REPRESENTACIÓN Y OPERACIONES

Examen final de CL 11 de Enero de 2012 Fecha de publicación de notas: Fecha de revisión:

Manual del Protocolo XML-RPC de Mensajería Negocios

15. Arquitectura de los multiprocesadores. 16. Multiprocesadores de memoria compartida. 17. Multicomputadores.

Java nos ofrece la clase Thread y la interfaz Runable que permiten que varios procesos estén funcionando de forma concurrente.

Tema 4. Gestión de entrada/salida

Transcripción:

! " # " # $% & ' '()*+ #* *' ++,-"./" [Ben90] Ben-Ari, M. Concurrent and Distributed Programming Prentice Hall, 1990. [Capítulos 3, 4, 5, 6 7 y 8 ] [Ray83] Raynal, M. Algorithms for Mutual Exclusion. MIT Press, 1986. [Pal03] Palma, J. et al. Programación Concurrente. [Capítulos 4, 5 y 6] [Tom03] Tomeu, A. Apuntes de Prog. Concurrente. [Tema 3]

Niveles de Exclusión Mutua-Sincronización LENGUAJE SISTEMA MONITORES, REGIONES CRÍTICAS SEMÁFOROS MEMORIA ESPERA OCUPADA

1 ) (! * #',# '' ( * (2 2! 3)( 1 '!''" #! #&' 4& 5 ( 2&6 '' 4* #&' '

! # 2 3' # 2 )6 ## % 71! 2 8' " #99((:4(: (#5-(,' 4% ) 57 *1#)&'

" # $ Turno: integer range 1..2 := 1; task body P2 is loop Resto_código_2; loop exit when Turno = 2; Sección_Crítica_2; Turno := 1; end P2; task body P1 is loop Resto_código_1; loop exit when Turno = 1; Sección_Crítica_1; Turno := 2; end P1;

l5 l6 l1 l3 l2 t1 TEOREMA: LA SOLUCIÓN DE TURNOS CONSERVA LA EM SOBRE LAS SECCIONES CRÍTICAS Y ESTÁ LIBRE DE INTERBLOQUEOS -Demostración: transformar a RdP pura, extraer sistemas de ecuaciones y resolver PA para E.M. e INTREBLOQUEO t3 l4 t2 t4

" # $ C1, C2: integer range 0..1 := 1; task body P1 is loop RC1 t1 L1 t2 SC1 Resto_código_1; loop exit when C2 = 1; C1 := 0; Sección_Crítica_1; C1 := 1; t3 end P1; task body P2 is loop RC2 t4 L2 t5 SC2 Resto_código_2; loop exit when C1 = 1; C2 := 0; Sección_Crítica_2; C2 := 1; t6 end P2;

c1=1 c2=1 RC1 RC2 t1 t4 L1 L2 t2 t5 SC1 SC2 t3 c1=0 c2=0 t6

% & +,"3"3",3;".";3"3" TEOREMA: LA RdP ANTERIOR NO CONSERVA LA EM SOBRE LAS SECCIONES CRÍTICAS -Demostración: transformar a RdP pura, extraer sistema de ecuacione y resolver PA para E.M <""=">""?"".";" 3"

'" # ( $ C1, C2: integer range 0..1 := 1; task body P1 is loop Resto_código_1; C1 := 0; loop exit when C2 = 1; Sección_Crítica_1; C1 := 1; end P1; RC1 T1 L1,t2 SC1 t3 task body P2 is loop Resto_código_2; C2 := 0; loop exit when C1 = 1; Sección_Crítica_2; C2 := 1; end P2; RC2 T4 L1,t5 SC2 t3

c1=0 c2=0 RC1 RC2 t1 t4 L1 L2 TEOREMA: AMBOS PROCESOS SE INTERBLOQUEAN EN SUS LAZOS DE ESPERA OCUPADA (L1 y L2) t2-demostración: transformar a RdP pura, extraer sistema t5 de ecuaciones y resolver PA para interbloqueo SC1 SC2 t3 c1=1 c2=1 t6

)" #* +* C1, C2: integer range 0..1 := 1; task body P1 is loop Resto_código_1; C1 := 0; loop exit when C2 =1; C1 := 1; C1 := 0; Sección_Crítica_1; C1 := 1; end P1; task body P2 is loop Resto_código_2; C2 := 0; loop exit when C1 = 1; C2 := 1; C2 := 0; Sección_Crítica_2; C2 := 1; end P2;

)" #* +* Respeta la exclusión mutua Presenta una forma de bloqueo débil (livelock) dada por una secuencia de entrelazado cuál es? Puede haber procesos hambrientos Ejercicio: Extraer RdP y verificar su análisis

%,--.,--/01234 Turno : Integer range 0..1 := 1; C1, C2: integer range 1..2 := 1; task body P1 is loop Resto_código_1; C1 := 0; loop exit when C2=1; if Turno=2 then C1:=1; loop exit when Turno:=1; C1 := 0; end if; Sección_Crítica_1; C1 := 1; Turno := 2; end P1; task body P2 is loop Resto_código_2; C2 := 0; loop exit when C1=1; if Turno=1 then C2:=1; loop exit then Turno=2; C2 := 0; end if; Sección_Crítica_2; C2 := 1; Turno := 1; end P2;

% %,-- Exclusión Mutua Libertad de Interbloqueos No hay procesos hambrientos Hay progreso en la ejecución Generalizable a n procesos [Dijkstra] Complejo y poco intuitivo

%. /01504 C1, C2: boolean := false; Turno : integer range 1..2; task body P1 is RC1 u1 u2, u3 u4, u5 SC1 u6 loop Resto_código_1; C1 := true; Turno := 2 ; while (C2 and Turno=2)do; Sección_Crítica_1; C1 := false; end P1; RC2 v1 task body P2 is loop Resto_código_2; C2 := true; Turno := 1; while (C1 and Turno=1)do; Sección_Crítica_2; C2 := false; end P2; v2, v3 v, v5 SC2 v6

C1:=false C2:=false RC1 RC2 u6 u1 C1:=true v1 C2:=true v6 u2 TEOREMA: CONSERVA LA E.M. Y ESTÁ LIBRE DE INTERBLOQUEOS. v2 u3 Turno:=1 -Demostración: transformar a RdP pura, extraer sistemas de ecuaciones y resolver PA en ambos casos v3 COROLARIO: NO HAY PROCESOS HAMBRIENTOS Y LA EJECUCIÓN PROGRESA SIEMPRE u5 v5 u4 v4 SC1 Turno:=2 SC2

% 6.6 /01224 var flag: array [0..1] of boolean; (*inicialmente FALSE*) turn: 0..1 := 0; INCORRECTO! repeat flag[0]:= true; while turn <> 0 do while flag[1] do end do; turn:= 0; enddo; 4 <seccion critica>; flag[0]:= false; until false; 3 repeat 1 flag[1]:= true; while turn <> 1 do 2 while flag[0] do end do; 5turn:= 1; enddo; 6<seccion critica>; flag[1]:= false; until false;

% 7 var c: array[0..n-1] of (pasivo, solicitando, en-cs); (*inicialmente 'pasivo'*) turn0: 0..n-1; (*valor 0 ó 1, inicialmente*) repeat c[i]:=solicitando; j:=turno //j es local a cada proceso while j<>i do if c[j]<>pasivo then j:=turno else j:= (j-1) mod n;endif; end; c[i]:=en-sc; k:=0; while (k<n) and (k=i or c[k]<> en-sc) do j:=j+1 enddo; until k>=n; turno:=i; <seccion critica>; turn:= (i-1) mod n; c[i]:=pasivo;

% 7 var flag: array[0..1] of boolean; (*inicialmente FALSE*) turn: array[0..1] of 0..1; (*valor 0 ó 1, inicialmente*) repeat flag[0]:= true; turn[0]:= turn[1] + 0 mod 2; while (flag[1] and turn[0]= turn[1] + 0 mod 2) do nothing end do; <seccion critica> flag[0]:= false; until false; repeat flag[1]:= true; turn[1]:= turn[0] + 1 mod 2; while (flag[0] and turn[1]= turn[0] + 1 mod 2) do nothing end do; <seccion critica> flag[1]:= false; until false;

% 8 N1, N2: Integer := 0; task body P1 is loop Resto_código_1; N1 := 1; N1 := N2+1; loop exit when N2=0 or N1<=N2; Sección_Crítica_1; N1 := 0; end P1; task body P2 is loop Resto_código_2; N2 := 1; N2 := N1+1; loop exit when N1=0 or N2<N1; Sección_Crítica_2; N2 := 0; end P2;

% 8+.8 9:4 Choosing: array (1..N) of integer (others=>0); Number: array (1..N) of integer (others=>0); task body Pi is I: constant integer :=..., task id loop Resto_código_I; choosing(i):=1; number (I)=1+max(number); choosing(i):=0; for J in 1..N loop if J<>I then loop exit when chossing(j)=0; loop exit when number(j)=0 or number(i)<number(j) or (number(i)=number(j) and i<j); end loop, end if; Sección_Crítica_I; number(i):=0; end Pi;

! "! 1! 4%

Swap cerradura : boolean := false; Swap (A,B) ";" Temp := B; B := A; A := Temp; Task body Pi is llave: boolean; //local RCi t1-4 L1-2 t2-5 SCi t3-6 loop Resto_Código_i; llave:=true; loop Swap(cerradura,llave); exit when llave=false; Sección_Crítica_i; cerradura:=false; end Pi;

cerradura:=false RC1 llave:=true llave:=true RC2 t1 t4 L1 t2 TEOREMA: t7 LA E.M. SE PRESERVA A NIVEL t8 DE SECCIONES CRITICAS. NO HAY INTERBLOQUEOS -Demostración: extraer sistemas de ecuaciones y resolver PA para E.M. e interbloqueo SC1 llave:=false llave:=false SC2 L2 t5 t3 t6

C: integer /*global*/ Test_and_Set (Li) ";" Li := C; C := 1; Task body Pi is Li: Integer range 0..1; //local loop Resto_Código_i; loop Test_and Set (Li); exit when Li := 0; Sección_Crítica_i; C := 0; end Pi;

(.,-/01234," #'!! 3 ) 2& *#* &* # &2 2 ) # 7

(#,(! 3&! 2! #!* 2 ) ' (1965)' Wait (S)@AB5C' ( ( ' Signal (S)4* '(BDC' Wait (S)=P(S) Signal (S)=V(S)

(#; Wait *Signal! & #! Signal #7( E4..F $ & # B@A & BA(C! 4 2 & = +

(#" Implementación Type semáforo=record of S: integer; L: lista_de_procesos; end;,!! &,(& BA* Wait 2 * G )( # 2,#7 #7 #'

(#" procedure inic(var sem:semaphore; s0:integer); sem.s:=s0; inicializar(sem.l); end; procedure wait(var sem:semaphore); if sem.s>0 then sem.s:=sem.s-1; else sem.l.insertar(proceso); bloquear (proceso); end; end; procedure signal(var sem:semaphore if not sem.l.vacia() then sem.l.eliminar (proceso); desbloquear (proceso); end; else sem.s:=sem.s+1; end;

(# SEMAFOROS CONJUNTO BLOQ. COLA BLOQUEADA ESPERA OCUPADA Wait(S):Inc. S si es mayor 0. Signal(s):Libera proc o dec. S Wait(S):Inc. S si es mayor 0. Signal(s):Libera proc o dec. S COLA FIFO Wait(S):Inc. S si es mayor 0. Signal(s):Libera proc o dec. S ESPERA OCUPADA

( C*H I S: semáforo := 1; Task body P1 is loop RC1 t1 SC1 t2 Resto_1; Wait (S); Sección_Crítica_1; Signal (S); end P1; Task body P2 is loop RC2 t3 SC2 t4 Resto_2; Wait (S); Sección_Crítica_2; Signal (S); end P2;

% <, 2 ', # 2 ( 1! + =

% <*=& S RC1 RC2 t1 t3 SC1 SC2 TEOREMA: LA E.M. SE PRESERVA A NIVEL DE SECCIONES t2 CRITICAS. NO HAY INTERBLOQUEOS t4 -Demostración: obtener matriz de incidencia, extraer sistemas de ecuaciones y resolver PA para E.M. e interbloqueo

( )C*H2H G C' S: semaphore := 0: Task Body P1 is Task Body P2 is RC1 t1 RC2, t2 loop Codigo Signal(S); Codigo end; loop Codigo Wait(S); Codigo end; RC3 t3 RC3, t4

% <*=& RC1 t1 RC3 RC2 S t3 t2 TEOREMA: P1 puede ciclar libremente, pero P2 debe esperar siempre la señal desde P1 RC4 -Demostración: obtener matriz de incidencia, extraer sistemas de ecuaciones y resolver PA para ambas situaciones t4

> ( 3 #2# 424 # I Barrera1 : semaphore := 0; Barrera2 : semaphore := 0; l1 t1,l2 t2 l3,t3 Task Body P1 is loop Signal(Barrera1); Wait(Barrera2); Código_Restante; end; l4 t4,l5 t5 l6,t6 Task Body P2 is loop Signal(Barrera2); Wait(Barrera1); Código_Restante; end;

Barrera1=1 Barrera2=1 t1 t4 t2 t5 t3 Barrera1=0 Barrera2=0 t6 TEOREMA: AMBOS PROCESOS SE SINCRONIZAN AL COMENZAR A EJECUTAR SUS CÓDIGOS RESTANTES -Demostración- Resolver PA correspondiente

)#+) &? 2 "?/!? "! ' & In_Ptr Out_Ptr

% " B: array (0..infinity) of integer; In_Ptr, Out_Ptr: integer:=0; Task body Productor is I:Integer; loop producir (I); B(In_Ptr):=I; In_Ptr:= In_Ptr+1; end Productor; Task body Consumidor is I:Integer; loop I:=B(Out_Ptr); Out_Ptr:= Out_Ptr+1; consumir (I); end Consumidor;

% % " J 7 J 7 = 2 *# ( 2 = + K!& ' ) & 2 *

% >((" ( B: array (0..infinity) of integer; In_Ptr, Out_Ptr: integer:=0; Elements: semaphore:=0; em: semaphore:=1; Task body Productor is I:Integer; loop producir (I); l1 t1 Wait(em); l2 B(In_Ptr):=I; In_Ptr:= In_Ptr+1; t2 Signal (em); Signal(Elements); end Productor; Task body Consumidor is I:Integer; loop Wait (Elements); Wait(em); I:=B(Out_Ptr); Out_Ptr:= Out_Ptr+1; Signal (em); consumir (I); end Consumidor; l5,t3 l6,t4 l7 t5

l1 em l5 t1 t2 l2 Elements t3 l6 t4 TEOREMA: El productor puede producir indiscriminadamente, pero el consumidor debe esperar a que haya al menos un dato en el buffer. l7 -Demostración: obtener matriz de incidencia, extraer sistemas de ecuaciones y resolver PA t5

% >((< B: array (0..N-1) of integer; In_Ptr, Out_Ptr: integer:=0; Elements: semaphore:=0; Spaces: semaphore:=n; em: semaphore:=1; Task body Productor is I:Integer; loop producir (I); Wait (Spaces); Wait(em); B(In_Ptr):=I; In_Ptr:=(In_Ptr+1)modN; Signal (em); Signal(Elements); end Productor; Task body Consumidor is I:Integer; loop Wait (Elements); Wait(em); I:=B(Out_Ptr); Out_Ptr:= (Out_Ptr+1)modN; Signal (em); Signal (Spaces); consumir (I); end Consumidor;

l1 em l5 t1 l2 Elements t3 t2 l6 N TEOREMA: El productor puede producir hasta llenar el buffer, el consumidor debe Spaces esperar a que haya al menos un dato en el buffer, y puede consumir mientras haya objetos en el mismo. l7 t4 -Demostración: obtener matriz de incidencia, extraer sistemas de ecuaciones y resolver PA t5

( ) C dispone de la biblioteca sem.h en el marco de las facilidades IPC. Define conjuntos de semáforos Semántica muy diferente a la estándar de Djikstra Son más potentes Funciones semget, semctl y semop

/*Antonio J. Tomeu-Dpto. LSI-Area CC. e I.A.*/ /*Ejemplo de Wait sobre un semaforo IPC */ #include <stdio.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #include <string.h> #define PERMISOS S_IRUSR S_IWUSR S_IRGRP S_IWGRP S_IROTH S_IWOTH #define TAM 3 #define CLAVE (key_t) 666 void ajustar(struct sembuf *s, int valor, int operacion, int flags); int main (void) { int semid; struct sembuf mioper[tam-1];

semid = semget(clave, TAM, IPC_CREAT PERMISOS); /*Creacion*/ if(semid==-1) printf("error"); semctl (semid, 0, SETVAL, 1); ajustar(&(mioper[0]), 0, -1, 0); semop(semid, mioper,1); /*Wait=>Decremento del semaforo*/ semop(semid, mioper,1); /*Wait=>Bloqueo del proceso*/ /*Eliminacion del conjunto de semaforos*/ semctl(semid, NULL, IPC_RMID);} void ajustar (struct sembuf *s, int valor, int operacion, int flags) { s->sem_num = (short) valor; s->sem_op = operacion; s->sem_flg = flags; return; }

( @* L!&! L!! '' 1E1F L! ) 1 #6''

( @* public class semaforo { private byte S; public void _inicial (byte valor) {S = valor; return;} synchronized public void Wait() { while (S == 0) try{ wait(); } catch (Exception e) {} S--; } } synchronized public void Signal() { S++; notifyall(); }

" * ( +1! ' + ' & # ' 1#2 44!&

& )=.6A> +6 /019B4 3#* 11 &#) &! 2 & "#E! F #EF? 3# *4*'

& )=# var V: shared T;...... region V do S; /*acceso en e.m. a V*/

& )=#,! # 32# #& ( 4 # 3 #* 32# # ( # 2!

& )=#" * 2 P: region x do region y do S1: Q: region y do region x do S2;!) 1#

& )=) # var V: shared T;...... region V when B do S; /*acceso en e.m. a V*/

& )=) # # 2 # ( 2 1 ##2 +,! + # +! M N ( #* ',2! 7+M N

& )=) #"

+) & )= var buffer: shared record B: array [0..n-1] of integer; In_Ptr, Out_Ptr, cont: integer; Productor region buffer when cont<n do producir(i); B[In_Ptr]:=I; In_Ptr:=In_Ptr+1 mod n; cont:=cont+1; end; Consumidor region buffer when cont>0 do end; I:=B[Out_Ptr]; Out_Ptr:=Out_Ptr+1 mod n; cont:=cont-1; consumir(i);

.6/019:4 3 & #1#2 #''1 2 #' * " ' ) G * 2 & &!

#" ;(! * C H

# type nombre-monitor=monitor declaraciones de variables procedure entry P1(...)... end;... procedure entry PN(...)... end; código de inicialización end;

#,! EG F! ) 32! ' ( '' * G )& ) G * 2G ) G *# 2G )#

#C) DEF ) 2 nombre_variable: condition; wait(variable_condición): 2 4..! 2 ' send(variable_condición):! non_empty(variable_condición):! &!' &c.wait, c.send! c.

#, E " < & G & G *# G * G G ( '4*2#' G )' G ' G )' G ' 7 O 3 G * G # G )' G *! G )' G *! #( '

+) monitor prod_con is B: array(0..n-1) of Integer; In_Ptr, Out_Ptr: Integer:=0; Count: Integer:=0; Not_Full, Not_Empty: Condition; Procedure Añadir(I:in Integer) is if Count=N then wait(not_full); end if; B(In_Ptr):=I; In_Ptr:=(In_Ptr+1) mod N; Send(Not_Empty); end; Procedure Coger(I:out Integer) is if Count=0 then wait(not_empty); end if; I:=B(Out_Ptr); Out_Ptr:=(Out_Ptr+1) mod N; Send(Not_Full); end; end prod_con;

( Wait Wait (S) Signal Signal (S) S 2 OEF # EF? J= 2 BA

( monitor Emula_Semaforo is S: Integer := S0; Not_Zero: Condition; procedure Emula_Wait is if S0=0 then Wait(Not_Zero); end if; S := S-1; end Emula_Wait; Procedure Emula_Signal is Begin S := S+1; Send(Not_Zero) end Emula_Signal; end monitor;

( & 1*,'' #&! C & Csemáforo* CCount 2 & ) 2

( B### ' & S Send(C) 2! if CCount > 0 then Signal(CSemáforo); end if; wait(c) 2! CCount := CCount+1; Signal(S); Wait(CSemáforo); Wait(S); CCount := CCount-1;

) No existen como tales Emulación mediante semáforos IPC Fases: Diseñar una solución con monitores Utilizar señalización SX Transformar a su equivalente con semáforos (Djikstra) Implementar con semáforos IPC

@* Todo objeto es un monitor potencial Clase Object: métodos wait, notify, notifyall Clases con métodos synchronized No soporta variables de condición Hay que simular la sincronización con los métodos de la clase Object. Equivalen a una única variable de condición.

@*# class Monitor { public Monitor(){ } //constructor public synchronized tipo1 metodo1() throws InterruptedException{ notifyall(); //señal explícita no desplazante while(!condicion1) wait(); //espera sobre v. de condición } public synchronized tipo2 metodo2() throws InterruptedException{ notifyall(); while(!condicion1) wait(); } }

# # ( 2 7 *! 24! *4 -+(! 4 2 * 2 & *

Monitor Lector_Escritor is Lector: integer:=0; Writing: boolean:=true; OK_to_Read, OK_to_Write: Condition; procedure Start_Read is if Writing or Awaited(OK_to_Write) then Wait(OK_to_Read); end if; Lector:= Lector+1; Send (OK_to_Read); end Start_Read; procedure End_Read is Lector:= Lector-1; if Lector=0 then Send(OK_to_Write); end if; end End_Read;

procedure Start_Write is if Lector<>0 or Writing then Wait(OK_to_Write); end if; Writing:=True; end Start_Write; procedure End_Write Writing:=False; if Awaited(OK_to_Read) then Send (OK_to_Read); else Send (OK_to_Write); end if; end End_Write; end Lector_Escritor Monitor;

Task Body Lector is loop Start_Read; Leer_Datos; End_Read; end Lector; Task Body Escritor is loop Start_Write; Escribir_Datos; End_Write; end Escritor;

#<( &!! Comer * Pensar #( 72 G 2 * 3 # 4* 2 4* 4*

(#% Tenedores: array(0..4) of Semaphore := (others=>1); Task body Filosofo is loop Pensar; Wait(Tenedores(i)); Wait(Tenedores(i+1) mod 5); Comer; Signal(Tenedores(i)); Signal(Tenedores(i+1) mod 5); end Filosofo;

T[0] T[1] T[2] T[3] T[4] a T[1] a T[2] a T[3] a T[4] a T[0]

(# % Mesa: Semaphore := 4; Tenedores: array(0..4) of Semaphore := (others=>1); Task body Filosofo is loop Pensar; Wait(Mesa); Wait(Tenedores(i)); Wait(Tenedores(i+1) mod 5); Comer; Signal(Tenedores(i)); Signal(Tenedores(i+1) mod 5); Signal(Mesa); end Filosofo;

# Monitor MTenedores Tenedores: array(0..4)of Integer range 0..2 (others)=>2; Listo: array (0..4) of Condition; Procedure Coger_Tenedor(I: Integer) is if Tenedores(I)<>2 then wait(listo(i)); end if; Tenedores((I+1) mod 5) := Tenedores((I+1) mod 5)-1; Tenedores((I-1) mod 5) := Tenedores((I-1) mod 5)-1; end Coger_Tenedor;

Procedure Dejar_Tenedor(I: Integer) is Tenedores((I+1) mod 5) := Tenedores((I+1) mod 5)+1; Tenedores((I-1) mod 5) := Tenedores((I-1) mod 5)+1; if Tenedores(I+1)=2 then send (Listo(I+1)); end if; if Tenedores(I-1)=2 then send (Listo(I-1)); end if; end Dejar_Tenedor; end MTenedores; Task body Filosofo is /*cinco entidades como esta*/ loop Pensar; Coger_Tenedor(I); Comer; Dejar_Tenedor(I); end Filosofo;

# Monitor MTenedores Estado: array(0..4)of (pensar, hambriento, comer); Listo: array (0..4) of Condition; Procedure Coger_Tenedor(I: Integer) is Begin Estado[I]:=hambriento; test(i); if Estado[i]<>comer then wait(listo[i]); end Coger_Tenedor; Procedure Dejar_Tenedor(I: Integer) is Estado[i]:=pensar; test(i-1 mod 5); test(i+1 mod 5); end Dejar_Tenedor;

Procedure test(k: Integer) is Begin if Estado[k-1 mod 5]<>comer and Estado[k]=hambriento and Estado[k+1 mod 5]<>comer then Estado[k]:=comer; send(listo[k]); end Coger_Tenedor; //codigo de inicialización For i:=1 to 5 Estado[i]:=pensar; end MTenedores;

,# 6( ( # ' #& 2 ) " )! 0" *)

,#) '' 3 7 2! * 1 */( // ( 0" *)

,#) task Body Pi is loop Resto_Código_i; send(coordinador, solicitud); receive(coordinador, permiso); Sección_Crítica_i; send(coordinador, terminación); end Pi; 0" *)

,#) A C H A C H ") "), " A C H H.'' ")

,#'- +& # A9 9!99DC 9 " # " #2! P69Q P Q 0" *)

,#'- +& 0" *)

,#%,-G El proceso que desea ejecutar su sección crítica debe ganar una votación entre todos los demás Conjunto de procesos ={P1, P2,,Pn} distribuidos en N nodos comunicados entre sí Se preserva el orden de los mensajes, y el retardo de los mismo es finito. Todos los nodos están comunicados entre sí Para cada proceso Pi existe un conjunto de procesos Si contenido en. Es su distrito de votantes Pi siempre pertenece a Si Todos los distritos tienen igual número de votantes. Para cada i,j se satisface que Si Sjconjunto vacío 0" *)

,#% -G i 1!! Si Bloqueado hasta recibir el voto de todos los procesos de Si Cuando un proceso de Si recibe una solicitud de voto contesta SÍ si aún no ha votado. Si ya ha votado (a otro proceso), retiene la respuesta El proceso Pi que ha ejecutado su sc informa a todos los procesos de Si que ya pueden votar a otros candidatos Exclusión mutua garantizada Pueden aparecer interbloqueos, pero se pueden prevenir 0" *)

,#% -G boolean voto_dado:= false; Task body Pi is Begin loop Resto_Código_i for(pj in Si) send(pj, solicitud); for(pj in Si) receive(pj, voto); Sección_Crítica_i; for(pj in Si) send(pj, finalizada); end; End; 0" *)

Task body Receptor_Solicitudes_i is Begin loop receive(pj, solicitud); if(voto_dado) encolar(pj); else voto_dado:=true; send(pj, voto); end; end; End; 0" *)

Task body Emisor_Permisos is Begin loop if(cola_vacía) voto_dado:=false; else Pj:=desencolar(); send(pj, voto); end; end; End; 0" *)

,#%,&+% G " #*"#% "! 3 ) #,! &2 7* & " * &'' &''*!(: &*!!1: ) 0" *)

,#% 1 3! 1& () 7 2! (!1, *& & 1 ( 21

,#" 1 EF '' 2 2 Task body Main_Process is loop Resto_De_Código; Choose_Sequence_Number;(*se pone a la cola*) Send_Request_to_Nodes; (*pide permiso a los demás*) Wait_for_reply; (*espera respuesta de todos*) Sección_Crítica; Reply_to_Deferred_Nodes;(*da permiso a otros*) end Main_Process; 0" *)

2 &(( (# Task body Request_Process is (*acepta solicitudes de otros*) loop accept Message; if Decide_to_Defer then Defer_reply; else Send_reply; end if; end Request_Process; 0" *)

2E*F ( 1'' ( # Task body Reply_Process is (*acepta respuesta de otros*) loop accept Message; Increment_Reply_count; if Last_Reply then Wake_Main_Process; end if; end Reply_Process; 0" *)

Los 3 procesos comparten las siguiente variables globales a nivel de nodo, las cuales informan sobre su estado. Number:Contiene el número de secuencia escogido por el nodo. High_Number:Mayor número de los recibidos. Para saltar la comparación si el nodo no desea competir por s.c. Requesting:flag indicador de si el nodo pide s.c. Reply_Count:Total de mensajes Reply recibidos. S:Semáforo para acceso en e.m. a variables globales. Wake_Up:Semáforo para suspender al proceso principal hasta que puede ejecutar su sección crítica. Deferred:Estructura de datos para indicar qué nodos tienen su respuesta diferida 0" *)

Number:Integer:=0; High_Number:Integer:=0; Requesting:Boolean:=False; Reply_Count:Integer:=0; S:Semaphore:=1; Wake_Up:Semaphore:=0; Deferred:array (1..N)of Boolean:=False; task type Main_Process is; task type Request_Process is entry Message (Num,ID:in Integer); end Request_Process; task type Reply_Process is entry Message; end Reply_Process; Main_Process: array (1..N) of Main_Process; Request_Process: array (1..N) of Request_Process; Reply_Process: array (1..N) of Reply_Process; 0" *)

, Procedure Choose_Number is; Wait(S); Requesting:=True; Number:=High_Number+1; Signal(S); end Choose_Number; Procedure Send_Request is; Reply_Count:=0; for J in 1..N loop if J<>I then Request_Process(J).Message(Number,I); end if; end Send_Request; Procedure Wait_for_Reply is; Wait(Wake_Up); end Wait_for_Reply; Procedure Reply_for_Deferred_Nodes is; Wait(S); Requesting:=False; Signal(S); for J in 1..N loop if Deferred (J) then Deferred:=False: Reply_Process(J).Message; end if; end Reply_for_Deferred_Nodes; 0" *)

,Request_Process Task body Request_Process is Received_Number:Integer; Received_ID:Integer; Decide_to_Defer:Boolean; loop accept Message(Num,ID:in Integer) do Received_Num:=Num; Received_ID:=ID; end Message; High_Number:=Max(High_Number, Received_Num); Wait(S); Decide_to_Defer:=Requesting and (Number<Received_Num or (Number=Received_Num) and I<Received_ID); if Decide_to_Defer then Deferred(Received_ID):=True; end if; Signal(S); end Request_Process; 0" *)

,Reply_Process "* # 3!)( '' Task body Reply_Process is loop accept Message; Reply_Count:=Reply_Count+1; if Reply_Count=N-1 then Signal (Wake_Up); end if; end Reply_Process; 0" *)

,#) Algoritmo Mensajes por E/S Retardo en entrada Problemas Centralizado 3 2 Caída del coordinador Token-Ring 1 a 0 a n-1 Pérdida token Distribuido Puro 2(n-1) 2(n-1) Caída de proceso 0" *)

Terminación Distribuida: Definición 4 1 7 4* ) ( 4*( &4* & 2 4*7(! 4*I # " )* 0",#1L!* #

Terminación Distribuida: Generalidades Soporte de los algoritmos La terminación se produce cuando? Características algoritmos de terminación entidades distribuidas estruturadas en grafo canales de comunicación inter-nodo dirigidos canales libres de error mensajes llegan a destino en orden de envío puede haber ciclos y bidireccionalidad existe un nodo fuente sin ejes de entrada

Terminación Distribuida: Ejemplo de Grafo C H S R C ( ' 1 0",#1L!* #