Está en la página 1de 195

Sistemas Operativos

Oscar Bedoya
oscarbed@eisc.univalle.edu.co
* Sincronización de procesos
* Sección crítica
* Semáforos
* Sincronización en Java
Sincronización de procesos

• Suponga un archivo cuyos registros están compuestos de los


siguientes cuatro campos:

Cédula Salario Dirección Teléfono


1152984120 4.000.000 Calle 13 # 339 1745
100 - 00
10066044 5.800.000 Calle 25 # 336 4346
25 A 44

• Se tienen dos tipos de procesos:


- Lectores
- Escritores
Sincronización de procesos

• Los problemas se presentan cuando los procesos obtienen acceso a


datos compartidos modificables
• Debe existir una sincronización entre procesos de tal manera que
cuando se esté modificando un registro, se impida el acceso al dato.
Esta sincronización se conoce como exclusión mutua
Sincronización de procesos

Problema del restaurante Chino


colocarPedido() atenderPedido()

cantidad
Cocinero 3 Mensajero

El proceso Mensajero
intenta tomar 2 pedidos. Si
solo hay 1 ó 0 espera hasta
que por lo menos hayan dos
Sincronización de procesos

Cocinero (Thread) Mensajero (Thread)

Mesa mesa; Mesa mesa;

run() run()

usa usa

