Comunicación y sincronización de procesos - Redes

Anuncio
Sistemas Operativos I
Tema 4
Comunicación y
sincronización de procesos
Equipo de Sistemas Operativos DISCA / DSIC
UPV
Comunicación y sincronización de procesos
Objetivos
Presentar dos alternativas básicas para comunicación entre procesos
Memoria común
Mensajes
Analizar las condiciones de carrera y estudiar el concepto de seriabilidad.
Estudiar, en el caso de memoria común, el problema de la sección critica.
Presentar los criterios de corrección al problema de la sección critica y
sus posibles soluciones de una forma estructurada:
Soluciones hardware
Semáforos
Realización de semáforos mediante soluciones hardware.
Adquirir destreza en la resolución de problemas de sincronización a través
de problemas clásicos (productores y consumidores, lectores y escritores,
cinco filósofos, etc.)
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
2
1
Comunicación y sincronización de procesos
Contenido
1.- Introducción
Bibliografia
A. Silberschatz, J. Peterson , P.
Galvin.
Sistemas
Operativos.
Conceptos Fundamentales. 5ª ed.
Capítulo 6.
A. Tanenbaum. Modern Operating
Systems. Capítulos 2,11 y 12
2.- Comunicación por memoria común
3.- El problema de la sección crítica
4.- Soluciones hardware
5.- Semáforos
6.- Problemas clásicos de
programación concurrente
7.- Construcciones lingüísticas
8.- Sincronización en POSIX
9.- Comunicación por mensajes
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
3
Comunicación y sincronización de procesos
Contenido
1.- Introducción
2.- Comunicación por memoria común
3.- El problema de la sección crítica
4.- Soluciones hardware
5.- Semáforos
6.- Problemas clásicos de programación concurrente
7.- Construcciones lingüísticas
8.- Sincronización en POSIX
9.- Comunicación por mensajes
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
4
2
1.Introducción
Existe la necesidad de comunicación entre procesos.
Los procesos requieren con frecuencia comunicación entre ellos
(ejemplo: tubos).
La comunicación entre procesos puede seguir dos esquemas
básicos:
Comunicación por memoria común
Comunicación por mensajes
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
5
1.Introducción
Comunicación por memoria común
La comunicación por memoria
común se puede dar en los
siguientes casos:
P1
Hilo 1
Hilo 2
Espacio de direcciones único: es el
caso de los hilos de ejecución
El s.o. crea una zona de memoria
accesible a un grupo de procesos
Problema de la sección crítica:
en un sistema con procesos
concurrentes que se comunican
compartiendo datos comunes es
necesario sincronizar el acceso
(lectura, escritura) a los datos
compartidos para asegurar la
consistencia de los mismos.
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
Datos
compartidos
6
3
1.Introducción
Comunicación por mensajes
La comunicación por mensajes se da “normalmente” en el siguiente caso:
Espacio de direcciones independentes
Sincronización en la comunicación por mensajes: Cuando dos procesos
se comunican vía mensajes se necesitan mecanismos para que el
proceso receptor espere (se suspenda hasta) a que el proceso emisor
envíe el mensaje y éste esté disponible.
No aparece el problema de la sección crítica.
P1
P2
mensaje
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
7
Comunicación y sincronización de procesos
Contenido
1.- Introducción
2.- Comunicación por memoria común
3.- El problema de la sección crítica
4.- Soluciones hardware
5.- Semáforos
6.- Problemas clásicos de programación concurrente
7.- Construcciones lingüísticas
8.- Sincronización en POSIX
9.- Comunicación por mensajes
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
8
4
2.Comunicación por memoria común
El problema de los productores y consumidores con buffer acotado
Productor: proceso que produce elementos (a una cierta velocidad) y los
deposita en un buffer.
Consumidor: proceso que toma elementos del buffer y los consume (a
una velocidad probablemente diferente a la del productor)
Buffer: Estructura de datos que sirve para intercambiar información entre
los procesos productores y consumidores. Actúa a modo de depósito para
absorber la diferencia de velocidad entre productores y consumidores
Ejemplo: buffer de impresora.
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
9
2.Comunicación por memoria común
El problema de los productores y consumidores con buffer acotado
C1
C2
Consumidores
salida
buffer
contador
entrada
Productores
Sistemas Operativos I (00-01)
P1
P2
Comunicación y sincronización de Procesos
10
5
2.Comunicación por memoria común
Productores y consumidores con buffer acotado
•Variables
•Variables compartidas:
compartidas:
var
var buffer:
buffer: array[0..n-1]
array[0..n-1]
of
of elemento;
elemento;
entrada:=0,
entrada:=0, salida:=0
salida:=0 :: 0..n-1;
0..n-1;
contador:=
contador:= 00 :: 0..n;
0..n;
•proceso
•proceso productor:
productor:
task
productor;
task productor;
var
var item:
item: elemento;
elemento;
repeat
repeat
item
item :=
:= producir();
producir();
while
while contador=
contador= nn do
do no-op;
no-op;
buffer[entrada]
buffer[entrada] :=
:= item;
item;
entrada
entrada :=
:= (entrada
(entrada +1)
+1) mod
mod n;
n;
contador:=contador+1;
contador:=contador+1;
until
until false
false
end
end productor;
productor;
Sistemas Operativos I (00-01)
•proceso
•proceso consumidor:
consumidor:
task
task consumidor;
consumidor;
var
var item:
item: elemento;
elemento;
repeat
repeat
while
while contador=
contador= 00 do
do no-op;
no-op;
item
item :=
:= buffer[salida]
buffer[salida]
salida
salida :=
:= (salida
(salida +1)
+1) mod
mod n;
n;
contador:=contador-1;
contador:=contador-1;
consumir(item);
consumir(item);
until
until false
false
end
end consumidor;
consumidor;
Comunicación y sincronización de Procesos
11
2.Comunicación por memoria común
Condiciones de carrera
Corrección en programes secuenciales: el programa cumple con sus
especificaciones (responde a unos invariantes o reglas de corrección).
Corrección
secuencial no implica corrección concurrente: Un
programa que tiene una implementación “secuencialmente correcta”
(correcta con un sólo hilo de ejecución) puede presentar problemas
cuando se intenta introducir concurrencia en forma de hilos de ejecución.
Condición de carrera: la ejecución de un conjunto de operaciones
concurrentes sobre una variable compartida, deja la variable en un estado
inconsistente con las especificaciones de corrección. Además, el
resultado de la variable depende de la velocidad relativa en que se
ejecutan las operaciones.
Peligro potencial: Las condiciones de carrera pueden presentarse en
algún escenario, pero no tienen por qué observarse en todas las posibles
trazas de la ejecución del programa.
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
12
6
2.Comunicación por memoria común
Ejemplo de un escenario de condición de carrera
Productor:
contador:= contador+1;
Consumidor:
contador:= contador-1;
mov
movreg1,
reg1,contador;
contador;
inc
reg1;
inc reg1;
mov
movcontador,
contador,reg1;
reg1;
Inicialmente:
contador =5
T
Proceso Operación
mov
movreg2,
reg2,contador;
contador;
dec
reg2;
dec reg2;
mov
movcontador,
contador,reg2;
reg2;
reg1 reg2
contador
0
1
Prod.
Prod.
mov contador, reg1
inc reg1
5
6
?
?
5
5
2
3
4
Cons.
Cons.
Cons.
mov contador, reg2
dec reg2
mov reg2, contador
?
?
?
5
4
4
5
5
4
5
Prod
mov reg1, contador
6
?
6
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
incorrecto
13
2.Comunicación por memoria común
Criterio de corrección en programas concurrentes
El criterio de corrección/consistencia más usual para programas concurrentes
es:
Seriabilidad (consistencia secuencial): El resultado de la ejecución
concurrente de un conjunto de operaciones ha de ser equivalente al
resultado de ejecutar secuencialmente cada una de las operaciones, en
alguno de los ordenes secuenciales posibles.
Condición de carrera = no seriabilidad: no hay ninguna posible
ejecución secuencial de un conjunto de operaciones que de el mismo
resultado que la ejecución concurrente.
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
14
7
2.Comunicación por memoria común
Ejemplo de seriabilidad
La ejecución concurrente de op1, op2 y op3 :
op1 || op2 || op3
se considera correcta si el estado final de los datos compartidos es igual al
estado en que quedarían después de alguna de las siguientes ejecuciones
secuenciales:
op1 ; op2 ; op3
o
op1 ; op3 ; op2 o
op2 ; op1 ; op3
o
op2 ; op3 ; op1 o
op3 ; op1 ; op2
o
op3 ; op2 ; op1 .
Ejemplo numérico: sea una variable x con valor inicial 3 sobre la que se
pueden realizar dos operaciones:
op1: incremento de 8
op2: multiplicación por 5
Resultados correctos de op1 || op2 : 55 y 23
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
15
Comunicación y sincronización de procesos
Contenido
1.- Introducción
2.- Comunicación por memoria común
3.- El problema de la sección crítica
4.- Soluciones hardware
5.- Semáforos
6.- Problemas clásicos de programación concurrente
7.- Construcciones lingüísticas
8.- Sincronización en POSIX
9.- Comunicación por mensajes
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
16
8
3.El problema de la sección crítica
Concepto de sección crítica
Una sección crítica es una zona de código en la que se accede a variables
compartidas por varios procesos.
Problemas potenciales: puede introducir condiciones de carrera si no se
adoptan las medidas adecuadas.
Posible solución: sincronizar el acceso a los datos de manera que
mientras un proceso ejecuta su sección crítica ningún otro proceso
ejecuta la suya (exclusión mútua).
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
17
3. El problema de la sección crítica
Formulación del problema de la sección crítica
Sean n procesos compitiendo para acceder a datos compartidos
Cada proceso tiene una zona de código, denominada sección crítica, en
la que accede a los datos compartidos.
Problema: encontrar un protocolo del tipo:
protocolo
protocolode
deentrada
entrada
sección
CRÍTICA
sección CRÍTICA
protocolo
protocolode
desalida
salida
sección
RESTANTE
sección RESTANTE
Que satisfaga las tres condiciones siguientes :
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
18
9
3. El problema de la sección crítica
Solución al problema de la sección crítica
Cualquier solución al problema de la sección crítica ha de cumplir tres
requisitos:
Exclusión mútua: si un proceso está ejecutando su sección crítica
ningún otro proceso puede estar ejecutando la suya.
Progreso: si ningún proceso está ejecutando su sección crítica y hay
otros que desean entrar a las suyas, entonces la decisión de qué proceso
entrará a la sección crítica se toma en un tiempo finito y sólo puede ser
seleccionado uno de los procesos que desean entrar.
Espera limitada: Después de que un proceso haya solicitado entrar en su
sección crítica, existe un límite en el número de veces que se permite que
otros procesos entren a sus secciones críticas.
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
19
3. El problema de la sección crítica
Solución al problema de la sección crítica
Supuestos:
Los procesos se ejecutan a velocidad no nula.
La corrección no ha de depender de hacer suposiciones sobre la
velocidad relativa de ejecución de los procesos.
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
20
10
3. El problema de la sección crítica
Ejemplo: Algoritmo que soluciona el caso para dos procesos
Variables compartidas:
var
varturno
turno::0..1;
0..1;
task Pj;
…
task Pi;
while turno <> j do no-op;
…
sección CRÍTICA
while turno <> i do no-op;
turno := i;
sección CRÍTICA
sección RESTANTE
…
end Pj;
turno := j;
sección RESTANTE
…
end Pi;
Sistemas Operativos I (00-01)
No satisface
el requisito
del progreso
Comunicación y sincronización de Procesos
21
Comunicación y sincronización de procesos
Contenido
1.- Introducción
2.- Comunicación por memoria común
3.- El problema de la sección crítica
4.- Soluciones hardware
5.- Semáforos
6.- Problemas clásicos de programación concurrente
7.- Construcciones lingüísticas
8.- Sincronización en POSIX
9.- Comunicación por mensajes
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
22
11
4. Soluciones hardware
Soluciones hardware al problema de la sección crítica
Las soluciones hardware son soluciones a nivel de instrucciones del lenguaje
máquina:
Deshabilitación de interrupciones
Instrucción test_and_set atómica (indivisible).
Instrucción swap atómica.
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
23
4. Soluciones hardware
Deshabilitación de interrupciones
La deshabilitación de interrupciones se realiza utilizando las instrucciones:
DI : Deshabilitar interrupciones
EI : Habilitar interrupciones
Se consigue la exclusión mútua inhibiendo los cambios de contexto
durante la sección crítica, obligando así a que los procesos se ejecuten de
manera atómica.
Solución únicamente viable al nivel del núcleo del sistema operativo:
puesto que no es deseable dejar el control de las interrupciones en manos
de los procesos de usuario. Las instrucciones DI y EI sólo se pueden
ejecutar en modo privilegiado.
DI
DI
sección
secciónCRÍTICA
CRÍTICA
EI
EI
sección
secciónRESTANTE
RESTANTE
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
24
12
4. Soluciones hardware
Operación test and set atómica
La operación test_and_set permite evaluar y modificar una variable atómicamente
en una sola operación de ensamblador.
La especificación funcional de esta operación es:
function
functiontestAndSet(var
testAndSet(varobjetivo:
objetivo:boolean):
boolean):boolean;
boolean;
begin
begin
testAndSet
testAndSet:=
:=objetivo;
objetivo;
objetivo
:=
TRUE;
objetivo := TRUE;
end
end
atómicamente!
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
25
4. Soluciones hardware
Solución al problema de la s.c. con test_and_set
Variables compartidas:
var
varllave
llave:=
:=FALSE
FALSE::boolean;
boolean;
task
taskPi;
Pi;
……
while
whiletestAndSet(llave)
testAndSet(llave)do
dono-op;
no-op;
Espera activa:
el proceso no se
suspende por esperar
la entrada a la SC
Sistemas Operativos I (00-01)
sección
secciónCRÍTICA
CRÍTICA
llave
:=
FALSE;
llave := FALSE;
sección
secciónRESTANTE
RESTANTE
……
end
endPi;
Pi;
Comunicación y sincronización de Procesos
26
13
4. Soluciones hardware
Solución a la s.c. con test and set y espera limitada
La solución anterior no satisface el requisito de la espera limitada.
Variables compartidas:
var
varesperando
esperando:=
:=FALSE
FALSE::array[0..n-1]
array[0..n-1]of
ofboolean;
boolean;
cerradura
cerradura:=
:=FALSE
FALSE::boolean;
boolean;
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
27
4. Soluciones hardware
Solución a la s.c. con test and set y espera limitada
task
Algoritmo del proceso i:
taskPi;
Pi;
var
j:
0..n-1;
var j: 0..n-1;
llave:
llave:boolean;
boolean;
...
...
esperando[i]:=
esperando[i]:=TRUE;
TRUE;
llave
llave:=
:=TRUE;
TRUE;
while
whileesperando[i]
esperando[i]and
andllave
llavedo
dollave:=testAndSet(cerradura);
llave:=testAndSet(cerradura);
esperando[i]
esperando[i]:=
:=FALSE;
FALSE;
sección
secciónCRÍTICA
CRÍTICA
j:=i+1
mod
n;
j:=i+1 mod n;
while
while(j<>i)
(j<>i)and
and(not
(notesperando[j])
esperando[j])do
doj:=j+1
j:=j+1mod
modn;
n;
ififj=i
then
cerradura
:=
FALSE
else
esperando[j]
j=i then cerradura := FALSE else esperando[j]:=
:=FALSE;
FALSE;
sección
secciónRESTANTE
RESTANTE
end
endPi;
Pi;
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
28
14
4. Soluciones hardware
Solución a la s.c. con test and set y espera limitada
Proceso 0 (i=0)
cerradura
esperando[i]:= TRUE;
F
llave := TRUE;
while esperando[i] and llave do llave:=testAndSet(cerradura);
esperando
esperando[i] := FALSE;
F
F
F
F
F
F
F
F
j:=i+1 mod n;
while (j<>i) and (not esperando[j]) do j:=j+1 mod n;
if j=i then cerradura := FALSE else esperando[j] := FALSE;
.......
Proceso 4 (i=4)
Sistemas Operativos I (00-01)
0
1
2
3
4
5
6
7
...
Comunicación y sincronización de Procesos
29
4. Soluciones hardware
Solución a la s.c. con test and set y espera limitada
Proceso 0 (i=0)
cerradura
esperando[i]:= TRUE;
F
llave := TRUE;
while esperando[i] and llave do llave:=testAndSet(cerradura);
esperando
esperando[i] := FALSE;
j:=i+1 mod n;
while (j<>i) and (not esperando[j]) do j:=j+1 mod n;
if j=i then cerradura := FALSE else esperando[j] := FALSE;
.......
Proceso 4 (i=4)
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
V
F
F
F
F
F
F
F
0
1
2
3
4
5
6
7
...
30
15
4. Soluciones hardware
Solución a la s.c. con test and set y espera limitada
Proceso 0 (i=0)
cerradura
esperando[i]:= TRUE;
V
llave := TRUE;
while esperando[i] and llave do llave:=testAndSet(cerradura);
esperando
esperando[i] := FALSE;
V
F
F
F
F
F
F
F
j:=i+1 mod n;
while (j<>i) and (not esperando[j]) do j:=j+1 mod n;
if j=i then cerradura := FALSE else esperando[j] := FALSE;
.......
Proceso 4 (i=4)
Sistemas Operativos I (00-01)
0
1
2
3
4
5
6
7
...
Comunicación y sincronización de Procesos
31
4. Soluciones hardware
Solución a la s.c. con test and set y espera limitada
Proceso 0 (i=0)
cerradura
esperando[i]:= TRUE;
V
llave := TRUE;
while esperando[i] and llave do llave:=testAndSet(cerradura);
esperando
esperando[i] := FALSE;
j:=i+1 mod n;
while (j<>i) and (not esperando[j]) do j:=j+1 mod n;
if j=i then cerradura := FALSE else esperando[j] := FALSE;
.......
Proceso 4 (i=4)
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
F
F
F
F
F
F
F
F
0
1
2
3
4
5
6
7
...
32
16
4. Soluciones hardware
Solución a la s.c. con test and set y espera limitada
Proceso 0 (i=0)
cerradura
esperando[i]:= TRUE;
V
llave := TRUE;
while esperando[i] and llave do llave:=testAndSet(cerradura);
esperando
esperando[i] := FALSE;
F
F
F
F
V
F
F
F
j:=i+1 mod n;
while (j<>i) and (not esperando[j]) do j:=j+1 mod n;
if j=i then cerradura := FALSE else esperando[j] := FALSE;
.......
Proceso 4 (i=4)
Sistemas Operativos I (00-01)
0
1
2
3
4
5
6
7
...
Comunicación y sincronización de Procesos
33
4. Soluciones hardware
Solución a la s.c. con test and set y espera limitada
Proceso 0 (i=0)
cerradura
esperando[i]:= TRUE;
V
llave := TRUE;
while esperando[i] and llave do llave:=testAndSet(cerradura);
esperando
esperando[i] := FALSE;
j:=i+1 mod n;
while (j<>i) and (not esperando[j]) do j:=j+1 mod n;
if j=i then cerradura := FALSE else esperando[j] := FALSE;
.......
Proceso 4 (i=4)
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
F
F
F
F
V
F
F
F
0
1
2
3
4
5
6
7
...
34
17
4. Soluciones hardware
Solución a la s.c. con test and set y espera limitada
Proceso 0 (i=0)
cerradura
esperando[i]:= TRUE;
V
llave := TRUE;
while esperando[i] and llave do llave:=testAndSet(cerradura);
esperando
esperando[i] := FALSE;
F
F
F
F
V
F
F
F
j:=i+1 mod n;
while (j<>i) and (not esperando[j]) do j:=j+1 mod n;
if j=i then cerradura := FALSE else esperando[j] := FALSE;
.......
Proceso 4 (i=4)
Sistemas Operativos I (00-01)
0
1
2
3
4
5
6
7
...
Comunicación y sincronización de Procesos
35
4. Soluciones hardware
Solución a la s.c. con test and set y espera limitada
Proceso 0 (i=0)
cerradura
esperando[i]:= TRUE;
V
llave := TRUE;
while esperando[i] and llave do llave:=testAndSet(cerradura);
esperando
esperando[i] := FALSE;
j:=i+1 mod n;
while (j<>i) and (not esperando[j]) do j:=j+1 mod n;
if j=i then cerradura := FALSE else esperando[j] := FALSE;
.......
Proceso 4 (i=4)
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
F
F
F
F
F
F
F
F
0
1
2
3
4
5
6
7
...
36
18
4. Soluciones hardware
Solución a la s.c. con test and set y espera limitada
Proceso 0 (i=0)
cerradura
esperando[i]:= TRUE;
F
llave := TRUE;
while esperando[i] and llave do llave:=testAndSet(cerradura);
esperando
esperando[i] := FALSE;
F
F
F
F
F
F
F
F
j:=i+1 mod n;
while (j<>i) and (not esperando[j]) do j:=j+1 mod n;
if j=i then cerradura := FALSE else esperando[j] := FALSE;
.......
Proceso 4 (i=4)
Sistemas Operativos I (00-01)
0
1
2
3
4
5
6
7
...
Comunicación y sincronización de Procesos
37
4. Soluciones hardware
Solución a la s.c. con test and set y espera limitada
Proceso 0 (i=0)
cerradura
esperando[i]:= TRUE;
F
llave := TRUE;
while esperando[i] and llave do llave:=testAndSet(cerradura);
esperando
esperando[i] := FALSE;
j:=i+1 mod n;
while (j<>i) and (not esperando[j]) do j:=j+1 mod n;
if j=i then cerradura := FALSE else esperando[j] := FALSE;
.......
Proceso 4 (i=4)
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
F
F
F
F
F
F
F
F
0
1
2
3
4
5
6
7
...
38
19
4. Soluciones hardware
Operación swap atómica
La operación swap permite intercambiar atómicamente dos variables en una sola
operación de ensamblador.
La especificación funcional de esta operación es:
function
functionswap(var
swap(vara,b:
a,b:boolean);
boolean);
var
temp
:
boolean;
var temp : boolean;
begin
begin
temp:=
temp:=a;
a;
a:=b;
a:=b;
bb:=
:=temp;
temp;
end
end
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
atómicamente!
39
4. Soluciones hardware
Solución a la s.c con swap
Variables compartidas:
var
varcerradura
cerradura:=
:=FALSE
FALSE::boolean;
boolean;
Espera activa
task
taskPi;
Pi;
var
varllave:
llave:boolean;
boolean;
…
…
llave
llave:=
:=TRUE
TRUE
while
whileswap(cerradura,
swap(cerradura,llave)
llave)until
untilllave
llave==FALSE;
FALSE;
sección
secciónCRÍTICA
CRÍTICA
cerradura
cerradura:=
:=FALSE;
FALSE;
sección
secciónRESTANTE
RESTANTE
…
…
end
endPi;
Pi;
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
40
20
Comunicación y sincronización de procesos
Contenido
1.- Introducción
2.- Comunicación por memoria común
3.- El problema de la sección crítica
4.- Soluciones hardware
5.- Semáforos
6.- Problemas clásicos de programación concurrente
7.- Construcciones lingüísticas
8.- Sincronización en POSIX
9.- Comunicación por mensajes
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
41
5. Semáforos
Definición de semáforo
Tipo de datos que toma valores enteros y sobre el que se definen las
siguientes operaciones atómicas:
S: semaforo(N);
P(S)
(* semáforo S con valor inicial N >=0 *)
S:=S-1;
if S<0 then esperar(S);
V(S)
S:=S+1;
if S<=0 then despertar(S);
atómicamente!
atómicamente!
La operación esperar(S) suspende al
proceso que ha invocado P() y lo introduce
en una cola de espera asociada a S.
La operación despertar(S) extrae un proceso
de la cola de espera asociada a S y lo
activa.
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
Semáforo
P
V
contador
cola
42
21
5. Semáforos
Solución al problema de la sección crítica con semáforos
Los semáforos son un mecanismo de sincronización que no requiere espera activa
Variables compartidas:
var
varmutex:
mutex:semaforo(1);
semaforo(1);
(*
(*valor
valorinicial
inicial11*)
*)
task
taskPi;
Pi;
......
P(mutex);
P(mutex);
sección
secciónCRÍTICA
CRÍTICA
V(mutex);
V(mutex);
sección
secciónRESTANTE
RESTANTE
......
end
endPi;
Pi;
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
43
5. Semáforos
Implementación de semáforos
ESTRUCTURAS DE CONTROL DEL
SISTEMA : Vector de semáforos
Tabla de procesos
Semáforo-i
Contador
Cola de procesos
esperando en el
semáforo i
P. primero
PCB 8
Estado: SUSP
…
Evento: Sem-i
...
PCB 4
PCB 2
P. siguiente
P. último
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
44
22
Flujo de Control del S.O.
semaforo(valor)
Llamadas al Sistema
relacionadas con semáforos
P(S)
Activación del
Sistema Operativo
V(S)
Guardar parte del contexto de usuario, para realizar cambio de modo de ejecución (usuario->núcleo)
S.contador:= S.contador-1;
Si S. contador < 0
entonces
Pasar a suspendido al
proceso
en ejecución;
Si S.contador
Insertarlo en S.cola;
Reservar un semáforo S;
S.contador:= valor;
S.contador:= S.contador+1;
Si S.contador <= 0
entonces
p:=extraer proceso de S.cola;
Pasar p a preparado
Si no
Planificador:
selección del próximo
proceso
Si no
Realizar cambio de modo de ejecución (núcleo -> usuario). Recuperar contexto de usuario.
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
45
5. Semáforos
Semáforos versus espera activa
Espera activa:
El proceso que espera entrar en la sección crítica “desaprovecha” el tiempo de CPU
comprobando cuando puede entrar (ejecutando las instrucciones del protocolo de
entrada).
Semáforos:
La espera se realiza en la cola del semáforo, que es una cola de procesos suspendidos.
El proceso que espera entrar en la sección crítica no utiliza CPU; está suspendido.
Espera
activa
Proceso:
EntrdaSC;
SecciónCrítica;
SalidaSC;
Espera
activa
q
P1,P2,P2:Proceso;
Duración se la
sección crítica 2q
Sistemas Operativos I (00-01)
P1 P2 P3 P1 P2 P3 P2 P3 P3
Espera
pasiva
P1 P1 P2 P2 P3 P3
Comunicación y sincronización de Procesos
46
23
5. Semáforos
Semáforos: ejemplos de utilización
Un semáforo es un mecanismo de sincronización de uso general:
Para conseguir exclusión mútua.
Para forzar relaciones de precedencia, como por ejemplo:
El proceso Pj debe ejecutar B después de que el proceso Pi haya
ejecutado A.
task Pi;
...
A;
V(sinc);
...
var sinc: semaforo(0);
Sistemas Operativos I (00-01)
task Pj;
...
P(sinc)
B;
...
Comunicación y sincronización de Procesos
47
5. Semáforos
Semáforos: problemas derivados de una utilización incorrecta
Interbloqueos: Hay un conjunto de procesos en el que todos esperan
(indefinidamente) un evento que sólo otro proceso del conjunto puede producir.
Ejemplo:
var s1: semaforo(1);
s2: semaforo(1);
task P1;
...
P(s1);
P(s2);
…
V(s1);
V(s2);
Sistemas Operativos I (00-01)
task P2;
...
P(s2);
P(s1);
…
V(s1);
V(s2);
Escenario:
Escenario:
P1
P1→
→P(s1);
P(s1);
P2
→
P(s2);
P2 → P(s2);
P2
P2→
→P(s1);
P(s1);
P1
→
P(s2);
P1 → P(s2);
Sistema
Sistemaen
ensituación
situación
de
interbloqueo
de interbloqueo…
…
Comunicación y sincronización de Procesos
48
24
Comunicación y sincronización de procesos
Contenido
1.- Introducción
2.- Comunicación por memoria común
3.- El problema de la sección crítica
4.- Soluciones hardware
5.- Semáforos
6.- Problemas clásicos de programación concurrente
7.- Construcciones lingüísticas
8.- Sincronización en POSIX
9.- Comunicación por mensajes
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
49
6. Problemas clásicos de concurrencia
Problemas clásicos de programación concurrente
Existe una serie de problemas clásicos que se utilizan como “banco de
pruebas” de los diferentes mecanismos de sincronización entre procesos:
Los productores y los consumidores
Los lectores y los escritores
Los cinco filósofos
El barbero dormilón
...
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
50
25
6. Problemas clásicos de concurrencia
El problema de los productores y consumidores con buffer acotado
C1
C2
Consumidores
salida
buffer
contador
entrada
Productores
Sistemas Operativos I (00-01)
P1
P2
Comunicación y sincronización de Procesos
51
6. Problemas clásicos de concurrencia
Los productores y consumidores
Variables compartidas
var
varbuffer:
buffer:array[0..n-1]
array[0..n-1]of
ofelemento;
elemento;
entrada:=0,
entrada:=0,salida:=0,
salida:=0,contador:=
contador:=00::0..n-1;
0..n-1;
lleno:
lleno:semaforo(0);
semaforo(0); vacio:
vacio:semaforo(n),
semaforo(n), mutex:
mutex:semaforo(1);
semaforo(1);
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
52
26
6. Problemas clásicos de concurrencia
Los productores y consumidores
task
taskproductor;
productor;
var
item:
var item:elemento;
elemento;
task
taskconsumidor;
consumidor;
var
varitem:
item:elemento;
elemento;
repeat
repeat
item
item:=
:=producir();
producir();
repeat
repeat
P(lleno);
P(lleno);
P(vacio);
P(vacio);
P(mutex);
P(mutex);
P(mutex);
P(mutex);
item
item:=
:=buffer[salida]
buffer[salida]
buffer[entrada]
buffer[entrada]:=
:=item;
item;
entrada
:=
(entrada
entrada := (entrada+1)
+1)mod
modn;
n;
contador:=contador+1;
contador:=contador+1;
V(mutex);
V(mutex);
V(lleno);
V(lleno);
V(vacio);
V(vacio);
consumir(item);
consumir(item);
until
untilfalse
false
end
endproductor;
productor;
Sistemas Operativos I (00-01)
salida
salida:=
:=(salida
(salida+1)
+1)mod
modn;
n;
contador:=contador-1;
contador:=contador-1;
V(mutex);
V(mutex);
until
untilfalse
false
end
endproductor;
productor;
Comunicación y sincronización de Procesos
53
6. Problemas clásicos de concurrencia
Los lectores y los escritores
Problema de los lectores y los escritores
Hay un conjunto de datos comunes (un fichero, una base de datos, etc.)
Los procesos lectores, acceden a los datos en modo de sólo lectura
Los procesos escritores, acceden a los datos en modo lectura-escritura
Especificación del protocolo: reglas de corrección
Diversos lectores pueden leer concurrentemente.
Los escritores se excluyen mútuamente entre ellos
Los escritores se excluyen mútuamente con los lectores.
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
54
27
6. Problemas clásicos de concurrencia
Los lectores y los escritores
Especificación del protocolo: reglas de corrección
LL
LL
STOP
E
E
STOP
E
STOP
Sistemas Operativos I (00-01)
E
E
L
L
Comunicación y sincronización de Procesos
55
6. Problemas clásicos de concurrencia
Loslectores y escritores
Especificación del protocolo: reglas de prioridad
Primera variante de los Lectores-Escritores: (Prioridad a los lectores)
Si hay lectores leyendo y
escritores esperando, entonces
un nuevo lector tiene preferencia sobre el escritor que espera.
Hay inanición para los escritores, si no paran de llegar lectores
Segunda variante de los Lectores-Escritores: (Prioridad a los escritores)
Si hay escritores esperando,
éstos siempre tienen preferencia sobre nuevos lectores que lleguen
Hay inanición para los lectores, si no paran de llegar escritores
Tercera variante, sin inanición para ningún tipo de proceso
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
56
28
6. Problemas clásicos de concurrencia
Los lectores y los escritores
Especificación del protocolo: reglas de prioridad
STOP
E
E
1ª variante
L
L
2ª variante
Sistemas Operativos I (00-01)
L
L
STOP
E
E
Comunicación y sincronización de Procesos
L
57
6. Problemas clásicos de concurrencia
Los lectores y los escritores (semáforos)
Solución a la primera variante: Inanición para los escritores
Variables compartidas:
var
varmutex:
mutex:semaforo(1);
semaforo(1);
esc
escsemaforo(1);
semaforo(1);
nlectores:=0
nlectores:=0::integer;
integer;
task
taskescritor;
escritor;
……
P(esc);
P(esc);
escribir();
escribir();
V(esc);
V(esc);
……
end
endescritor;
escritor;
Sistemas Operativos I (00-01)
task
tasklector;
lector;
……
P(mutex);
P(mutex);
nlectores
nlectores:=
:=nlectores
nlectores++1;
1;
ififnlectores
=
nlectores =11then
thenP(esc);
P(esc);
V(mutex);
V(mutex);
leer();
leer();
P(mutex);
P(mutex);
nlectores
nlectores:=
:=nlectores
nlectores--1;
1;
ififnlectores
=
nlectores =00then
thenV(esc);
V(esc);
V(mutex);
V(mutex);
……
end
endlector;
lector;
Comunicación y sincronización de Procesos
58
29
Comunicación y sincronización de procesos
Contenido
1.- Introducción
2.- Comunicación por memoria común
3.- El problema de la sección crítica
4.- Soluciones hardware
5.- Semáforos
6.- Problemas clásicos de programación concurrente
7.- Construcciones lingüísticas
8.- Sincronización en POSIX
9.- Comunicación por mensajes
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
59
7. Construcciones lingüísticas
Con el fin de simplificar la programación de aplicaciones concurrentes,
algunos lenguajes de programación proporcionan herramientas
(construcciones lingüísticas) que facilitan la sincronización entre las
tareas y proporcionan un modelo de programación uniforme.
Monitores
Tipos protegidos en ADA
Métodos synchronized en Java
Soluciones a nivel de
lenguaje de programación
Soluciones a
nivel de
sistema operativo
Soluciones hardware
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
60
30
7.1 Monitores
Concepto
Un monitor es un tipo de datos que encapsula datos y operaciones.
Proporciona:
Exclusión mútua.
Sincronización.
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
61
7.1 Monitores
Sintaxis:
type nombre_monitor = monitor
.... declaración de variables.
procedure entry P1(....);
begin ... end;
function entry F2(....);
begin ... end;
......
begin
..... Código de inicialización
end;
Sistemas Operativos I (00-01)
Variables
Variablesinternas
internasal
almonitor:
monitor:
••Variables
compartidas
Variables compartidas
••Variables
Variablescondición
condición
Métodos
Métodosde
deacceso:
acceso:
•• Unica
Unicavía
víade
deacceso
accesoaalas
las
variables
variablescompartidas
compartidas
•• Exclusión
Exclusiónmutua
mutua
•• Se
Seinvoca
invocaautomáticamente
automáticamentealal
instanciar
el
instanciar elmonitor
monitoryyantes
antes
de
ser
accedido
de ser accedidopor
porningún
ningún
proceso
proceso
•• Se
Seutiliza
utilizapara
paralalainicialización
inicialización
de
las
variables
de las variablesdel
delmonitor
monitor
Comunicación y sincronización de Procesos
62
31
7.1 Monitores
Variables de tipo condición:
Para definir esquemas complejos de sincronización, se pueden
definir las variables del tipo condition.
var x: condition;
Sobre las variables condition se pueden realizar las siguientes
operaciones:
x.wait; Causa la suspensión (en una cola asociada a x) del
proceso que invocó la operación.
x.signal; Se reanuda (si existe) un proceso suspendido en la
cola asociada a x.
x.awaited; Indica el número de procesos suspendidos en la cola
asociada a x.
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
63
7.1 Monitores
Productores-consumidores con monitores
Monitor
B:buffer_limitado;
B:buffer_limitado;
taskProductor;
Productor;
task
var:
elemento:item;
var: elemento:item;
repeat
repeat
....Producirun
unelemento
elemento
....Producir
B.insertar(elemento);
B.insertar(elemento);
untilfalse;
false;
until
end
Productor;
end Productor;
Sistemas Operativos I (00-01)
PROGRAMA PRINCIPAL
taskConsumidor;
Consumidor;
task
var:elemento:item;
elemento:item;
var:
repeat
repeat
B.extraer(elemento);
B.extraer(elemento);
....Procesarelemento
elemento
....Procesar
untilfalse;
false;
until
endConsumidor;
Consumidor;
end
Comunicación y sincronización de Procesos
64
32
Productores-consumidores con monitores
MONITOR
type
typebuffer_limitado
buffer_limitado==monitor
monitor
const
constn=100;
n=100;
cont,
cont,entrada,
entrada,salida:integer;
salida:integer;
lleno,
lleno,vacio:
vacio:condition;
condition;
buffer:
buffer:array[0..n-1]
array[0..n-1]of
ofitem;
item;
procedureentry
entryinsertar
insertar(elem:item);
(elem:item);
procedure
procedure
entry
insertar
(elem:item);
begin
begin
begin
.....
.....
.....
end;
end;
end;
procedureentry
entryextraer
extraer(var
(varelem:item);
elem:item);
procedure
procedure
entry
extraer
(var
elem:item);
begin
begin
begin
.....
.....
.....
end;
end;
end;
begin
begin
entrada:=0;
entrada:=0;salida:=0;cont:=0;
salida:=0;cont:=0;
end;
end;
Sistemas Operativos I (00-01)
procedure entry insertar (elem:item);
begin
if cont=n then lleno.wait;
cont:=cont+1;
buffer[entrada]:=item;
entrada:=(entrada + 1) mod n;
vacio.signal;
end;
procedure entry extraer(var elem:item);
begin
if cont=0 then vacio.wait;
cont:=cont-1;
item:=buffer[salida];
salida :=(salida + 1) mod n;
lleno.signal;
end;
Comunicación y sincronización de Procesos
65
7.1Monitores
Variantes
Existen diferentes variantes en la definición de un monitor según resuelvan el
siguiente problema:
Un proceso P ejecuta x.signal y activa a otro proceso Q, Potencialmente
P y Q pueden continuar su ejecución dentro del monitor. ¿Cómo se garantiza
la ejecución en exclusión mutua en el monitor?
Modelo de Hoare: El proceso que invoca la operación x.signal (P) se
suspende (en una cola de “urgencia”) de forma que el proceso reanudado
por la operación x.signal (Q) pasa a ejecutarse dentro del monitor.
Modelo de Lampson y Redell: El proceso P continúa ejecutándose y Q
se ejecutará cuando el monitor quede libre.
Modelo de Brinch-Hansen: La operación x.signal ha de ser la última
operación que un proceso invoca antes de salir del monitor.
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
66
33
7.1 Monitores
Modelo de colas
Cola de entrada
MONITOR
Zona de espera del monitor
(procesos suspendidos)
Variable condición c1
c1.wait
Variable condición c2
c1.signal
Datos
c2.wait
c2.signal
Procedimientos
y funciones
Cola urgente (Hoare)
Sistemas Operativos I (00-01)
Salida
Comunicación y sincronización de Procesos
67
7.1 Monitores
Implementación de monitores con semáforos
Variables globales, por cada monitor se definen:
var
varmutex:
mutex:semaforo(1);
semaforo(1);
urgente:
urgente:semaforo(0);
semaforo(0);(*cola
(*colade
deurgencia*)
urgencia*)
cont_urg:
integer:=0;
cont_urg: integer:=0;
Para cada procedimiento o funcion F, se genera:
P(mutex);
P(mutex);
.....
.....Cuerpo
Cuerpode
deF;
F;
ififcont_urg
>
cont_urg >00
then
thenV(urgente)
V(urgente)
else
elseV(mutex);
V(mutex);
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
68
34
7.1 Monitores
Implementación de monitores con semáforos
Para cada variable condición X, se define:
var
var x_sem:
x_sem:semaforo(0);
semaforo(0);
x_cont:
x_cont:integer:=0;
integer:=0;
Operación X.signal
Operación X.wait
x_cont:=
x_cont:=x_cont+1;
x_cont+1;
ififcont_urg
cont_urg>>00
then
thenV(urgente)
V(urgente)
else
elseV(mutex);
V(mutex);
P(x_sem);
P(x_sem);
x_cont:=
x_cont:=x_cont-1;
x_cont-1;
Sistemas Operativos I (00-01)
ififx_cont
x_cont>>00
then
thenbegin
begin
cont_urg:=
cont_urg:=cont_urg
cont_urg++1;
1;
V(x_sem);
V(x_sem);
P(urgente);
P(urgente);
cont_urg:=
cont_urg:=cont_urg
cont_urg--1;
1;
end;
end;
Comunicación y sincronización de Procesos
69
7.1 Monitores
Lectores-escritores con monitores
Monitor
varle:le-control;
le:le-control;
var
var
varle:le-control;
le:le-control;
tasklector();
lector();
task
begin
begin
repeat
repeat
le.pre-leer();
le.pre-leer();
leer();
leer();
le.post-leer();
le.post-leer();
untilfalse;
false;
until
endlector;
lector;
end
Sistemas Operativos I (00-01)
PROGRAMA PRINCIPAL
taskescritor();
escritor();
task
begin
begin
repeat
repeat
le.pre-escribir();
le.pre-escribir();
escribir();
escribir();
le.post-escribir();
le.post-escribir();
until
false;
until false;
end
escritor;
end escritor;
Comunicación y sincronización de Procesos
70
35
7.1 Monitores
Lectores-escritores con monitores
MONITOR
type
typele-control
le-control==monitor;
monitor;
var
lectores,
var lectores,escritores
escritores:Integer;
:Integer;
leer,
leer,escribir
escribir: :condition;
condition;
procedure
procedureentry
entrypre-leer();
pre-leer();
ifif escritores
escritores>>00then
thenleer.wait;
leer.wait;
lectores
lectores:=
:=lectores+1;
lectores+1;
leer.signal;
leer.signal;(*(*despertar
despertaralalsiguiente
siguiente*)*)
end;
end;
procedure
procedureentry
entrypost-leer();
post-leer();
lectores
:=
lectores-1;
lectores := lectores-1;
ififlectores
lectores==00then
thenescribir.signal;
escribir.signal;
end;
end;
Sistemas Operativos I (00-01)
Inanición
Inaniciónpara
paraescritores
escritores
procedure
entry
pre-escribir();
procedure entry pre-escribir();
ifif escritores
escritores>>00or
orlectores
lectores>>00
then
thenescribir.wait;
escribir.wait;
escritores
escritores:=
:=escritores+1;
escritores+1;
end;
end;
procedure
procedureentry
entrypost-escribir();
post-escribir();
escritores
:=
escritores :=escritores-1;
escritores-1;
ififleer.awaited
leer.awaited>>00
then
thenleer.signal;
leer.signal;
else
elseescribir.signal;
escribir.signal;
end;
end;
begin
begin
lectores:=0;
lectores:=0;escritores:=0;
escritores:=0;
end.
end.
Comunicación y sincronización de Procesos
71
7.1 Monitores
Lectores-escritores con monitores
MONITOR
type
typele-control
le-control==monitor;
monitor;
var
varlectores,
lectores,escritores
escritores:Integer;
:Integer;
leer,
leer,escribir
escribir: :condition;
condition;
procedure
procedureentry
entrypre-leer();
pre-leer();
ifif escritores
escritores>>00or
orescribir.awaited
escribir.awaited>>00
then
leer.wait;
then leer.wait;
lectores
lectores:=
:=lectores+1;
lectores+1;
leer.signal;
leer.signal;(*(*despertar
despertaralalsiguiente
siguiente*)*)
end;
end;
procedure
procedureentry
entrypost-leer();
post-leer();
lectores
:=
lectores-1;
lectores := lectores-1;
ififlectores
lectores==00then
thenescribir.signal;
escribir.signal;
end;
end;
Sistemas Operativos I (00-01)
Inanición
Inaniciónpara
paralectores
lectores
procedure
entry
pre-escribir();
procedure entry pre-escribir();
ifif escritores
escritores>>00or
orlectores
lectores>>00
then
thenescribir.wait;
escribir.wait;
escritores
escritores:=
:=escritores+1;
escritores+1;
end;
end;
procedure
procedureentry
entrypost-escribir();
post-escribir();
escritores
:=
escritores :=escritores-1;
escritores-1;
ififescribir.awaited
escribir.awaited>>00
then
thenescribir.signal;
escribir.signal;
else
elseleer.signal;
leer.signal;
end;
end;
begin
begin
lectores:=0;
lectores:=0;escritores:=0;
escritores:=0;
end.
end.
Comunicación y sincronización de Procesos
72
36
7.1 Monitores
Lectores-escritores con monitores
MONITOR
type
typele-control
le-control==monitor;
monitor;
var
varlectores,
lectores,escritores
escritores:Integer;
:Integer;
leer,
leer,escribir
escribir: :condition;
condition;
procedure
procedureentry
entrypre-leer();
pre-leer();
ifif escritores
escritores>>00or
orescribir.awaited
escribir.awaited>>00
then
leer.wait;
then leer.wait;
lectores
lectores:=
:=lectores+1;
lectores+1;
leer.signal;
leer.signal;(*(*despertar
despertaralalsiguiente
siguiente*)*)
end;
end;
procedure
procedureentry
entrypost-leer();
post-leer();
lectores
lectores:=
:=lectores-1;
lectores-1;
ififlectores
lectores==00then
thenescribir.signal;
escribir.signal;
end;
end;
Sistemas Operativos I (00-01)
Sin
SinInanición
Inanición
procedure
entry
procedure entrypre-escribir();
pre-escribir();
ifif escritores
escritores>>00or
orlectores
lectores>>00
then
thenescribir.wait;
escribir.wait;
escritores
escritores:=
:=escritores+1;
escritores+1;
end;
end;
procedure
procedureentry
entrypost-escribir();
post-escribir();
escritores
:=
escritores :=escritores-1;
escritores-1;
ififleer.awaited
leer.awaited>>00
then
thenleer.signal;
leer.signal;
else
elseescribir.signal;
escribir.signal;
end;
end;
begin
begin
lectores:=0;
lectores:=0;escritores:=0;
escritores:=0;
end.
end.
Comunicación y sincronización de Procesos
73
7.1 Monitores
Monitores: espera condicional
Cuando se produce una llamada a x.signal, ¿qué proceso se activa?
El monitor permite una variante de la operación wait sobre una variable
condición para que, cuando se produzca la operación signal, se active a los
procesos suspendidos por orden de prioridad.
Se define la siguiente construcción:
x.wait(c)
donde:
c es una expresión entera que se evalúa cuando se realiza la operación wait.
El valor de c se almacena junto al proceso suspendido.
Al invocar la operación signal, se activa el proceso que tenga mayor prioridad
(menor valor numérico de c).
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
74
37
7.1 Monitores
Monitores espera condicional
type
typeasignacion-recurso
asignacion-recurso==monitor
monitor
var
var ocupado:
ocupado:boolean;
boolean;
x:
x:condition;
condition;
procedure
procedureentry
entryadquirir(tiempo:
adquirir(tiempo:integer);
integer);
begin
begin
ififocupado
ocupadothen
thenx.wait(tiempo);
x.wait(tiempo);
ocupado:=
true;
ocupado:= true;
end;
end;
procedure
procedureentry
entryliberar;
liberar;
begin
begin
ocupado:=
ocupado:=false;
false;
x.signal;
x.signal;
end;
end;
begin
begin
ocupado:=
ocupado:=false;
false;
end.
end.
Asignación de recursos
basada en tiempo de
uso.
De aquellos procesos
que se encuentren
esperando
por
el
recurso ocupado, se
reanudará aquel que
lo vaya a usar durante
menos tiempo.
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
75
7.2 Objetos protegidos
Objetos protegidos de ADA : declaración
Un objeto protegido encapsula datos que son accedidos simultáneamente por
varias tareas.
Las tareas acceden a los datos del objeto utilizando operaciones protegidas,
las cuales pueden ser funciones, procedimientos y entradas.
protected
protected [type]
[type]
Nombre[(Discriminantes)]
Nombre[(Discriminantes)]
is
is
procedure
Pnombre(Params);
procedurePnombre(Params);
Pnombre(Params);
procedure
procedure
Pnombre(Params);
function
Fnombre(Params)
return
Un_Tipo;
function
Fnombre(Params)
returnUn_Tipo;
Un_Tipo;
function
Fnombre(Params)
function
Fnombre(Params) return
return
Un_Tipo;
entry
Enombre(Params);
entry
Enombre(Params);
entry
Enombre(Params);
entry Enombre(Params);
private
private
Datos_Protegidos
Datos_Protegidos :: Su_Tipo;
Su_Tipo;
end
end Nombre;
Nombre;
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
76
38
7.2 Objetos protegidos
Objetos protegidos de ADA
La especificación tiene dos partes:
Una pública, donde se declaran las operaciones protegidas.
Una privada donde se declaran los datos protegidos. La parte privada no
es visible por los clientes del objeto protegido.
especificación
especificación
protected
protected [type]
[type]
Nombre[(Discriminantes)]
Nombre[(Discriminantes)]
is
is
procedure
procedure Pnombre(Params);
Pnombre(Params);
function
function Fnombre(Params)
Fnombre(Params) return
return Un_Tipo;
Un_Tipo;
entry
Enombre(Params);
entry Enombre(Params);
private
private
Datos_Protegidos
Datos_Protegidos :: Su_Tipo;
Su_Tipo;
end
end Nombre;
Nombre;
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
77
7.2 Objetos protegidos
Objetos protegidos de ADA: declaración
En el cuerpo del objeto se
implementan las operaciones
protegidas.
protected
protected body
body Nombre
Nombre
is
is
--cuerpo
--cuerpo
end
end Nombre;
Nombre;
ADA permite declarar tipos
protegidos o instancias individuales.
Objeto_1:
Objeto_1: Nombre;
Nombre;
Objeto_2:
Objeto_2: Nombre;
Nombre;
Sistemas Operativos I (00-01)
especificación
especificación
protected
protected [type]
[type]
Nombre[(Discriminantes)]
Nombre[(Discriminantes)]
is
is
procedure
procedure Pnombre(Params);
Pnombre(Params);
function
function Fnombre(Params)
Fnombre(Params)
return
return Un_Tipo;
Un_Tipo;
entry
entry Enombre(Params);
Enombre(Params);
private
private
Datos_Protegidos
Datos_Protegidos :: Su_Tipo;
Su_Tipo;
end
end Nombre;
Nombre;
instanciación
instanciación
Comunicación y sincronización de Procesos
78
39
7.2 Objetos protegidos
Objetos protegidos de ADA: control de concurrencia
Las funciones permiten consultar el objeto protegido y, por tanto, pueden
ejecutarse simultáneamente varias funciones.
Cuando una tarea está ejecutando un procedimiento o una entrada del objeto
protegido, otra tarea interesada en acceder al objeto protegido queda detenida
hasta que éste queda libre.
Las entradas tienen asociadas una condición lógica denominada barrera (o
guarda). Si en el momento de llamar al objeto la barrera es cierta, la tarea ejecuta
la entrada. En caso contrario, la tarea queda detenida en dicha entrada.
entry
entry Una_Entrada
Una_Entrada (Params)
(Params) when
when Alguna_Condición
Alguna_Condición is
is
var_locales;
var_locales;
begin
begin
...
...
end
end Una_Entrada;
Una_Entrada;
La
Laexpresión
expresiónde
deuna
unabarrera
barrerano
nopuede
puede
contener
parámetros
de
la
entrada.
contener parámetros de la entrada.
!
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
79
7.2 Objetos protegidos
Objetos protegidos de ADA: control de concurrencia
Las barreras se revaluan cuando finaliza la ejecución de una entrada o
un procedimiento. Si alguna barrera es ahora cierta se elige una tarea
detenida por dicha barrera y reanuda su ejecución.
Las tareas detenidas en barreras tienen prioridad cuando son
despertadas frente a aquellas que están esperando fuera del objeto
protegido.
Sistemas Operativos I (00-01)
E1
E2
Comunicación y sincronización de Procesos
80
40
7.2 Objetos protegidos
Construcción de semáforos con objetos protegidos de ADA
especificación
especificación
protected
protectedtype
typeSemaforo
Semaforo(Inicial:integer:=1)
(Inicial:integer:=1)
is
is
entry
entryP;
P;
procedure
procedureV;
V;
private
private
contador:Integer:=Inicial;
contador:Integer:=Inicial;
end
endSemaforo;
Semaforo;
utilización
utilización
Un_semaforo:
Un_semaforo:Semaforo(5);
Semaforo(5);
....
....
Un_semaforo.P;
Un_semaforo.P;
....
....
Un_semaforo.V;
Un_semaforo.V;
Sistemas Operativos I (00-01)
cuerpo
cuerpo
protected
protectedbody
bodySemaforo
Semaforois
is
entry
P
when
contador>0
entry P when contador>0is
is
begin
begin
contador:=contador-1;
contador:=contador-1;
end
endP;
P;
procedure
procedureVVis
is
begin
begin
contador:=contador+1;
contador:=contador+1;
end
endV;
V;
end
endSemaforo;
Semaforo;
Comunicación y sincronización de Procesos
81
7.2 Objetos protegidos
Ejemplo en ADA: el buffer acotado
procedure Prodcons is
n : constant Integer := 10;
subtype Indice is Integer range 0..n-1;
subtype Cantidad is Integer range 0..n;
subtype Item is Integer ;
type Buffers is array (Indice) of Item;
task
tasktype
typeProductor;
Productor;
task
tasktype
typeConsumidor;
Consumidor;
Un_Buffer:
Un_Buffer:Buffer;
Buffer;
Prod_1:
Prod_1:Productor;
Productor;
Prod_2:
Prod_2:Productor;
Productor;
Cons
Cons ::Consumidor;
Consumidor;
Sistemas Operativos I (00-01)
protected
protectedtype
typeBuffer
Bufferis
is
entry Poner
Poner (x
(x::in
inITEM);
ITEM);
entry Quitar
Quitar(x
(x::out
outITEM);
ITEM);
private
private
Buf:
Buf:Buffers;
Buffers;
Entrada
Entrada::Indice
Indice:=
:=0;
0;
Salida
Salida ::Indice
Indice:=
:=0;
0;
Contador:
Contador:Cantidad
Cantidad:=
:=0;
0;
end
endBuffer
Buffer;;
Comunicación y sincronización de Procesos
82
41
7.2 Objetos protegidos
Ejemplo en ADA: el buffer acotado
protected body Buffer is
entry Poner (x : in Item) when Contador < n is
begin
Buf(entrada) := x;
Entrada := (Entrada + 1) mod n;
Contador := Contador + 1;
end Poner;
entry Quitar (x : out Item) when Contador > 0 is
begin
x:= Buf(Salida);
Salida := (Salida + 1) mod n;
Contador := Contador - 1;
end Quitar;
end Buffer ;
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
83
7.2 Objetos protegidos
Ejemplo en ADA: el buffer acotado
task
taskbody
bodyProductor
Productoris
is
xx::ITEM;
ITEM;
begin
begin
loop
loop
xx:=
:=...;
...;
Un_Buffer.Poner(x);
Un_Buffer.Poner(x);
----otras
otrasacciones
acciones
end
endloop;
loop;
end
endProductor
Productor;;
task
taskbody
bodyConsumidor
Consumidoris
is
xx::ITEM;
ITEM;
begin
begin
loop
loop
Un_Buffer.Quitar(x);
Un_Buffer.Quitar(x);
----otras
otrasacciones
acciones
end
endloop;
loop;
end
endConsumidor;
Consumidor;
begin
null;
end ProdCons;
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
84
42
Comunicación y sincronización de procesos
Contenido
1.- Introducción
2.- Comunicación por memoria común
3.- El problema de la sección crítica
4.- Soluciones hardware
5.- Semáforos
6.- Problemas clásicos de programación concurrente
7.- Construcciones lingüísticas
8.- Sincronización en POSIX
9.- Comunicación por mensajes
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
85
8. Sincronización en POSIX
POSIX ofrece dos primitivas de sincronización de hilos: los mutex (o cerrojos)
y las variables condición.
Mutex (cerrojos)
Tienen dos estados posibles:
Abierto ningún hilo es el propietario
Cerrado el hilo que lo cierra es el propietario. Un mutex no puede
tener dos hilos propietarios simultáneamente.
Cuando un hilo intenta cerrar un mutex que ya ha sido cerrado, se
suspende hasta que el hilo propietario lo abra.
Sólo el hilo propietario puede abrir el mutex.
Creación e inicialización de los mutex:
p_thread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
86
43
8. Sincronización en POSIX
Llamada
pthread_mutex_lock (mut)
pthread_mutex_unlock (mut)
pthread_mutex_trylock(mut)
Descripción
Si el mutex mut estaba abierto, lo cierra y
el hilo que lo cierra es el propietario del
mutex. Si estaba cerrado, suspende(*) al
hilo hasta que se abra el mutex.
Abre el mutex mut. Solo el hilo
propietario del mutex puede abrirlo (**).
Igual que pthread_mutex_lock pero en
lugar de suspender al hilo si el semáforo
estaba cerrado, retorna immediatamente
con un código de error.
(*) Hay tipos de mutex, que le permiten al propietario cerrarlo varias veces
sin bloquearse. Con este tipo de mutex, el propietario debe abrirlo tantas
veces como lo hubiera cerrado para dejarlo finalmente abierto.
(**) Hay sistemas, como Redhat 5.1, que permiten que otros hilos abran el
mutex, sin embargo este funcionamiento no es portable.
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
87
8. Sincronización en POSIX
Variables condición en POSIX
Las variables condición son un tipo abstracto de datos con tres operaciones
básicas:
wait: suspende al proceso que la invoca en la condición.
signal: activa un proceso suspendido en la condición
broadcast: activa a todos los procesos suspendidos en la condición
Las variables condición siempre deben estar asociadas a un mutex.
Además existen métodos para limitar el tiempo que un hilo está bloqueado en
una variable condición.
Creación e inicialización de atributos:
p_thread_cond_t c1 = PTHREAD_COND_INITIALIZER;
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
88
44
8. Sincronización en POSIX
Variables condición en POSIX
Llamada
pthread_cond_wait(cond, mut)
pthread_cond_signal(cond)
pthread_cond_broadcast(cond)
pthread_cond_timedwait
(cond, mut,duracion)
Sistemas Operativos I (00-01)
Descripción
De forma atómica, realiza la operación
p_thread_mutex_unlock sobre mut, y
bloquea al hilo en la variable condición cond.
Cuando es despertado, el hilo cierra
nuevamente el mutex mut (realizando la
operación p_thread_mutex_lock.
Despierta a uno de los hilos que están
bloqueados en la variable condición. Si no hay
hilos bloqueados, no sucede nada.
Despierta todos los hilos bloqueados sobre
cond.
Igual que pthread_cond_wait pero si antes
de duracion no se ha despertado al hilo, la
llamada finalizará con un código de error. Al
despertar, el hilo que invoca la llamada,
vuelve a cerrar el mutex mut.
Comunicación y sincronización de Procesos
89
8. Sincronización en POSIX
El productor consumidor en POSIX (i)
Variables globales:
#define
#definenn10
10
int
intentrada,
entrada,salida,
salida,contador;
contador;
int
int buffer[n];
buffer[n];
pthread_mutex_t
pthread_mutex_t mutex
mutex==PTHREAD_MUTEX_INITIALIZER;
PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t
lleno
pthread_cond_t lleno==PTHREAD_COND_INITIALIZER;
PTHREAD_COND_INITIALIZER;
pthread_cond_t
pthread_cond_t vacio
vacio==PTHREAD_COND_INITIALIZER;
PTHREAD_COND_INITIALIZER;
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
90
45
8. Sincronización en POSIX
El productor consumidor en POSIX (i)
void
void*productor(void
*productor(void**arg){
arg){
int
inti;i;
for
for(i=0;
(i=0;i<100;
i<100;i++)
i++)Insertar(i);
Insertar(i);
pthread_exit(0);
pthread_exit(0);
}}
void
void*consumidor(void
*consumidor(void**arg){
arg){
int
inti;i;
for
for(i=0;
(i=0;i<100;
i<100;i++)
i++)
printf(“%d
printf(“%d“,“,Extraer());
Extraer());
pthread_exit(0);
pthread_exit(0);
}}
main(
main()){{
pthread_t
pthread_tth_a,
th_a,th_b;
th_b;
entrada
entrada==salida
salida==contador
contador==0;
0;
}}
pthread_create(&th_a,
pthread_create(&th_a,NULL,productor,NULL);
NULL,productor,NULL);
pthread_create(&th_b,
pthread_create(&th_b,NULL,consumidor,NULL);
NULL,consumidor,NULL);
pthread_join(th_a,
pthread_join(th_a,NULL);
NULL);
pthread_join(th_b,
pthread_join(th_b,NULL);
NULL);exit(0);
exit(0);
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
91
8. Sincronización en POSIX
El productor consumidor en POSIX (i)
Insertar
Insertar(int
(intdato)
dato){{
pthread_mutex_lock(&mutex);
while (contador >=n) pthread_cond_wait(&lleno, &mutex);
buffer[entrada]=
buffer[entrada]=dato;
dato;entrada=
entrada=(entrada+1)
(entrada+1)%
%n;
n;
contador=
contador+1;
contador= contador+1;
pthread_cond_broadcast(&vacio);
pthread_mutex_unlock(&mutex);
}}
int
intExtraer
Extraer(()){{
int
intdato;
dato;
pthread_mutex_lock(&mutex);
while (contador == 0) pthread_cond_wait(&vacio, &mutex);
dato
dato==buffer[salida];
buffer[salida];salida=
salida=(salida+1)
(salida+1)%
%n;
n;
contador=contador
1;
contador=contador - 1;
pthread_cond_broadcast(&lleno);
pthread_mutex_unlock(&mutex);
return
returndato;
dato;
}}
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
92
46
Comunicación y sincronización de procesos
Contenido
1.- Introducción
2.- Comunicación por memoria común
3.- El problema de la sección crítica
4.- Soluciones hardware
5.- Semáforos
6.- Problemas clásicos de programación concurrente
7.- Construcciones lingüísticas
8.- Sincronización en POSIX
9.- Comunicación por mensajes
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
93
9. Comunicación por mensajes
Sistemas de mensajes
Los sistemas de mensajes permiten la comunicación entre procesos con
espacios de direcciones distintos, bien sean locales o remotos.
Operaciones básicas (proporcionadas por el Sistema Operativo):
send(dst,mensaje): enviar un mensaje a un destino.
receive(org,mensaje): recibir un mensaje de un origen.
P1
P2
mensaje
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
94
47
9. Comunicación por mensajes
Variantes
Según el modo de nombrar origen y destino:
Comunicación directa: proceso a proceso.
Comunicación indirecta: basada en puertos o buzones.
Según la capacidad del enlace:
Comunicación síncrona: el enlace tiene capacidad = 0.
Comunicación asíncrona: el enlace tiene capacidad > 0.
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
95
9. Comunicación por mensajes
Comunicación directa
Los mensajes se direccionan a procesos.
Los procesos necesitan conocer sus identificadores: las direcciones dst y
org son identificadores de procesos.
org puede ser un comodín, ANY. En este caso se recibe de cualquier
proceso y ANY toma el valor del proceso emisor.
Recibir de
“20”
P1
P15
A:
proceso 15
De:
proceso 20
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
96
48
9. Comunicación por mensajes
Comunicación indirecta: puertos o buzones
Los mensajes se envían a puertos: las direcciones dst y org son
identificadores de puertos.
Un puerto tiene un identificador único en el sistema.
El protocolo TCP/IP utiliza puertos “bien conocidos” que sirven para
invocar servicios de red.
– ftp: port 20 y 21
– www: port 80
– ntp: port 123
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
97
9. Comunicación por mensajes
Comunicación indirecta: puertos
Nodo “garbi”
Nodo “xaloc”
A:
Servicio ftp
Puerto 20
P2
Puerto 21
Puerto 55
P1
Puerto 90
Puerto 80
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
P3
98
49
9. Comunicación por mensajes
Comunicación indirecta: puertos y buzones
Puertos: permiten que varios procesos envíen, pero sólo puede haber un
proceso asociado para recibir.
Buzones: permiten que varios procesos se asocien para recibir. El
sistema operativo selecciona qué proceso recibe el mensaje.
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
99
9. Comunicación por mensajes
Operaciones sobre puertos
¿Qué proceso puede recibir del puerto? Alternativas:
a) El propietario: El proceso que lo crea es el propietario del puerto y es
el único que puede recibir o destruir el puerto. Cuando el proceso
propietario finaliza, se destruyen todos los puertos que posee. Son
necesarias las siguientes operaciones:
create(port): crea un puerto.
destroy(port): destruye un puerto.
b) El que se vincula al puerto: El puerto pertenece al S.O. y su
existencia es independiente de los procesos que lo utilizan. Cuando un
proceso se vincula a un puerto, es el único que puede recibir de él.
bind(puerto): vincula un proceso con un puerto.
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
100
50
9. Comunicación por mensajes
Comunicación síncrona
La capacidad del enlace es cero: El enlace no almacena mensajes; no
pueden existir mensajes enviados y pendientes de entrega.
Cita o rendez-vous: La comunicación sólo tiene lugar cuando emisor y
receptor han invocado sus operaciones respectivas send y receive.
Implementación de la cita o rendez-vous: El primer proceso que llega a la
cita se suspende esperando a que el otro llegue.
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
101
9. Comunicación por mensajes
Mensajes: Comunicación síncrona
Escenario 1:
send antes que receive
send
send
P2
suspendido
P1
Sistemas Operativos I (00-01)
P2
suspendido
P1
recv
recv
Escenario 2:
receive antes que send
Comunicación y sincronización de Procesos
102
51
9. Comunicación por mensajes
Comunicación asíncrona
La capacidad del enlace es N: pueden haber mensajes enviados y pendientes de
entrega
Variantes:
Capacidad limitada: N está acotado.
Capacidad ilimitada: N no está acotado.
Sincronización:
Receive de enlace vacío:
– Opción bloqueante: suspender al proceso que la invoca.
– Opción no bloqueante : devolver un error al proceso que la invoca.
Send a un enlace lleno:
– Opción bloqueante: suspender al proceso que la invoca.
– Opción no bloqueante : devolver un error al proceso que la invoca o
perder el mensaje.
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
103
9. Comunicación por mensajes
El problema de los Productores y Consumidores con mensajes:
Los espacios de direcciones son separados. No hay variables comunes.
Versión con:
Comunicación directa.
Comunicación síncrona o asíncrona (send y receive bloqueantes)
task productor;
var item : elemento;
repeat
item := producir();
send( consumidor, item );
until false;
end productor;
Sistemas Operativos I (00-01)
task consumidor;
var item : elemento;
repeat
receive( productor, item );
consumir(item);
until false;
end consumidor;
Comunicación y sincronización de Procesos
104
52
9. Comunicación por mensajes
El problema de los Productores y Consumidores con mensajes:
Versión con:
Comunicación directa.
Comunicación asíncrona, con enlace de capacidad N (receive bloqueante, send no
bloqueante)
task
taskproductor;
productor;
var
varitem
item::elemento;
elemento;
m
m::mensaje;
mensaje;
repeat
repeat
item
item:=
:=producir();
producir();
receive(
receive(consumidor,
consumidor,m
m););
construir_msj(m,
construir_msj(m,item);
item);
send(
consumidor,
send( consumidor,m
m););
until
false;
until false;
end
endproductor;
productor;
Sistemas Operativos I (00-01)
task
taskconsumidor;
consumidor;
var
varitem
item::elemento;
elemento;
m
m::mensaje;
mensaje;
i:i:integer;
integer;
for
i:=1
for i:=1to
toNNdo
do send(
send(productor,
productor,m
m););
repeat
repeat
receive(
receive(productor,
productor,m
m););
item
item:=
:=extraer_msj(m);
extraer_msj(m);
consumir(item);
consumir(item);
until
untilfalse;
false;
end
endconsumidor;
consumidor;
Comunicación y sincronización de Procesos
105
9. Comunicación por mensajes
Mensajes: el modelo cliente-servidor
Modelo de comunicación especialmente adecuado para sistemas
distribuidos, basado en asociar un proceso servidor al recurso que se
desa compartir.
Existen dos patrones de comportamiento diferenciados:
Servidores: Gestionan un recurso y ofrecen servicios relacionados con el
recurso. Reciben peticiones de los clientes, las ejecutan en su nombre y
responden a los clientes.
Clientes: Envían mensajes de petición a los servidores y esperan respuesta.
Sistemas Operativos I (00-01)
Comunicación y sincronización de Procesos
106
53
9. Comunicación por mensajes
Mensajes: el modelo cliente-servidor
Nodo C
petición
Nodo S
C
S
WWW
respuesta
CLIENT
CLIENT
…
…
send(serv,
send(serv,petición);
petición);
recv(rem,
recv(rem,respuesta);
respuesta);
...
...
Sistemas Operativos I (00-01)
SERVIDOR
SERVIDOR
repeat
repeat
recv(serv,
recv(serv,petición,
petición,…);
…);
respuesta=
respuesta=trabajar(petición);
trabajar(petición);
rem=remite(peticion);
rem=remite(peticion);
send(rem,
send(rem,respuesta,
respuesta,…);
…);
until
untilfalse;
false;
Comunicación y sincronización de Procesos
107
54
Descargar