Está en la página 1de 41

Sincronización de procesos

Mariano Gómez Plaza


Tipos de procesos
Independientes Cooperantes
Su estado no es compartido Su estado es compartido

Son deterministas Su funcionamiento no es


determinista
Son reproducibles Su funcionamiento puede
ser irreproducible
Pueden ser detenidos y Si son detenidos y posteriormente
rearrancados sin ningún rearrancados puede que
efecto negativo se produzcan efectos negativos

Ejemplo: un programa que Ejemplo: un proceso que escribe


calcula 1000 cifras decimales en el terminal la cadena “abc” y
de pi otro la cadena “cba”

Sincronización de
 2009-2010 Mariano Gómez Plaza
procesos 2
Productor-consumidor
 Un proceso produce datos que son posteriormente
procesados por otro proceso
 i.e.: el manejador de teclado y el programa que
recoge los caracteres de un buffer
 Lo más cómodo es emplear un buffer circular
Escribe Lee

Productor Consumidor

Sincronización de
 2009-2010 Mariano Gómez Plaza
procesos 3
Código del productor
 El productor no puede escribir en el buffer si está lleno
 Comparte con el consumidor: el buffer y el contador
do {
...
produce un nuevo elemento (elemento_p)
...
while (contador == MAX_ELEMENTOS)
haz_nada;
buffer[indice_p] = elemento_p;
indice_p = (indice_p + 1) %
MAX_ELEMENTOS;
contador = contador + 1;
} while (TRUE);

Sincronización de
 2009-2010 Mariano Gómez Plaza
procesos 4
Código del consumidor
 El consumidor no puede leer del buffer si está vacío
 Comparte con el productor: el buffer y el contador
do {
while (contador == 0) haz_nada;
elemento_c = buffer[indice_c];
indice_c = (indice_c + 1) %
MAX_ELEMENTOS;
contador = contador - 1;
...
consume el elemento (elemento_c)
...
} while (TRUE);

Sincronización de
 2009-2010 Mariano Gómez Plaza
procesos 5
Condiciones de carrera
 El código anterior no funciona por existir
condiciones de carrera al actualizar el contador
 Veamos qué ocurre al ejecutar la sentencia:
contador = contador + 1;
Productor Consumidor
load r0, contador load r0, contador
add r0, 1 sub r0, 1
store contador, r0 store contador, r0
 Problema: la modificación del contador no es
atómica

Sincronización de
 2009-2010 Mariano Gómez Plaza
procesos 6
Atomicidad
 Una operación se dice que es atómica (en un
sistema uniprocesador) cuando se ejecuta con las
interrupciones deshabilitadas
 Las referencias y las asignaciones son atómicas en
la mayoría de los sistemas. Esto no es siempre
cierto para matrices, estructuras o números en
coma flotante
 Si el HW no proporciona operaciones atómicas,
éstas no pueden construirse por SW

Sincronización de
 2009-2010 Mariano Gómez Plaza
procesos 7
Sincronización
Persona B
Persona A
3:00 Mira en la nevera. No hay leche

3:05 Va a la tienda

3:10 Llega a la tienda Mira en la nevera. No hay leche

3:15 Deja la tienda Va a la tienda

3:20 Llega a casa y guarda la leche Llega a la tienda

3:25 Deja la tienda

3:30 Llega a casa y ...


Sincronización de
 2009-2010 Mariano Gómez Plaza
procesos 8
¿Cuál es el problema planteado?
Alguien necesita leche, pero no tanta
 Exclusión mutua: es el mecanismo que asegura
que sólo una persona o proceso está haciendo algo
en un instante determinado (los otros están
excluidos).
 Sección crítica: es la sección de código, o
colección de operaciones, en el que se actualizan
variables comunes. Cuando un proceso está
ejecutando código de su SC, ningún otro proceso
puede estar en su SC

Sincronización de
 2009-2010 Mariano Gómez Plaza
procesos 9
Problema de la sección crítica
 Toda solución debe cumplir tres condiciones
Exclusión mutua
Progreso
Espera limitada
 Solución general:
do {
protocolo de entrada
sección crítica
protocolo de salida
resto de la sección
} while (TRUE);

Sincronización de
 2009-2010 Mariano Gómez Plaza
procesos 10
Tipos de soluciones
 Suposiciones:
 Los procesos se ejecutan a una velocidad  0
 Su velocidad relativa no influye
 Soluciones basadas en variables de control
 Soluciones basadas en instrucciones máquina
específicas (test-and-set o swap)
 Soluciones basadas en primitivas del SO
 Soluciones basadas en regiones críticas y
monitores

Sincronización de
 2009-2010 Mariano Gómez Plaza