Mesa Programa
int cantidad usa
Mesa mesa;
colocarPedido() Cocinero procesoCocinero;
atenderPedido() Mensajero procesoMensajero;
main()
public class Mesa{
int cantidad;

public Mesa(){
cantidad=0;
}

public void colocarPedido(){


cantidad=cantidad+1;
}

public void atenderPedido(){


while (cantidad<2)
;
cantidad=cantidad-2;
}

}
public class Mesa{
int cantidad;
• Cocinero y Mensajero comparten
la variable cantidad
public Mesa(){
cantidad=0;
}

public void colocarPedido(){


cantidad=cantidad+1;
}

public void atenderPedido(){


while (cantidad<2)
;
cantidad=cantidad-2;
}

}
public class Mesa{
1 cantidad 3
int cantidad;

public Mesa(){
cantidad=0;
}

public void colocarPedido(){


cantidad=cantidad+1; 2
}

public void atenderPedido(){


while (cantidad<2)
;
cantidad=cantidad-2; 3

}
public class Mesa{
1 cantidad 3
int cantidad;

public Mesa(){
cantidad=0;
}

public void colocarPedido(){ register1=cantidad


cantidad=cantidad+1; 2 register1=register1+1
} cantidad=register1

public void atenderPedido(){


while (cantidad<2)
; register2=cantidad
cantidad=cantidad-2; 3 register2=register2-2
} cantidad=register2

}
1 cantidad 3

r1 r2 c
register1=cantidad
0 0 3
2 register1=register1+1
cantidad=register1

register2=cantidad
3 register2=register2-2
cantidad=register2
1 cantidad 3

r1 r2 c
register1=cantidad
3 0 3
2 register1=register1+1
cantidad=register1

register2=cantidad
3 register2=register2-2
cantidad=register2
1 cantidad 3

register1=cantidad
r1 r2 c
2 register1=register1+1
4 0 3
cantidad=register1

register2=cantidad
3 register2=register2-2
cantidad=register2
1 cantidad 3

register1=cantidad
r1 r2 c
2 register1=register1+1
4 0 4
cantidad=register1

register2=cantidad
3 register2=register2-2
cantidad=register2
1 cantidad 3

register1=cantidad
2 register1=register1+1
cantidad=register1

r1 r2 c
register2=cantidad
4 4 4
3 register2=register2-2
cantidad=register2
1 cantidad 3

register1=cantidad
2 register1=register1+1
cantidad=register1

register2=cantidad
r1 r2 c
3 register2=register2-2
4 2 4
cantidad=register2
1 cantidad 3

register1=cantidad
2 register1=register1+1
cantidad=register1

register2=cantidad
3 register2=register2-2 r1 r2 c
cantidad=register2 4 2 2
1 cantidad 3

register1=cantidad
2 register1=register1+1
cantidad=register1

register2=cantidad
3 register2=register2-2
cantidad=register2 cantidad 2

Si TODAS las instrucciones se


ejecutaran secuencialmente
1 cantidad 3

register1=cantidad register2=cantidad
2 register1=register1+1 3
register2=register2-2
cantidad=register1 cantidad=register2
1 cantidad 3

register1=cantidad
2 register1=register1+1 3
register2=cantidad
register2=register2-2
cantidad=register1
cantidad=register2
1 cantidad 3

r1 r2 c
register1=cantidad 3 0 3
2 register1=register1+1 3
register2=cantidad
register2=register2-2
cantidad=register1
cantidad=register2
1 cantidad 3

register1=cantidad r1 r2 c
2 register1=register1+1 4 0 3
register2=cantidad
register2=register2-2
cantidad=register1
cantidad=register2
1 cantidad 3

register1=cantidad
2 register1=register1+1 r1 r2 c
register2=cantidad
4 3 3
register2=register2-2
cantidad=register1
cantidad=register2
1 cantidad 3

register1=cantidad
2 register1=register1+1
register2=cantidad
r1 r2 c
register2=register2-2
4 1 3
cantidad=register1
cantidad=register2
1 cantidad 3

register1=cantidad
2 register1=register1+1
register2=cantidad
register2=register2-2 r1 r2 c
cantidad=register1 4 1 4
cantidad=register2
1 cantidad 3

register1=cantidad
2 register1=register1+1
register2=cantidad
register2=register2-2
cantidad=register1 r1 r2 c
cantidad=register2 4 1 1
1 cantidad 3

register1=cantidad
2 register1=register1+1
register2=cantidad
register2=register2-2
cantidad=register1
cantidad=register2

cantidad 1
1 cantidad 3

register1=cantidad
2 register1=register1+1
register2=cantidad
register2=register2-2
cantidad=register1
cantidad=register2

cantidad 1
El valor incorrecto para cantidad
se presenta porque se permite
que ambos hilos manipulen la
variable cantidad de manera
concurrente
1 cantidad 3

r1=0 r2=3 c=3


register2=cantidad
2 register1=cantidad
register2=register2-2
register1=register1+1
cantidad=register2
cantidad=register1

cantidad ?
Indique el valor de cantidad al
final de la ejecución
1 cantidad 3

r1=0 r2=3 c=3


register2=cantidad
2 register1=cantidad r1=3 r2=3 c=3

register2=register2-2 r1=3 r2=1 c=3


register1=register1+1 r1=4 r2=1 c=3
cantidad=register2 r1=4 r2=1 c=1
cantidad=register1
r1=4 r2=1 c=4

cantidad 4
public class Mesa{
1 cantidad 3
int cantidad;

public Mesa(){
cantidad=0;
}

public void colocarPedido(){ register1=cantidad


cantidad=cantidad+1; 2 register1=register1+1
} cantidad=register1

public void atenderPedido(){


while (cantidad<2)
; register2=cantidad
cantidad=cantidad-2; 3 register2=register2-2
} cantidad=register2

}
Sincronización de procesos

• La parte del código que no puede ser interrumpida por otro proceso
(p. ej modificar un registro, modificar una variable compartida) se
denomina sección crítica
• Cuando un hilo o proceso se ejecuta en su sección crítica, ningún
otro proceso puede acceder a la misma parte del código
Sincronización de procesos

Sincronización
Los algoritmos que se han propuesto para permitir sincronización
entre procesos se pueden clasificar en tres grupos:
1. Espera activa
2. Espera no activa*
3. Mecanismos hardware
public class Mesa{
int cantidad;

public Mesa(){
cantidad=0;
}

public void colocarPedido(){


cantidad=cantidad+1;
}

public void atenderPedido(){ Acá se presenta espera activa,


while (cantidad<2) es decir, el proceso sigue
; compitiendo por procesador aun
cantidad=cantidad-2; cuando no lo necesita
}

}
Sincronización de procesos

Problema del restaurante Chino


colocarPedido() atenderPedido()

cantidad
Cocinero 3 Mensajero
atenderPedido()
colocarPedido()
Cocinero Mensajero

Mensajero
Cocinero
atenderPedido()
colocarPedido()
Sincronización de procesos

Semáforos
(Dijkstra 1965)
Sincronización de procesos

Dijkstra
(1930 – 2002)
Sincronización de procesos

Proceso 1 Proceso 3

Proceso 4
Proceso 2
Proceso 5

S:3
Sincronización de procesos

pedir
Proceso 1 Proceso 3

Proceso 4
Proceso 2
Proceso 5

S:3
Sincronización de procesos

Proceso 1 Proceso 3

Proceso 4
Proceso 2
Proceso 5

S:2
Sincronización de procesos

Proceso 1 Proceso 3

Proceso 4
Proceso 2
pedir
Proceso 5

S:2
Sincronización de procesos

Proceso 1 Proceso 3

Proceso 4
Proceso 2
Proceso 5

S:1
Sincronización de procesos

Proceso 1 Proceso 3

Proceso 4
Proceso 2
devolver
Proceso 5

S:2
Sincronización de procesos

Proceso 1 Proceso 3

Proceso 4
Proceso 2
pedir
Proceso 5

S:2
Sincronización de procesos

Proceso 1 Proceso 3

Proceso 4
Proceso 2
Proceso 5

S:1
Sincronización de procesos

pedir
Proceso 1 Proceso 3

Proceso 4
Proceso 2
Proceso 5

S:1
Sincronización de procesos

Proceso 1 Proceso 3

Proceso 4
Proceso 2
Proceso 5

S:0
Sincronización de procesos

Proceso 1 Proceso 3

Proceso 4
pedir
Proceso 2
Proceso 5

El proceso 2 espera a
que alguien devuelva
un recurso

S:0
Sincronización de procesos

Proceso 1 Proceso 3

pedir
Proceso 4
pedir
Proceso 2
Proceso 5

El proceso 2 espera a
que alguien devuelva El proceso 4 espera a
un recurso que alguien devuelva un
recurso
S:0
Sincronización de procesos

Proceso 1 Proceso 3

pedir
Proceso 4
pedir
Proceso 2
Proceso 5

Valor actual del


S:0 semáforo
Sincronización de procesos

Un semáforo es una variable entera que tiene dos operaciones:

- P(). Permite pedir un recurso. Disminuye en 1 el valor del semáforo


si hay recursos disponibles. Sino lo obliga a esperar

- V(). Permite indicar que hay un recurso más disponible. Aumenta


en 1 el valor del semáforo
Sincronización de procesos

P()
Proceso 1 Proceso 3

Proceso 4
Proceso 2
Proceso 5

S:2
Sincronización de procesos

Proceso 1 Proceso 3

Proceso 4
Proceso 2
Proceso 5

S:1
Sincronización de procesos

Proceso 1 Proceso 3

Proceso 4
Proceso 2
V()
Proceso 5

S:2
Sincronización de procesos

Proceso 1 Proceso 3

Proceso 4
P()
Proceso 2
Proceso 5

S:0
Sincronización de procesos

Semaforo
int valor;
P()
V()
public class Semaforo{

int valor;

En el constructor se indica
public Semaforo(int v){ la cantidad de recursos
iniciales del semáforo
valor = v;
}

public void P(){

public void V(){

}
}
Sincronización de procesos

Proceso 1 Proceso 3

Recurso
Recurso Proceso 4
Proceso 2 Recurso
Proceso 5
semáforo1: 3
Sincronización de procesos

Proceso 1 Proceso 3

Recurso
Recurso Proceso 4
Proceso 2 Recurso
Proceso 5
semáforo1: 3

Semaforo semaforo1=new Semaforo(3);


Sincronización de procesos

Proceso 1 Proceso 3

Recurso
Recurso Proceso 4
Proceso 2 Recurso
Proceso 5
semáforo1: 3

Semaforo semaforo1=new Semaforo(3);


Crea un semáforo que permite
sincronizar 3 recursos
Sincronización de procesos

semaforo1.P();

Proceso 1 Proceso 3

Recurso
Recurso Proceso 4
Proceso 2 Recurso
Proceso 5
semáforo1: 3

semaforo1.P(): si hay un recurso disponible se concede y se


disminuye en 1 el semáforo, sino, espera a que alguien libere
alguno
Sincronización de procesos

Proceso 1 Recurso Proceso 3

Recurso
Recurso Proceso 4
Proceso 2
Proceso 5
semáforo1: 2
Sincronización de procesos

semaforo1.V();

Proceso 1 Recurso Proceso 3

Recurso
Recurso Proceso 4
Proceso 2
Proceso 5
semáforo1: 2

semaforo1.V(): indica que hay un recurso más disponible. El


semáforo se aumenta en 1
Sincronización de procesos

Proceso 1 Proceso 3

Recurso
Recurso Proceso 4
Proceso 2 Recurso
Proceso 5
semáforo1: 3
Proceso1: Proceso2: Proceso3:
public void run(){ public void run(){ public void run(){
... ... semaforo.P();
semaforo.P(); ... imprime(“1”)
imprime(“a”); semaforo.P(); imprime(“2”)
imprime(“b”); imprime(“I”) imprime(“3”)
imprime(“c”); imprime(“II”) imprime(“4”)
imprime(“d”); imprime(“III”) semaforo.V();
imprime(“e”); imprime(“IV”) }
imprime(“f”); semaforo.V();
imprime(“g”); }
imprime(“h”);
semaforo.V();
}

Semaforo semaforo=new Semaforo(2);


Proceso1: Proceso2: Proceso3:
public void run(){ public void run(){ public void run(){
... ... semaforo.P();
semaforo.P(); ... imprime(“1”)
imprime(“a”); semaforo.P(); imprime(“2”)
imprime(“b”); imprime(“I”) imprime(“3”)
imprime(“c”); imprime(“II”) imprime(“4”)
imprime(“d”); imprime(“III”) semaforo.V();
imprime(“e”); imprime(“IV”) }
imprime(“f”); semaforo.V();
imprime(“g”); }
imprime(“h”);
semaforo.V();
}

Semaforo semaforo=new Semaforo(2);


Si se ejecutan los tres procesos al tiempo, en
qué orden imprimen
Proceso1: Proceso2: Proceso3:
public void run(){ public void run(){ public void run(){
... ... semaforo.P();
semaforo.P(); ... imprime(“1”)
imprime(“a”); semaforo.P(); imprime(“2”)
imprime(“b”); imprime(“I”) imprime(“3”)
imprime(“c”); imprime(“II”) imprime(“4”)
imprime(“d”); imprime(“III”) semaforo.V();
imprime(“e”); imprime(“IV”) }
imprime(“f”); semaforo.V();
imprime(“g”); }
imprime(“h”);
semaforo.V();
}

Semaforo semaforo=new Semaforo(1);


Si se ejecutan los tres procesos al tiempo, en
qué orden imprimen
Sincronización de procesos

Semáforos
Existen dos tipos de semáforos:
• Semáforo binario (mutex)
• Semáforo de conteo
Sincronización de procesos

Semáforo binario (mutex)


Se utiliza cuando solo se tiene un recurso al cual proveer exclusión
mutua.

Semaforo mutex=new Semaforo(1);


Proceso1: Proceso2: Proceso3:
public void run(){ public void run(){ public void run(){
... ... semaforo.P();
semaforo.P(); ... imprime(“1”)
imprime(“a”); semaforo.P(); imprime(“2”)
imprime(“b”); imprime(“I”) imprime(“3”)
imprime(“c”); imprime(“II”) imprime(“4”)
imprime(“d”); imprime(“III”) semaforo.V();
imprime(“e”); imprime(“IV”) }
imprime(“f”); semaforo.V();
imprime(“g”); }
imprime(“h”);
semaforo.V();
}

Semaforo semaforo=new Semaforo(1);


Si se ejecutan los tres procesos al tiempo, en
que orden imprimen
Sincronización de procesos

Proceso 1 Proceso 3

Proceso 4
Proceso 2
Proceso 5
1

Semáforo binario: el valor de S sólo puede ser 0 ó 1


Proceso1: Proceso2:
public void run(){ public void run(){
... ...
mutex.P(); ...
imprime(“a”); mutex.P();
imprime(“b”); imprime(“I”)
imprime(“c”); imprime(“II”)
imprime(“d”); imprime(“III”)
imprime(“e”); imprime(“IV”)
imprime(“f”); mutex.V();
imprime(“g”); }
imprime(“h”);
mutex.V();
}

Semaforo mutex=new Semaforo(1);


Si se ejecutan los dos procesos al tiempo, en
qué orden imprimen
Proceso1: Proceso2:
public void run(){ public void run(){
... ...
mutex.P(); ...
cantidad=cantidad+1; mutex.P();
mutex.V(); cantidad=cantidad-5;
} mutex.V();
}

Semaforo mutex=new Semaforo(1);


Si se ejecutan los dos procesos al tiempo, en
qué orden se modifica la variable cantidad
Proceso1: Proceso2:
public void run(){ public void run(){
... ...
mutex.P(); mutex.P();
cantidad=cantidad+1; cantidad=cantidad-5;
mutex.V(); mutex.V();
} }

Semaforo mutex=new Semaforo(1);


Si se ejecutan los dos procesos al tiempo, en
qué orden se modifica la variable cantidad
Proceso1: Proceso2:
public void run(){ public void run(){
... ...
mutex.P(); mutex.P();
cantidad=cantidad+1; cantidad=cantidad-5;
mutex.V(); mutex.V();
} }

Con un mutex se garantiza que solo uno de


los dos conjuntos de instrucciones se
ejecutan en un momento dado
Proceso1: Proceso2:
public void run(){ public void run(){
... ...
mutex.P(); mutex.P();
cantidad=cantidad+1; cantidad=cantidad-5;
mutex.V(); mutex.V();
} }

La parte del código que solo puede ejecutar


un proceso al tiempo se conoce como
sección critica
public class Mesa{
1 cantidad 3
int cantidad;

public Mesa(){
cantidad=0;
}

public void colocarPedido(){ register1=cantidad


cantidad=cantidad+1; 2 register1=register1+1
} cantidad=register1

public void atenderPedido(){


while (cantidad<2)
; register2=cantidad
cantidad=cantidad-2; 3 register2=register2-2
} cantidad=register2

}
Sincronización de procesos

Semáforos de conteo
Permite sincronizar el uso de n recursos por cualquier cantidad de
procesos

Semaforo semaforo=new Semaforo(n);


donde n es un número entero
Proceso1: Proceso2: Proceso3:
public void run(){ public void run(){ public void run(){
... ... semaforo.P();
semaforo.P(); ... imprime(“1”)
imprime(“a”); semaforo.P(); imprime(“2”)
imprime(“b”); imprime(“I”) imprime(“3”)
imprime(“c”); imprime(“II”) imprime(“4”)
imprime(“d”); imprime(“III”) semaforo.V();
imprime(“e”); imprime(“IV”) }
imprime(“f”); semaforo.V();
imprime(“g”); }
imprime(“h”);
semaforo.V();
}

Semaforo semaforo=new Semaforo(2);


Sincronización de procesos

Semáforos
• Suponga que tiene tres impresoras y dos lectores de CD para
sincronizar, cuántos semáforos necesita?
Sincronización de procesos

Semaforo impresoras=new Semaforo(3); Semaforo lectores=new Semaforo(2);


Proceso1: Proceso2:
public void run(){ public void run(){
... ...
impresoras.P(); lectores.P();
imprime(“a”); leerDatosCD();
imprime(“b”); lectores.V();
imprime(“c”); impresoras.P();
impresoras.V(); imprime(“I”)
lectores.P(); imprime(“II”)
leerDatosCD(); imprime(“III”)
lectores.V(); imprime(“IV”)
} impresoras.V();
}

Semaforo impresoras=new Semaforo(1);


Semaforo lectores=new Semaforo(1);
Proceso1: Proceso2:
public void run(){ public void run(){
... ...
impresoras.P(); lectores.P();
lectores.P(); impresoras.P();
leerDatosCD(); leerDatosCD();
imprime(“a”); imprime(“I”)
lectores.V(); impresoras.V();
impresoras.V(); lectores.V();
} }

Semaforo impresoras=new Semaforo(1);


Semaforo lectores=new Semaforo(1);
Sincronización de procesos

Bloqueos mutuos (deadlock)


• Un conjunto de procesos se encuentra en bloqueo mutuo cuando
cada proceso en el conjunto está esperando un evento que solo puede
ser ocasionado por otro proceso en el conjunto
Problemas
Sincronización de procesos

Problema del restaurante Chino


colocarPedido() atenderPedido()

cantidadPedidos
Cocinero 3 Mensajero

• El proceso Cocinero siempre coloca 1


pedido en la mesa

• El proceso Mensajero intenta tomar


2 pedidos. Si solo hay 1 ó 0 espera
hasta que por lo menos hayan dos
Sincronización de procesos

Problema del restaurante Chino


colocarPedido() atenderPedido()

cantidadPedidos
Cocinero 3 Mensajero
atenderPedido()
Mensajero

Mensajero
atenderPedido()
Sincronización de procesos

Cocinero (Thread) Mensajero (Thread)

Mesa mesa; Mesa mesa;

run() run()

usa usa

Mesa Programa
int cantidadPedidos usa
Mesa mesa;
colocarPedido() Cocinero c1;
atenderPedido() Mensajero m1;
main()
Sincronización de procesos

Semaforo Cocinero (Thread) Mensajero (Thread)


int v; Mesa mesa; Mesa mesa;
P()
run() run()
V()

usa usa usa

Mesa Programa
int cantidadPedidos usa
Mesa mesa;
colocarPedido() Cocinero c1;
atenderPedido() Mensajero m1,m2,m3;
main()
public class Mesa{
int cantidadPedidos;

public Mesa(){
cantidadPedidos=0;
}

public void colocarPedido(){


cantidadPedidos = cantidadPedidos+1;
}

public void atenderPedido(){


while (cantidadPedidos<2)
;
cantidadPedidos = cantidadPedidos-2;
}

}
public class Mesa{
int cantidadPedidos;

public Mesa(){
cantidadPedidos=0;
}

public void colocarPedido(){


cantidadPedidos = cantidadPedidos+1;
}

public void atenderPedido(){


cantidadPedidos = cantidadPedidos-2;
}

}
Sincronización de procesos

Problema del restaurante Chino


colocarPedido() atenderPedido()

cantidadPedidos
Cocinero 3 Mensajero
atenderPedido()
Mensajero

¿Qué recurso necesita un Mensajero


mensajero para completar atenderPedido()
atenderPedido()?
¿Inicialmente cuántos
recursos hay en la mesa?
Sincronización de procesos

Problema del restaurante Chino


colocarPedido() atenderPedido()

cantidadPedidos
Cocinero 3 Mensajero
atenderPedido()
Mensajero

Mensajero
atenderPedido()

Semaforo cajasDisponibles=new Semaforo(0);


Sincronización de procesos

Problema del restaurante Chino


colocarPedido() atenderPedido()

cantidadPedidos
Cocinero 3 Mensajero
atenderPedido()
Mensajero

Semaforo cajasDisponibles=new Semaforo(0);

¿Quién hace cajasDisponibles.P()? disminuye el semáforo


¿Quién hace cajasDisponibles.V()? aumenta el semáforo
public class Mesa{
int cantidadPedidos;
Semaforo cajasDisponibles=new Semaforo(0);

public Mesa(){
cantidadPedidos=0;
}

public void colocarPedido(){


cantidadPedidos = cantidadPedidos+1;
}

public void atenderPedido(){


cantidadPedidos = cantidadPedidos-2;
}

}
public class Mesa{
int cantidadPedidos;
Semaforo cajasDisponibles=new Semaforo(0);

public Mesa(){
cantidadPedidos=0;
}

public void colocarPedido(){


cantidadPedidos = cantidadPedidos+1;
}

public void atenderPedido(){


cajasDisponibles.P();
cantidadPedidos = cantidadPedidos-2;
}

}
public class Mesa{
int cantidadPedidos;
Semaforo cajasDisponibles=new Semaforo(0);

public Mesa(){
cantidadPedidos=0;
}

public void colocarPedido(){


cantidadPedidos = cantidadPedidos+1;
}

public void atenderPedido(){


cajasDisponibles.P();
cajasDisponibles.P();
cantidadPedidos = cantidadPedidos-2;
}

}
public class Mesa{
int cantidadPedidos;
Semaforo cajasDisponibles=new Semaforo(0);

public Mesa(){
cantidadPedidos=0;
}

¿Dónde se hace
public void colocarPedido(){
cantidadPedidos = cantidadPedidos+1;
cajasDisponibles.V()?
}

public void atenderPedido(){


cajasDisponibles.P();
cajasDisponibles.P();
cantidadPedidos = cantidadPedidos-2;
}

}
public class Mesa{
int cantidadPedidos;
Semaforo cajasDisponibles=new Semaforo(0);

public Mesa(){
cantidadPedidos=0;
}

public void colocarPedido(){


cantidadPedidos = cantidadPedidos+1;
cajasDisponibles.V();
}

public void atenderPedido(){


cajasDisponibles.P();
cajasDisponibles.P();
cantidadPedidos = cantidadPedidos-2;
}

}
public class Mesa{
int cantidadPedidos;
Semaforo cajasDisponibles=new Semaforo(0);

public Mesa(){
cantidadPedidos=0;
}
Suponga que quisiera
public void colocarPedido(){
asegurar que solo un hilo al
cantidadPedidos = cantidadPedidos+1; tiempo esté modificando la
cajasDisponibles.V(); variable cantidadPedidos,
} ¿cómo lo hace?
public void atenderPedido(){
cajasDisponibles.P();
cajasDisponibles.P();
cantidadPedidos = cantidadPedidos-2;
}

}
Proceso1: Proceso2:
public void run(){ public void run(){
... ...
mutex.P(); mutex.P();
cantidad=cantidad+1; cantidad=cantidad-5;
mutex.V(); mutex.V();
} }

La parte del código que solo puede ejecutar


un proceso al tiempo se conoce como
sección critica
public class Mesa{
int cantidadPedidos;
Semaforo cajasDisponibles=new Semaforo(0);

public Mesa(){
cantidadPedidos=0;
}

public void colocarPedido(){


cantidadPedidos = cantidadPedidos+1;
cajasDisponibles.V();
}

public void atenderPedido(){


cajasDisponibles.P();
cajasDisponibles.P();
cantidadPedidos = cantidadPedidos-2;
}

}
public class Mesa{
int cantidadPedidos;
Semaforo cajasDisponibles=new Semaforo(0);
Semaforo mutex=new Semaforo(1);
public Mesa(){
cantidadPedidos=0;
}
public void colocarPedido(){
mutex.P();
cantidadPedidos = cantidadPedidos+1;
mutex.V();
cajasDisponibles.V();
}
public void atenderPedido(){
cajasDisponibles.P();
cajasDisponibles.P();
mutex.P();
cantidadPedidos = cantidadPedidos-2;
mutex.V();
}
}
public class Mesa{
int cantidadPedidos;
Semaforo cajasDisponibles=new Semaforo(0);
Semaforo mutex=new Semaforo(1);
public Mesa(){
cantidadPedidos=0;
}
public void colocarPedido(){
Suponga que inicia el
mutex.P();
programa y el cocinero se
cantidadPedidos = cantidadPedidos+1;
queda dormido, ¿dónde
mutex.V();
espera el mensajero?
cajasDisponibles.V();
}
public void atenderPedido(){
cajasDisponibles.P();
cajasDisponibles.P();
mutex.P();
cantidadPedidos = cantidadPedidos-2;
mutex.V();
}
}
Sincronización de procesos

Problema del restaurante Chino


colocarPedido() atenderPedido()

cantidadPedidos
Cocinero 3 Mensajero
atenderPedido()
Mensajero

Mensajero
atenderPedido()

Son 3 mensajeros
Sincronización de procesos

Semaforo Cocinero (Thread) Mensajero (Thread)


int v; Mesa mesa; Mesa mesa;
P() int numeroMensajero;
run()
V() run()

usa usa usa

Mesa Programa
int cantidadPedidos usa
Mesa mesa;
colocarPedido() Cocinero c1;
atenderPedido() Mensajero m1,m2,m3;
main()
Sincronización de procesos

Problema de las naranjas


bajarNaranja() comerNaranja()

cantidadNaranjas
Reoolector 3 Comensal
bajarNaranja()
Reoolector
bajarNaranja() • Un recolector siempre baja de a una
Reoolector naranja
• El comensal come de a una naranja y
espera si no hay
Sincronización de procesos

Semaforo Comensal (Thread) Recolector (Thread)


int v; Canasto canasto; Canasto canasto;
P() int numeroRecolector;
run()
V() run()

usa usa usa

Canasto Programa
int cantidadNaranjas; usa
Canasto canasto;
bajarNaranja() Comensal c1;
comerNaranja() Recolector r1,r2,r3;
main()
public class Canasto{
int cantidadNaranjas;

public Canasto(){
cantidadNaranjas=0;
}

public void bajarNaranja(){

}
public void comerNaranja(){

}
}
Sincronización de procesos

Problema de las naranjas


bajarNaranja() comerNaranja()

cantidadNaranjas
Reoolector 3 Comensal
bajarNaranja()
Reoolector
bajarNaranja()

Reoolector

¿Qué recurso necesita un


comensal para completar
comerNaranja()?
¿Inicialmente cuántos
recursos hay en la mesa?
Sincronización de procesos

Problema de las naranjas


bajarNaranja() comerNaranja()

cantidadNaranjas
Reoolector 3 Comensal
bajarNaranja()
Reoolector
bajarNaranja()

Reoolector
Semaforo naranjasDisponibles=new Semaforo(0);
Sincronización de procesos

Problema de las naranjas


bajarNaranja() comerNaranja()

cantidadNaranjas
Reoolector 3 Comensal
bajarNaranja()
Reoolector
bajarNaranja()

Reoolector
Semaforo naranjasDisponibles=new Semaforo(0);

¿Quién hace naranjasDisponibles.P()? disminuye el semáforo


¿Quién hace naranjasDisponibles.V()? aumenta el semáforo
public class Canasto{
int cantidadNaranjas;
Semaforo naranjasDisponibles=new Semaforo(0);
Semaforo mutex=new Semaforo(1);
public Canasto(){
cantidadNaranjas=0;
}
public void bajarNaranja(){
mutex.P();
cantidadNaranjas = cantidadNaranjas+1;
mutex.V();
naranjasDisponibles.V();
}
public void comerNaranja(){
naranjasDisponibles.P();
mutex.P();
cantidadNaranjas = cantidadNaranjas-1;
mutex.V();
}
}
Sincronización de procesos

Problema de los recolectores y el glotón


colocarDulce() tomarDulce()
cantidadDulces
Recolector 3 Gloton
colocarDulce()

Recolector
colocarDulce()
Recolector

• Un recolector siempre coloca 1 dulce


en la mesa
• En la mesa caben máximo 10 dulces
• El Glotón toma siempre 1 dulce, si no
hay debe esperar
Sincronización de procesos

Recolector (Thread) Gloton (Thread)

Mesa mesa; Mesa mesa;

run() run()

usa usa

Mesa Programa
int cantidadDulces; usa
Mesa mesa;
colocarDulce() Recolector procesoRecolector;
tomarDulce() Gloton procesoGloton;
main()
Sincronización de procesos

Semaforo Recolector (Thread) Gloton (Thread)


int v; Mesa mesa; Mesa mesa;
P() int numeroRecolector;
run()
V() run()

usa usa usa

Mesa Programa
int cantidadDulces; usa
Mesa mesa;
colocarDulce() Recolector r1,r2,r3;
tomarDulce() Gloton g1;
main()
Sincronización de procesos

Problema de los recolectores y el glotón


colocarDulce() tomarDulce()
cantidadDulces
Recolector 3 Gloton
colocarDulce()

Recolector
colocarDulce()
Recolector

¿Qué recurso necesita un


glotón para completar
tomarDulce()?
¿Inicialmente cuántos
recursos hay en la mesa?
Sincronización de procesos

Problema de los recolectores y el glotón


colocarDulce() tomarDulce()
cantidadDulces
Recolector 3 Gloton
colocarDulce()

Recolector
colocarDulce()
Recolector

Semaforo dulcesDisponibles=new Semaforo(0);


Sincronización de procesos

Problema de los recolectores y el glotón


colocarDulce() tomarDulce()
cantidadDulces
Recolector 3 Gloton
colocarDulce()

Recolector
colocarDulce()
Recolector

Semaforo dulcesDisponibles=new Semaforo(0);

¿Quién hace dulcesDisponibles.P()?


¿Quién hace dulcesDisponibles.V()?
Sincronización de procesos

Problema de los recolectores y el glotón


colocarDulce() tomarDulce()
cantidadDulces
Recolector 3 Gloton
colocarDulce()

Recolector
colocarDulce()
Recolector

¿Qué recurso necesita un


recolector para completar
colocarDulce()?
¿Inicialmente cuántos
recursos hay en la mesa?
Sincronización de procesos

Problema de los recolectores y el glotón


colocarDulce() tomarDulce()
cantidadDulces
Recolector 3 Gloton
colocarDulce()

Recolector
colocarDulce()
Recolector

Semaforo espaciosDisponibles=new Semaforo(10);


Sincronización de procesos

Problema de los recolectores y el glotón


colocarDulce() tomarDulce()
cantidadDulces
Recolector 3 Gloton
colocarDulce()

Recolector
colocarDulce()
Recolector

Semaforo espaciosDisponibles=new Semaforo(10);

¿Quién hace espaciosDisponibles.P()?


¿Quién hace espaciosDisponibles.V()?
public class Mesa{
int cantidadDulces;
Semaforo mutex=new Semaforo(1);
Semaforo dulcesDisponibles=new Semaforo(0);
Semaforo espaciosDisponibles=new Semaforo(10);

public Mesa(){
cantidadDulces=0;
}

public void colocarDulce(){


cantidadDulces=cantidadDulces+1;
}

public void tomarDulce(){


cantidadDulces=cantidadDulces-1;
}
}
public class Mesa{
int cantidadDulces;
Semaforo mutex=new Semaforo(1);
Semaforo dulcesDisponibles=new Semaforo(0);
Semaforo espaciosDisponibles=new Semaforo(10);

public Mesa(){
cantidadDulces=0;
}

public void colocarDulce(){


cantidadDulces=cantidadDulces+1;
}

public void tomarDulce(){


cantidadDulces=cantidadDulces-1;
}
}
public class Mesa{
int cantidadDulces;
Semaforo mutex=new Semaforo(1);
Semaforo dulcesDisponibles=new Semaforo(0);
Semaforo espaciosDisponibles=new Semaforo(10);

public Mesa(){
cantidadDulces=0;
}

public void colocarDulce(){


mutex.P();
cantidadDulces=cantidadDulces+1;
mutex.V();
}

public void tomarDulce(){


mutex.P();
cantidadDulces=cantidadDulces-1;
mutex.V();
}
}
public class Mesa{
int cantidadDulces;
Semaforo mutex=new Semaforo(1);
Semaforo dulcesDisponibles=new Semaforo(0);
Semaforo espaciosDisponibles=new Semaforo(10);

public Mesa(){
cantidadDulces=0;
}

public void colocarDulce(){


mutex.P();
cantidadDulces=cantidadDulces+1;
mutex.V();
}

public void tomarDulce(){


mutex.P();
cantidadDulces=cantidadDulces-1;
mutex.V();
}
}
public class Mesa{
int cantidadDulces;
Semaforo mutex=new Semaforo(1);
Semaforo dulcesDisponibles=new Semaforo(0);
Semaforo espaciosDisponibles=new Semaforo(10);

public Mesa(){
cantidadDulces=0;
}

public void colocarDulce(){


mutex.P();
cantidadDulces=cantidadDulces+1;
mutex.V();
}

public void tomarDulce(){


dulcesDisponibles.P();
mutex.P();
cantidadDulces=cantidadDulces-1;
mutex.V();
}
}
public class Mesa{
int cantidadDulces;
Semaforo mutex=new Semaforo(1);
Semaforo dulcesDisponibles=new Semaforo(0);
Semaforo espaciosDisponibles=new Semaforo(10);

public Mesa(){
cantidadDulces=0;
}

public void colocarDulce(){


mutex.P();
cantidadDulces=cantidadDulces+1;
mutex.V();
dulcesDisponibles.V();
}

public void tomarDulce(){


dulcesDisponibles.P();
mutex.P();
cantidadDulces=cantidadDulces-1;
mutex.V();
}
}
public class Mesa{
int cantidadDulces;
Semaforo mutex=new Semaforo(1);
Semaforo dulcesDisponibles=new Semaforo(0);
Semaforo espaciosDisponibles=new Semaforo(10);

public Mesa(){
cantidadDulces=0;
}

public void colocarDulce(){


mutex.P();
cantidadDulces=cantidadDulces+1;
mutex.V();
dulcesDisponibles.V();
}

public void tomarDulce(){


dulcesDisponibles.P();
mutex.P();
cantidadDulces=cantidadDulces-1;
mutex.V();
}
}
public class Mesa{
int cantidadDulces;
Semaforo mutex=new Semaforo(1);
Semaforo dulcesDisponibles=new Semaforo(0);
Semaforo espaciosDisponibles=new Semaforo(10);

public Mesa(){
cantidadDulces=0;
}
public void colocarDulce(){
espaciosDisponibles.P();
mutex.P();
cantidadDulces=cantidadDulces+1;
mutex.V();
dulcesDisponibles.V();
}
public void tomarDulce(){
dulcesDisponibles.P();
mutex.P();
cantidadDulces=cantidadDulces-1;
mutex.V();
}
}
public class Mesa{
int cantidadDulces;
Semaforo mutex=new Semaforo(1);
Semaforo dulcesDisponibles=new Semaforo(0);
Semaforo espaciosDisponibles=new Semaforo(10);

public Mesa(){
cantidadDulces=0;
}
public void colocarDulce(){
espaciosDisponibles.P();
mutex.P();
cantidadDulces=cantidadDulces+1;
mutex.V();
dulcesDisponibles.V();
}
public void tomarDulce(){
dulcesDisponibles.P();
mutex.P();
cantidadDulces=cantidadDulces-1;
mutex.V();
espaciosDisponibles.V();
}
}
public class Mesa{
int cantidadDulces;
Semaforo mutex=new Semaforo(1);
Semaforo dulcesDisponibles=new Semaforo(0);
Semaforo espaciosDisponibles=new Semaforo(10);

public Mesa(){
cantidadDulces=0; Suponga que inicia el programa y
} los recolectores duermen, ¿dónde
public void colocarDulce(){ espera el glotón?
espaciosDisponibles.P();
mutex.P();
cantidadDulces=cantidadDulces+1;
Suponga que los recolectores
mutex.V();
colocan 10 dulces y el glotón
dulcesDisponibles.V(); duerme, si llega otro recolector
} con un dulce más, ¿dónde espera?
public void tomarDulce(){
dulcesDisponibles.P();
mutex.P();
cantidadDulces=cantidadDulces-1;
mutex.V();
espaciosDisponibles.V();
}
}
Sincronización de procesos

Problema de la oficina de correo


colocar() tomar()
cantidadCartas
Administrador Cartero
tomar()
Cartero

tomar()
Cartero

• Se tiene un estante con capacidad


máxima para 50 cartas
• El Administrador siempre coloca 4
cartas, espera si no caben
• Un cartero toma siempre 2 cartas,
espera si no las hay
Sincronización de procesos

Semaforo Administrador (Thread) Cartero (Thread)


int v; Estante estante; Estante estante;
P() int numeroCartero;
run()
V() run()

usa usa usa

Estante Programa
int cantidadCartas; usa
Estante estante;
colocar() Administrador a1;
retirar() Cartero c1,c2,c3;
main()
public class Estante{
int cantidadCartas;

public Estante(){
cantidadCartas=0;
}

public void colocar(){


cantidadCartas=cantidadCartas+4;
}

public void tomar(){


cantidadCartas=cantidadCartas-2;
}
}
Sincronización de procesos

Problema de la oficina de correo


colocar() tomar()
cantidadCartas
Administrador Cartero
tomar()
Cartero

tomar()
Cartero

¿Qué recurso necesita un


cartero para completar
tomar()?
¿Inicialmente cuántos
recursos hay en la mesa?
Sincronización de procesos

Problema de la oficina de correo


colocar() tomar()
cantidadCartas
Administrador Cartero
tomar()
Cartero

tomar()
Cartero

Semaforo cartasDisponibles=new Semaforo(0);

¿Qué recurso necesita un


cartero para completar
tomar()?
¿Inicialmente cuántos
recursos hay en la mesa?
Sincronización de procesos

Problema de la oficina de correo


colocar() tomar()
cantidadCartas
Administrador Cartero
tomar()
Cartero

tomar()
Cartero

¿Qué recurso necesita un


Administrador para
completar colocar()?
¿Inicialmente cuántos
recursos hay en la mesa?
Sincronización de procesos

Problema de la oficina de correo


colocar() tomar()
cantidadCartas
Administrador Cartero
tomar()
Cartero

tomar()
Cartero

Semaforo espaciosDisponibles=new Semaforo(50);

¿Qué recurso necesita un


Administrador para
completar colocar()?
¿Inicialmente cuántos
recursos hay en la mesa?
public class Estante{
int cantidadCartas;
Semaforo cartasDisponibles=new Semaforo(0);
Semaforo espaciosDisponibles=new Semaforo(50);
Semaforo mutex=new Semaforo(0);

public Estante(){
cantidadCartas=0;
}
public void colocar(){
cantidadCartas=cantidadCartas+4;
}
public void tomar(){
cantidadCartas=cantidadCartas-2;
}
}
public class Estante{
int cantidadCartas;
Semaforo cartasDisponibles=new Semaforo(0);
Semaforo espaciosDisponibles=new Semaforo(50);
Semaforo mutex=new Semaforo(0);

public Estante(){
cantidadCartas=0;
}
public void colocar(){
mutex.P();
cantidadCartas=cantidadCartas+4;
mutex.V();
}
public void tomar(){
mutex.P();
cantidadCartas=cantidadCartas-2;
mutex.V();
}
}
public class Estante{
int cantidadCartas;
Semaforo cartasDisponibles=new Semaforo(0);
Semaforo espaciosDisponibles=new Semaforo(50);
Semaforo mutex=new Semaforo(0);

public Estante(){
cantidadCartas=0;
}
public void colocar(){
mutex.P();
cantidadCartas=cantidadCartas+4;
mutex.V();
}
public void tomar(){
mutex.P();
cantidadCartas=cantidadCartas-2;
mutex.V();
}
}
public class Estante{
int cantidadCartas;
Semaforo cartasDisponibles=new Semaforo(0);
Semaforo espaciosDisponibles=new Semaforo(50);
Semaforo mutex=new Semaforo(0);

public Estante(){
cantidadCartas=0;
}
public void colocar(){
mutex.P();
cantidadCartas=cantidadCartas+4;
mutex.V();
}
public void tomar(){
cartasDisponibles.P();
mutex.P();
cantidadCartas=cantidadCartas-2;
mutex.V();
}
}
public class Estante{
int cantidadCartas;
Semaforo cartasDisponibles=new Semaforo(0);
Semaforo espaciosDisponibles=new Semaforo(50);
Semaforo mutex=new Semaforo(0);

public Estante(){
cantidadCartas=0;
}
public void colocar(){
mutex.P();
cantidadCartas=cantidadCartas+4;
mutex.V();
}
public void tomar(){
cartasDisponibles.P();
cartasDisponibles.P();
mutex.P();
cantidadCartas=cantidadCartas-2;
mutex.V();
}
public class Estante{
int cantidadCartas;
Semaforo cartasDisponibles=new Semaforo(0), Semaforo espaciosDisponibles=new Semaforo(50
Semaforo mutex=new Semaforo(0);
public Estante(){
cantidadCartas=0;}
public void colocar(){
mutex.P();
cantidadCartas=cantidadCartas+4;
mutex.V();
cartasDisponibles.V();
cartasDisponibles.V();
cartasDisponibles.V();
cartasDisponibles.V();
}
public void tomar(){
cartasDisponibles.P();
cartasDisponibles.P();
mutex.P();
cantidadCartas=cantidadCartas-2;
mutex.V();
public class Estante{
int cantidadCartas;
Semaforo cartasDisponibles=new Semaforo(0), Semaforo espaciosDisponibles=new Semaforo(50
Semaforo mutex=new Semaforo(0);
public Estante(){
cantidadCartas=0;}
public void colocar(){
mutex.P();
cantidadCartas=cantidadCartas+4;
mutex.V();
cartasDisponibles.V();
cartasDisponibles.V();
cartasDisponibles.V();
cartasDisponibles.V();
}
public void tomar(){
cartasDisponibles.P();
cartasDisponibles.P();
mutex.P();
cantidadCartas=cantidadCartas-2;
mutex.V();
public void colocar(){
espaciosDisponibles.P();
espaciosDisponibles.P();
espaciosDisponibles.P();
espaciosDisponibles.P();
mutex.P();
cantidadCartas=cantidadCartas+4;
mutex.V();
cartasDisponibles.V();
cartasDisponibles.V();
cartasDisponibles.V();
cartasDisponibles.V();
}
public void tomar(){
cartasDisponibles.P();
cartasDisponibles.P();
mutex.P();
cantidadCartas=cantidadCartas-2;
mutex.V();
espaciosDisponibles.V();
espaciosDisponibles.V();
Sincronización de procesos

Problema de los lectores y escritores

Cédula Salario Dirección Teléfono


1152984120 4.000.000 Calle 13 # 339 1745
100 - 00
10066044 5.800.000 Calle 25 # 336 4346
25 A 44

• Se tienen dos tipos de procesos:


- Lectores
- Escritores
Sincronización de procesos

Problema de los lectores y escritores

Escritor Lector

BD
Lector

Lector
Sincronización de procesos

Problema de los lectores y escritores


startRead()

Escritor Lector

BD

endRead()
Sincronización de procesos

Problema de los lectores y escritores

startWrite()

Escritor Lector

BD

endWrite()
Sincronización de procesos

Problema de los lectores y escritores


startRead()

Escritor Lector

BD

endRead()
Sincronización de procesos

Problema de los lectores y escritores

startWrite() startRead()

Escritor Lector

BD
Sincronización de procesos

Problema de los lectores y escritores

startWrite() startRead()
readerCount=2
Escritor Lector

BD

startRead()

Lector
Sincronización de procesos

Problema de los lectores y escritores

startWrite() startRead()
readerCount=1
Escritor Lector

BD
endRead()

startRead()

Lector
Sincronización de procesos

Problema de los lectores y escritores

startWrite()
readerCount=0
Escritor

BD

endRead()
startRead()

Lector
Sincronización de procesos

Problema de los lectores y escritores

startWrite()
readerCount=0
Escritor

BD
Sincronización de procesos

Problema de los lectores y escritores

startWrite()
readerCount=0
Escritor

BD
endWrite()
Sincronización de procesos

Problema de los lectores y escritores

startWrite() startRead()

Escritor Lector

BD

endWrite() endRead()

• Dos hilos lectores pueden estar simultáneamente en BD


• Sin embargo, si un escritor y algún otro hilo (lector o escritor)
están en BD simultáneamente pueden ocurrir inconsistencias en
los datos
Sincronización de procesos

Problema de los lectores y escritores


• Se debe asegurar que los escritores tengan acceso exclusivo a la
base de datos compartida
• Existen varias versiones, se trata la versión en la cual ningún lector
debe esperar a menos que un escritor ya haya obtenido permiso para
usar BD
• Esto indica que si un escritor espera y luego llega un lector, el lector
debe acceder a BD antes que el escritor
• En esta versión los escritores pueden morir de inanición posponiendo
eternamente la escritura debido a que siempre llega por los menos un
lector
Sincronización de procesos

Semaforo Writer (Thread) Reader (Thread)

int valor; Database database; Database database;


int numeroLector;
P() run()
V() run()

usa usa usa

Database Test
int readerCount; usa
Database database;
startRead() Writer e1;
endRead() Reader r1,r2,r3;
startWrite() main()
endWrite()
Sincronización de procesos

Problema de los lectores y escritores

startWrite() startRead()

Escritor Lector

BD

endWrite() endRead()

Es una clase con los métodos:


• startWrite()
• endWrite()
• startRead()
• endRead()
que deben proveer exclusión mutua
public class Database{
int readerCount;

public Database(){
readerCount=0;
}

public void startRead(){


}

public void endRead(){


}

public void startWrite(){


}

public void endWrite(){


}
}
Sincronización de procesos

Problema de los lectores y escritores


startRead()

Lector

endRead()
readerCount BD
Sincronización de procesos

Problema de los lectores y escritores


startRead()
readerCount+1

Lector

readerCount endRead()
BD readerCount-1
Sincronización de procesos

Problema de los lectores y escritores


startRead()
readerCount+1

Lector

readerCount endRead()
BD readerCount-1

startRead()
readerCount+1

Lector
endRead()
readerCount-1
public class Database{
int readerCount;

public Database(){
readerCount=0;
}

public void startRead(){


}

public void endRead(){


}

public void startWrite(){


}

public void endWrite(){


}
}
public void startRead(){
readerCount=readerCount+1;
}
public void endRead(){
readerCount=readerCount-1;
}
public void startRead(){
mutex.P();
readerCount=readerCount+1;
mutex.V();
}
public void endRead(){
mutex.P();
readerCount=readerCount-1;
mutex.V();
}
Sincronización de procesos

Problema de los lectores y escritores


• Problema: falta controlar el acceso de los escritores de tal forma
que solamente puedan escribir cuando la cantidad de lectores sea
cero
Sincronización de procesos

Problema de los lectores y escritores


• Problema: falta controlar el acceso de los escritores de tal forma
que solamente puedan escribir cuando la cantidad de lectores sea
cero

Lector
Escritor BD

• Hay un solo recurso, la BD


• Si un lector hace startRead ()
debe solicitar el recurso
• Esto solo lo hace el primer
lector
Sincronización de procesos

Problema de los lectores y escritores


• Problema: falta controlar el acceso de los escritores de tal forma
que solamente puedan escribir cuando la cantidad de lectores sea
cero

Lector
Escritor BD

semaforoBD:1
Sincronización de procesos

Problema de los lectores y escritores


• Problema: falta controlar el acceso de los escritores de tal forma
que solamente puedan escribir cuando la cantidad de lectores sea
cero
startRead()

Escritor Lector

BD

semaforoBD:1
Sincronización de procesos

Problema de los lectores y escritores


• Problema: falta controlar el acceso de los escritores de tal forma
que solamente puedan escribir cuando la cantidad de lectores sea
cero
startRead()

Escritor Lector
readerCount (1) BD

semaforoBD:0
Sincronización de procesos

Problema de los lectores y escritores


• Problema: falta controlar el acceso de los escritores de tal forma
que solamente puedan escribir cuando la cantidad de lectores sea
cero
startWrite() startRead()

Escritor Lector

BD
El escritor debe
esperar hasta que se
semaforoBD:0
libere el recurso
Sincronización de procesos

Problema de los lectores y escritores


• Problema: falta controlar el acceso de los escritores de tal forma
que solamente puedan escribir cuando la cantidad de lectores sea
cero
startRead()

Escritor Lector
readerCount (1) BD

semaforoBD:0
Sincronización de procesos

Problema de los lectores y escritores


• Problema: falta controlar el acceso de los escritores de tal forma
que solamente puedan escribir cuando la cantidad de lectores sea
cero
startRead()

Escritor Lector
startRead()
readerCount (1) BD
Lector

semaforoBD:0

¿El segundo lector


debe esperar?
Sincronización de procesos

Problema de los lectores y escritores


• Problema: falta controlar el acceso de los escritores de tal forma
que solamente puedan escribir cuando la cantidad de lectores sea
cero
startRead()

Escritor Lector
startRead()
readerCount (2) BD
Lector

semaforoBD:0

El segundo lector no espera,


ya que los “lectores” tiene el
control de la base de datos
Sincronización de procesos

Problema de los lectores y escritores


• Problema: falta controlar el acceso de los escritores de tal forma
que solamente puedan escribir cuando la cantidad de lectores sea
cero
startRead()

Escritor Lector
startRead()
readerCount (2) BD
Lector

semaforoBD:0

¿Cuándo retornan los


“lectores” el control de la
base de datos?
Sincronización de procesos

Problema de los lectores y escritores


• Problema: falta controlar el acceso de los escritores de tal forma
que solamente puedan escribir cuando la cantidad de lectores sea
cero
startRead()

Escritor Lector
endRead()
readerCount (2) BD
startRead() Lector

semaforoBD:0
Sincronización de procesos

Problema de los lectores y escritores


• Problema: falta controlar el acceso de los escritores de tal forma
que solamente puedan escribir cuando la cantidad de lectores sea
cero

Escritor

readerCount (1) BD
startRead() Lector

semaforoBD:0
Sincronización de procesos

Problema de los lectores y escritores


• Problema: falta controlar el acceso de los escritores de tal forma
que solamente puedan escribir cuando la cantidad de lectores sea
cero

Escritor
startRead()
readerCount (1) BD
Lector

semaforoBD:0
endRead()
Sincronización de procesos

Problema de los lectores y escritores


• Problema: falta controlar el acceso de los escritores de tal forma
que solamente puedan escribir cuando la cantidad de lectores sea
cero

Escritor
startRead()
readerCount (0) BD
Lector

semaforoBD:1
endRead()
Sincronización de procesos

Problema de los lectores y escritores


• Problema: falta controlar el acceso de los escritores de tal forma
que solamente puedan escribir cuando la cantidad de lectores sea
cero

Utilizar un semáforo para controlar el acceso a la base de datos, se


hace P() en el semáforo de BD cuando un escritor quiere escribir,
será concedido solamente si el semáforo es 1, esto es, no hay
lectores. Los lectores harán V() para liberar a BD solamente cuando
hayan salido todos, es decir, readerCount es 0. Cuando un lector
ingrese a BD, es decir, haga P() y se le concede, no se retornará V()
sino hasta que salgan todos
• db es un semáforo que controla el acceso a BD
Semaforo db=new Semaforo(1);
• Inicialmente es 1
• Cada vez que se desee escribir se hace P(), también si es el primer lector
• Se hace V() cuando un escritor termina o cuando sale el ultimo de los
lectores

public void startRead(){ public void endRead(){


Solo el primero
mutex.P(); lector solicita la BD mutex.P();
readerCount=readerCount+1; readerCount=readerCount-1;
mutex.V(); mutex.V();
} }
• db es un semáforo que controla el acceso a BD
Semaforo db=new Semaforo(1);
• Inicialmente es 1
• Cada vez que se desee escribir se hace P(), también si es el primer lector
• Se hace V() cuando un escritor termina o cuando sale el ultimo de los
lectores

Cuando se termina de leer,


public void startRead(){ public void endRead(){ se retornaría el control de
BD solamente si fuese el
mutex.P(); mutex.P(); último lector

readerCount=readerCount+1; readerCount=readerCount-1;
if (readerCount==1) mutex.V();
db.P(); }
mutex.V();
}
• db es un semáforo que controla el acceso a BD
Semaforo db=new Semaforo(1);
• Inicialmente es 1
• Cada vez que se desee escribir se hace P(), también si es el primer lector
• Se hace V() cuando un escritor termina o cuando sale el ultimo de los
lectores

Cuando se termina de leer,


public void startRead(){ public void endRead(){ se retornaría el control de
BD solamente si fuese el
mutex.P(); mutex.P(); último lector

readerCount=readerCount+1; readerCount=readerCount-1;
if (readerCount==1) mutex.V();
db.P(); if (readerCount==0)
mutex.V(); db.V();
} }
• db es un semáforo que controla el acceso a BD
Semaforo db=new Semaforo(1);
• Inicialmente es 1
• Cada vez que se desee escribir se hace P(), también si es el primer lector
• Se hace V() cuando un escritor termina o cuando sale el ultimo de los
lectores

Cuando se termina de leer,


public void startRead(){ public void endRead(){ se retornaría el control de
BD solamente si fuese el
mutex.P(); mutex.P(); último lector

readerCount=readerCount+1; readerCount=readerCount-1;
if (readerCount==1) mutex.V();
db.P(); if (readerCount==0)
mutex.V(); db.V();
} }

public void startWrite(){ public void endWrite(){

} }
• db es un semáforo que controla el acceso a BD
Semaforo db=new Semaforo(1);
• Inicialmente es 1
• Cada vez que se desee escribir se hace P(), también si es el primer lector
• Se hace V() cuando un escritor termina o cuando sale el ultimo de los
lectores

Cuando se termina de leer,


public void startRead(){ public void endRead(){ se retornaría el control de
BD solamente si fuese el
mutex.P(); mutex.P(); último lector

readerCount=readerCount+1; readerCount=readerCount-1;
if (readerCount==1) mutex.V();
db.P(); if (readerCount==0)
mutex.V(); db.V();
} }

public void startWrite(){ public void endWrite(){


db.P(); db.V();
} }
Considere la siguiente situación:
Un escritor está en BD, llega un primer lector y espera en db.P(). Si llega otro lector qué ocurre?

Cuando se termina de leer,


public void startRead(){ public void endRead(){ se retornaría el control de
BD solamente si fuese el
mutex.P(); mutex.P(); último lector

readerCount=readerCount+1; readerCount=readerCount-1;
if (readerCount==1) mutex.V();
db.P(); if (readerCount==0)
mutex.V(); db.V();
} }

public void startWrite(){ public void endWrite(){


db.P(); db.V();
} }
Considere la siguiente situación:
Un escritor está en BD, llega un primer lector y espera en db.P(). Si llega otro lector qué ocurre:
• Empieza a leer porque no cumple la condición de readerCount==1 y supone que está leyendo ó,
• ¿Dónde dice que espere?

Cuando se termina de leer,


public void startRead(){ public void endRead(){ se retornaría el control de
BD solamente si fuese el
mutex.P(); mutex.P(); último lector

readerCount=readerCount+1; readerCount=readerCount-1;
if (readerCount==1) mutex.V();
db.P(); if (readerCount==0)
mutex.V(); db.V();
} }

public void startWrite(){ public void endWrite(){


db.P(); db.V();
} }

También podría gustarte