procesos 11
Solución con variables de control
 Válidas para varios procesadores
 Suposición: las instrucciones de carga y
almacenamiento son atómicas
Primer intento
 Ti y Tj comparten la variable turno

Thread Ti
do {
while (turno != i) haz_nada;
sección crítica
turno = j;
resto de la sección
} while (TRUE);

Sincronización de
 2009-2010 Mariano Gómez Plaza
procesos 12
Segundo intento
 Variables compartidas:
flag[i] = FALSE;
flag[j] = FALSE;
 Estas variables indican la intención de los hilos de entrar
en sección crítica
Thread Ti
do {
flag[i] = TRUE;
while (flag[j]) haz_nada;
sección crítica
flag[i] = FALSE;
resto de la sección
} while (TRUE);

Sincronización de
 2009-2010 Mariano Gómez Plaza
procesos 13
Tercer intento (Dekker)
 Variables compartidas:
int turno, flag[2];
flag[i] = flag[j] = FALSE;
Thread Ti
do {
flag[i] = TRUE;
turno = j;
while (flag[j] && (turno == j))
haz_nada;
sección crítica
flag[i] = FALSE;
resto de la sección
} while (TRUE);

Sincronización de
 2009-2010 Mariano Gómez Plaza
procesos 14
Sincronización hardware
int test_and_set (int *destino) {
int aux;
aux = *destino;
*destino = TRUE;
return (aux); }
 Variable compartida cerrojo iniciada a FALSE
do {
while (test_and_set (&cerrojo))
haz_nada;
sección crítica
cerrojo = FALSE;
resto de la sección
} while (TRUE);

Sincronización de
 2009-2010 Mariano Gómez Plaza
procesos 15
Instrucción swap
void swap (int *a, int *b) {
int aux;
aux = *a;
*a = *b;
*b = aux; }
 Variable compartida cerrojo iniciada a FALSE
do { llave = TRUE;
do {
swap (cerrojo, llave);
} while (llave != FALSE);
sección crítica
cerrojo = FALSE;
resto de la sección
} while (TRUE);

Sincronización de
 2009-2010 Mariano Gómez Plaza
procesos 16
Semáforos
 Introducidos por Dijkstra en los años 60
 Es un tipo especial de variable que sólo puede ser
accedida por dos primitivas P y V
 P (semáforo): operación atómica que espera
hasta que la variable semáforo sea positiva, en este
momento la decrementa en 1
 V (semáforo): operación atómica que incrementa
la variable semáforo en 1
 ¿Cómo quedaría el problema de la sección crítica
con semáforos?

Sincronización de
 2009-2010 Mariano Gómez Plaza
procesos 17
Características de los semáforos
 Son independientes de la máquina
 Son simples
 Pueden trabajar con varios procesos
 Pueden permitir que varios procesos entren en la
sección crítica al mismo tiempo en caso de
necesitarse esta posibilidad
 Doble uso de los semáforos:
 Exclusión mutua
 Sincronización

Sincronización de
 2009-2010 Mariano Gómez Plaza
procesos 18
Productor-consumidor
 Restricciones:
El consumidor espera a que haya datos en el buffer
El productor espera a que haya buffers vacíos
Sólo un único proceso puede manipular el buffer a la
vez
 Semáforos:
smf_llenos, smf_vacíos y exmut
 Inicialización:
smf_llenos = 0
smf_vacíos = número_de_buffers
exmut = 1

Sincronización de
 2009-2010 Mariano Gómez Plaza
procesos 19
Productor Consumidor
P (smf_vacíos); P (smf_llenos);
P (exmut); P (exmut);
Produce un dato; Consume el dato;
V (exmut); V (exmut);
V (smf_llenos); V (smf_vacíos);

¿Por qué el productor hace P(smf_vacíos) y


V(smf_llenos)?
¿Es importante el orden en que se ejecutan las
primitivas P y V?
¿Cómo podemos extender el problema si hay dos
consumidores?
Sincronización de
 2009-2010 Mariano Gómez Plaza
procesos 20
Lectores-escritores
 Descripción:
 Los escritores acceden a la BBDD cuando no
haya ningún otro escritor y ningún lector.
Semáforo escribir
 Los lectores acceden cuando no haya ningún
escritor accediendo o esperando. Semáforo
leer
 Variables compartidas: LA, LE, EA, EE. A estas
variables accederemos en exclusión mutua.
Semáforo exmut

Sincronización de
 2009-2010 Mariano Gómez Plaza
procesos 21
Iniciación
 leer = escribir = 0
 exmut = 1
 LA = EA = LE = EE = 0
 Además:
 Los escritores tienen prioridad sobre los lectores

Sincronización de
 2009-2010 Mariano Gómez Plaza
procesos 22
Lector Escritor
P (exmut); P (exmut);
if ((EA + EE) == 0) { if (( EA + LA + EE) == 0){
V (escribir);
V (leer); EA = EA + 1;
LA = LA + 1; } else {
} else { EE = EE + 1;
LE = LE + 1; }
V (exmut);
} P (escribir);
V (exmut); Escribimos los datos;
P (leer); P (exmut);
Leemos los datos; EA = EA - 1;
if (EE > 0) {
P (exmut); V (escribir);
LA = LA - 1; EA = EA + 1;
if (LA == 0 && EE > 0) { EE = EE - 1;
V (escribir); } else while (LE > 0) {
V (leer);
EA = EA + 1; LA = LA + 1;
EE = EE - 1; LE = LE - 1;
} }
V (exmut); V (exmut);

Sincronización de
 2009-2010 Mariano Gómez Plaza
procesos 23
Casos particulares
 Un lector entra y deja el sistema
 Un escritor entra y deja el sistema
 Entran dos lectores al sistema
 Un escritor entra y debe esperar
 Un lector entra y debe esperar
 Los lectores abandonan el sistema y el escritor
continúa
 Los escritores abandonan el sistema, y el último
lector continúa y abandona

Sincronización de
 2009-2010 Mariano Gómez Plaza
procesos 24
Problema de los filósofos
 Variables compartidas:
exmut
semaforo[N]

void filosofo (int i) {


while (TRUE) {
piensa();
toma_tenedores(i);
come();
pon_tenedores(i);
}
} /* Fin de filosofo */

Sincronización de
 2009-2010 Mariano Gómez Plaza
procesos 25
Problema de los filósofos
void toma_tenedores(int i) {
P(exmut);
estado[i] = HAMBRIENTO;
comprueba(i);
V(exmut);
P(semaforo[i]);
} /* Fin de toma_tenedores */

void pon_tenedores(int i) {
P(exmut);
estado[i] = PENSANDO;
comprueba((i-1)%N);
comprueba((i+1)%N);
V(exmut);
} /* Fin de pon_tenedores */

Sincronización de
 2009-2010 Mariano Gómez Plaza
procesos 26
Problema de los filósofos
void comprueba(int i) {
if (estado[i] == HAMBRIENTO
&& estado[(i-1)%N] != COMIENDO
&& estado[(i+1)%N] != COMIENDO)
{
estado[i] = COMIENDO;
V(semaforo[i]);
}
} /* Fin de comprueba */
 ¿A qué valores se deben iniciar los semáforos?
 ¿Por qué la función comprueba siempre se invoca
desde una sección crítica?

Sincronización de
 2009-2010 Mariano Gómez Plaza
procesos 27
Problema del barbero dormilón
 Problema: 1 barbero y N sillas de espera
 Si un cliente entra y no hay sillas, se va
 Semáforos:
clientes: número de clientes en espera sin
contar el que está en la silla del peluquero
barberos: número de barberos inactivos
exmut: exclusión mutua
 Variable compartida:
esperando: número de clientes esperando
 Inicialmente:
clientes=0 barberos=0 exmut=1 esperando=0

Sincronización de
 2009-2010 Mariano Gómez Plaza
procesos 28
Barbero Cliente
do { do {
P(clientes); P(exmut);
P(exmut); if (esperando < SILLAS) {
esperando=esperando-1; esperando=esperando + 1;
V(barberos); V(clientes);
V(exmut); V(exmut);
P(barberos);
/* Se corta el pelo */
/* Corta el pelo */
} else {
V(exmut);
} while (TRUE);
}
} while (PELOLARGO);

Sincronización de
 2009-2010 Mariano Gómez Plaza
procesos 29
Problema del puente estrecho
 Por un puente sólo pueden pasar o coches que
suben o coches que bajan.
 Solución:
 Variables compartidas:
int contadorsubida = 0, contadorbajada = 0;
semaforo exmut_s, exmut_b, puente;
 Iniciación:
 Los semáforos inicialmente deben valer 1
 No se tratan los problemas de inanición

Sincronización de
 2009-2010 Mariano Gómez Plaza
procesos 30
Código subida Código bajada
P(exmut_s); P(exmut_b);
contadorsubida++; contadorbajada++;
if (contadorsubida == 1) if (contadorbajada == 1)
P(puente); P(puente);
V(exmut_s); V(exmut_b);

... Se sube el puente ... ... Se baja el puente ...

P(exmut_s); P(exmut_b);
contadorsubida--; contadorbajada--;
if (contadorsubida == 0) if (contadorbajada == 0)
V(puente);
V(puente);
V(exmut_b);
V(exmut_s);

Sincronización de
 2009-2010 Mariano Gómez Plaza
procesos 31
Codificación los semáforos
 Las primitivas P y V se realizan por SW
 Razón: P y V se ven implicados en aspectos de
planificación
 Partimos de la siguiente declaración:
typedef struct {
int contador;
(cola q;)
int t; /* Para multiprocesadores
*/
} SEMAFORO;
 En el caso de los semáforos con espera activa el
código entre paréntesis sobra
Sincronización de
 2009-2010 Mariano Gómez Plaza
procesos 32
P y V en spin locks (espera activa)
P (SEMAFORO *s) { V (SEMAFORO *s) {
while (1) { cli;
cli; s->contador+ = 1;
if (s->contador > 0) sti;
{ }
s->contador- = 1;
sti;
return;
}
sti;
} /* fin del while */
}

Sincronización de
 2009-2010 Mariano Gómez Plaza
procesos 33
P y V en sistemas uniprocesador
P (SEMAFORO *s) { V (SEMAFORO *s) {
cli; cli;
if (s->contador > 0) if (s->q == vacía) {
{ s->contador+ = 1;
s->contador- = 1; } else {
sti; Sacar proceso de s-
return; >q
} Despertarlo
Añadimos proc. a s->q }
sti; sti;
Planificación }
}

Sincronización de
 2009-2010 Mariano Gómez Plaza
procesos 34
P y V en sistemas multiprocesador
P (SEMAFORO *s) { V (SEMAFORO *s) {
while (TAS(s->t) != 0); while (TAS(s->t) != 0);
if (s->contador > 0) { if (s->q vacía) {
s->contador- = 1; s->contador+ = 1;
s->t = 0; } else {
return; Sacar proceso de s-
} >q;
Añadimos proc. a s->q Despertarlo;
s->t = 0; }
Planificación s->t = 0;
} }

Sincronización de
 2009-2010 Mariano Gómez Plaza
procesos 35
Comunicación con mensajes
 Válido para comunicación intermáquina
 Definición:
 Mensaje: parte de información que es pasada de
un proceso a otro
 Buzón: lugar donde se depositan los mensajes
desde el envío a la recepción
 Operaciones sobre mensajes:
 Enviar
 Recibir

Sincronización de
 2009-2010 Mariano Gómez Plaza
procesos 36
Métodos de comunicación
 Comunicación en un único sentido: los mensajes
fluyen en un único sentido
 Ejemplos: Tuberías de UNIX, productor-
consumidor y streams
 Comunicación bidireccional: los mensajes fluyen en
ambos sentidos
 Ejemplos: Llamadas a procedimientos remotos
(RPC´s) o el modelo cliente-servidor

Sincronización de
 2009-2010 Mariano Gómez Plaza
procesos 37
Ejemplos
 Productor:  Consumidor:
int mensaje1[1000]; int mensaje2[1000];
while (1) { while (1) {
--Preparamos el recibir (mensaje2,
mensaje1-- buzón);
enviar (mensaje1, --Procesamos el
buzón); mensaje2--
} }
 Cliente:  Servidor:
char resp[1000]; char orden[100];
envia(“leer vax”, char resp[1000];
buzon1); recibir (orden, buzon1);
recibir (resp, buzon2); enviar (resp, buzon2);

Sincronización de
 2009-2010 Mariano Gómez Plaza
procesos 38
¿Por qué utilizar mensajes?
 Muchas aplicaciones responden a este esquema
 Las partes que se comunican pueden ser
completamente independientes.
 Ventajas:
 Es más difícil que se produzcan errores
 Permite que los procesos no confíen entre sí
 Las aplicaciones pueden ser escritas por
programadores y en tiempos diferentes
 Los procesos pueden correr en diferentes
procesadores, conectados a través de una red

Sincronización de
 2009-2010 Mariano Gómez Plaza
procesos 39
Implementación de los mensajes
 Nombres
 Comunicación simétrica
 Comunicación asimétrica
 Copiado
 Paso por valor: es lento y obligatorio en sistemas
sin memoria compartida
 Paso por referencia: es rápido pero hay
problemas con su modificación
 Híbrido: copy-on-write

Sincronización de
 2009-2010 Mariano Gómez Plaza
procesos 40
Implementación de los mensajes
 Bloqueo versus no bloqueo
 enviar y recibir pueden ser bloqueantes o no
 Formas de espera en un buzón:
Varios procesos pueden esperar en un buzón
Un proceso puede esperar en varios buzones
 Longitud
 Mensajes de longitud fija
 Mensajes de longitud variable

Sincronización de
 2009-2010 Mariano Gómez Plaza
procesos 41

También podría gustarte