1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

58
1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5

Transcript of 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

Page 1: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

1

Concurrencia: Exclusión Mútua y Sincronización

Capítulo 5

Page 2: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

2

Concurrencia

• Concurrencia abarca conceptos tales como– Comunicación entre procesos

– Compartición y competición de recursos compartidos

– Sincronización de actividades de multiples procesos colaborativos

– Asignación de la CPU a los procesos

• Concurrencia no sólo surge en sistemas multiprocesadores o sistemas distribuidos, sino también en sistemas monoprocesadores con multiprogramación

Page 3: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

3

Concurrencia

Page 4: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

4

Principios de concurrencia

• No se puede asumir la velocidad relativa y el orden de ejecución de los procesos, la cual depende de– Las actividades de otros procesos o hebras

– El manejo de interrupciones

– La política de scheduling del SO

• Surgen problemas como – Compartición de recursos globales

– Administración eficiente de recursos. ¿Qué pasaría si el SO asigna un recurso de I/O a un proceso y éste inmediatamente se suspende?

– Difícil encontrar errores de programación. Los errores de sincronización y concurrencia son típicamente poco determinísticos.

Page 5: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

5

Un ejemplo simple

void echo(){

chin = getchar(); // asuma que chin is compartidachout = chin;putchar(chout);

}

Proceso P1 Proceso P2. .chin = getchar(); .. interrupción chin = getchar();chout = chin; chout = chin;putchar(chout); . interrupción. putchar(chout);. .

• Solución: Permitir que sólo un proceso ejecute la función a la vez

Page 6: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

6

Condición de carrera (race condition)

• Una condición de carrera ocurre cuando varios procesos o hebras leen y escriben datos compartidos y el resultado final depende del orden en que se ejecuten las instrucciones

• Ejemplo: Inicialmente, b=1, c=2, variables compartidas

P1 P2

b = b + c c = b + c

Page 7: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

7

Interacción entre Procesos

• Procesos no tienen conocimiento de la existencia de otros procesos – Aunque los procesos no trabajen colaborativamente, el SO debe administrar la competencia por recursos del sistema

• Procesos conocen indirectamente la existencia de otros – Saben que los recursos que accesan son compartidos con otros procesos

• Procesos que directamente conocen la existencia de otros procesos– Conocen el pid de los otros procesos

– Se comunican explícitamente

– Cooperan en alguna tarea

Page 8: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

8

Page 9: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

9

Cocurrencia en competencia de recursos

• Dos o más procesos necesitan accesar un (o más) recurso durante sus ejecuciones.

• Los procesos no saben de la existencia de otros procesos y sus operaciones no deben ser afectadas por la ejecución de otros procesos.

• Entonces, los procesos no deben afectar el estado de los recursos.

• Problemas potenciales de control– Exclusion mútua - sectiones críticas

• Sólo un programa a la vez puede ejecutar su sección crítica

– Deadlock (abrazo mortal)• P1 solicita y obtiene recurso R1; P2 solicita y obtiene R2. Luego P1 solicita R2, y P2 solicita R1

– Starvation (inhanición) • Es posible que un proceso esperando por un recurso (bloqueado) nunca lo obtenga

Page 10: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

10

Concurrencia en compartición

• Ejemplo: Múltiples procesos acceden variables compartidas

• Datos compartidos pueden ser leídos o escritos, y las operaciones de escritura debieran ser exclusivas

• Otro problema coherencia de datos

• Ejemplo: suponga que necesitamos mantener a=b

P1 P2

a = a+1 b = 2*b

b = b+1 a = 2*a

Page 11: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

11

Concurrencia en cooperación mediante comunicación

• Varios procesos trabajan en conjunto para resolver alguna tarea

• Los procesos se comunican explícitamente, por ejemplo mediante el envío de mensajes

• Si toda la comunicación está basada en paso de mensajes, no existe problema de exclusión mútua.

• Sin embargo, puede existir deadlock e inhanición

Page 12: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

12

Exclusión mútua

• Una visión abstracta de la implementación de EM sería

P1 P2 void P1() void P2(){ { while (true) { while (true) { código antes de la SC código antes de la SC entercritical(Ra); entercritical(Ra); SC; SC; exitcritical(Ra); exitcritical(Ra); código después de la SC código después de la SC } }} }

Page 13: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

13

Requirimientos para exclusión mútua

• Sólo un proceso puede estar ejecutando su SC

• Un proceso que no se encuentra en su SC no debe interferir con otros procesos que deseen ingresar a la SC

• No se permite que un proceso que desea entrar en su SC espere indefinidamente: No deadlock o inhanición

• Cuando ningún proceso está en su SC, la solicitud de cualquier proceso para ingresar a su SC no debe ser denegada

• No se puede asumir nada respecto de la velocidad relativa y orden en la ejecución de los procesos

• Un proceso permanece en su SC por un tiempo finito

Page 14: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

14

Exclusión mútua:solución por hardware

• Deshabilitación de Interrupciones– Recordar que un proceso se ejecuta hasta que invoca un llamado al SO o es

interrumpido– Entoces para garantizar EM, el proceso deshabilita las interrupciones justo antes

de entrar en su SC while (true)

{ deshabilitar_interrupciones(); SC habilitar_interrupciones(); }

– Problema 1: habilidad del procesador para hacer context-switch queda limitada– Problema 2: no sirve para multiprocesadores

Page 15: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

15

EM: solución por hardware

• Instrucciones especiales de máquina – 2 acciones se llevan a cabo en forma atómica, como leer y escribir o leer y probar sobre

una dirección simple de memoria

– Acceso es bloqueado para cualquier otra instrucción

• Test and Set Instruction

boolean testset (int i) {

if (i == 0) {

i = 1;

return true;

}

else {

return false;

}

}

Page 16: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

16

EM: solución por hardware

• Instrucción Exchange (swap)

void exchange(int register, int memory) {

int temp;

temp = memory;

memory = register;

register = temp;

}

Page 17: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

17

EM: ejemplo

• parbegin(P(1), P(2),…,P(n)) suspende la ejecución del programa principal e inicia la ejecución concurrente de n procesos con el mismo código, pero diferente parámetro i

• Sólo aquel que encuentra bolt=0 entra. Los otros permanecen en busy-waiting o spin-waiting

Page 18: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

18

EM por instrucciones de máquina

• Ventajas– Aplicable a cualquier número de procesos y procesadores que comparten

memoria física

– Simple y fácil de verificar

– Puede ser usada con varias SC, cada una controlada por su propia variable

• Desventajas– Busy-waiting consume tiempo de procesador

– Es posible inhanición

– Es posible deadlock si existe prioridades entre los procesos: Suponga dos procesos P1 y P2, con P1 prioridad más baja que P2. Si P1 está en su SC y luego es interrumpido para que P2 entre al procesador, ¿Qué pasaría?

Page 19: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

19

Soluciones por Software

• Dos procesos, P0 y P1 comparten la variable global turn la cual indica cuál de los procesos puede ingresar a la seción crítica

• Inicialmente turn = 0

• Garantiza exclusión mútua• Problemas

– Alternación estricta de ejecución. – ¿Qué pasaría se P0 falla?– No existe inanición

while (true) { while (turn != 0); sc(); turn = 1; otro_codigo… }

while (true) { while (turn != 1); sc(); turn = 0; otro_codigo… }

P0 P1

Page 20: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

20

Segundo intento

• El problema con la solución anterior es que almacenamos el nombre del proceso que puede entrar a la SC

• Una nueva posible solución es almacenar el nombre del procesos que está en su SC

• Boolean flag[2]

• Incialmente flag[0] = flag[1] = false

• Si el uno de los procesos falla fuera de su SC, el otro no se bloquea indefinidamente, pero si se bloque dentro de su SC, si.

• Esta solución no satisface el requerimiento de exclusión mútua!!!

while (true) { while (flag[1]); flag[0] = true; sc(); flag[0] = false; otro_codigo… }

while (true) { while (flag[0]); flag[1] = true; sc(); flag[1] = false; otro_codigo… }

Page 21: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

21

Tercer intento

• El problema más evidente de la solución anterior es que un proceso puede cambiar su estado después que el otro proceso la ha “consultado”, pero antes que el otro haya entrado a su SC

• flag[0] = flag[1] = False

• El requerimiento de exclusión mútua es satisfecho, pero…

• Se puede producir deadlock ¿por qué?

while (true) { flag[0] = true; while (flag[1]); sc(); flag[0] = false; otro_codigo… }

while (true) { flag[1] = true; while (flag[0]); sc(); flag[1] = false; otro_codigo… }

Page 22: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

22

Cuarta solución

• Considere la siguiente secuencia– P0 pone flag[0] en true– P1 pone flag[1] en true– P0 chequea flag[1]– P1 chequea flag[0]– P0 pone flag[0] en false– P1 pone flag[1] en false– P0 pone flag[0] en true– P1 pone flag[1] en true

while (true) { flag[0] = true; while (flag[1]){ flag[0] = false; flag[0] = true; } sc(); flag[0] = false; otro_código… }

while (true) { flag[1] = true; while (flag[0]){ flag[1] = false; flag[1] = true; } sc(); flag[1] = false; otro_codigo… }

Livelock

Page 23: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

23

Una solución correcta (algoritmo de Peterson)

• En este algoritmo usamos dos variables globales:– Turn que indica cual proceso podria entrar a la SC y

– flag[] que indica el desea de entrar a la SC

– Inicialmente flag[0] = flag[1] = false

• Esta solución garantiza exclusión mútua

• No produce deadlock

while (true) { flag[0] = true; turn = 1; while (flag[1] && turn == 1); sc(); flag[0] = false; otro_codigo… }

while (true) { flag[1] = true; turn = 0; while (flag[0] && turn == 0); sc(); flag[1] = false; otro_codigo… }

Page 24: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

24

Semáforos

• Una semáforo es una variable especial usada para que dos o más procesos se señalicen mutuamente

• Un semáforo es una variable entera – Inicializada con un número no negativo

– Sólo dos operaciones acceden al semáforo

– semWait(s) decrementa el semáforo; si el valor resultante es negativo, el proceso se bloquea; sino, continúa su ejecución

– semSignal(s) incrementa el semáforo; si el valor resultante es menor o igual que zero, entonces se despierta un proceso que fue bloqueado por semWait()

Page 25: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

25

Primitivas sobre semáforos

Page 26: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

26

Semáforo binario

• semWait(s) { if (s.value == 1) s.value = 0; else { place this process in s.queue block this process } }

• semSignal(s) { if (s.queue is empty()) s.value = 1 else { remove a process P from s.queue; place P on the ready list; }

• un semáforo binario puede ser inicializado en 0 ó 1

• también son conocidos como mutex

Page 27: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

27

Exclusión mútua usando semáforos binarios

Page 28: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

28

Page 29: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

29

Políticas de encolamiento definequién, entre aquellos que estánesperando, pasa a ejecutarse.

semáforo fuerteGarantiza libre de inhaniciónEj: FIFO

Semáforo débilNo garantiza libre de inhaniciónEj: Prioridad

Page 30: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

30

El problema del Productor/Consumidor

• Uno o más productores generan datos y lo colocan en un buffer (compartido)

• Un consumidor toma (consume) los datos del buffer uno a la vez

• Sólo un agente (productor o consumidor) accesa el buffer a la vez

Page 31: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

31

Caso buffer infinito

producer:

while (true) {

/* produce item v */

b[in] = v;

in++;

}

consumer:

while (true) {

while (in <= out)

/*do nothing */;

w = b[out];

out++;

/* consume item w */

}

Page 32: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

32

Caso buffer circular o finito

producer:

while (true) {

/* produce item v */

while ((in + 1) % n == out)

/* do nothing */;

b[in] = v;

in = (in + 1) % n

}

consumer:

while (true) {

while (in == out)

/* do nothing */;

w = b[out];

out = (out + 1) % n;

/* consume item w */

}

Page 33: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

33

Page 34: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

34

•Semáforo binario s es usado para asegurar exclusión mútua

•Semáforo delay se usa para hacer que el consumidor espere si el buffer está vacio

• Variable n = in-out

Solución incorrecta

Page 35: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

35

Solución correcta

Page 36: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

36

Solución caso buffer infinito con semáforo contador

Page 37: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

37

Solución caso buffer finitocon semáforo contador

Semáforo e usado paracontar el número de espaciosvacíos

BloquearseProductor desea insertar en buffer llenoConsumidor desea sacar de buffer vacío

DesbloquearseConsumidor: item insertadoProductor: item sacado

Page 38: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

38

Implementación de semáforos con testset()

• semWait(s) {

while (!testset(s.flag)) ;

s.count--;

if (s.count < 0) {

place this process in s.queue

block this process and set s.flag to 0

} else (NOOOOO)

s.flag = 0;

• semSignal(s) {

while (!testset(s.flag));

s.count++;

if (s.count <= 0) {

remove a process P from s.queue;

place P on ready list;

}

s.flag = 0;

El SO debe garantizar que la operaciones sobre semáforosse realicen en forma atómica

En este caso la deshabilitación de interrupciones sería una opción válida

Page 39: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

39

El problema de los filósofos comensales

• Cinco filósofos se sientan alrededor de una mesa con una fuente de spaghetti.

• Cuando un filósofo no está comiendo, está filosofando.• Como carecen de habilidades manuales, necesitan de dos tenedores para

comer, pero sólo hay cinco.• Cuando uno o dos de los tenedores están siendo ocupados por el filósofo de

al lado, el filósofo vuelve a filosofar.• Cuando un filósofo deja de comer spaghetti, coloca los tenedores sobre la

mesa.

Page 40: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

40

Solución 1

• Esta solución no está libre de deadlock

Semaphore fork[5] = {1}void philosopher(int i) { while (true) { think(); semWait(fork[i]); semWait(fork[(i+1)mod 5]); eat(); semSignal(fork[(i+1] mod 5); semSignal(fork[i]); }}

main(){ parbegin(philosopher(0),philosopher(1), philosopher(2),philosopher(3), philosopher(4));

}

Page 41: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

41

Solución 2• Una posible solución al problema de deadlock es controlar que sólo 4

tenedores puedan ser usados

Semaphore fork[5] = {1}Semaphore room = 4;void philosopher(int i) { while (true) { think(); semWait(room); semWait(fork[i]); semWait(fork[(i+1)mod 5]); eat(); semSignal(fork[(i+1] mod 5); semSignal(fork[i]); semSignal(room); }}

main(){ parbegin(philosopher(0),philosopher(1), philosopher(2),philosopher(3), philosopher(4));

}

Page 42: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

42

El problema de los lectores/escritores

• Uno o más lectores pueden estar simultáneamente leyendo un archivo

• Pero sólo un escritor puede estar escribiendo el archivo

• Si un escritor está escribiendo el archivo, ningún lector puede estar leyendo el archivo

• Ej: sistema de biblioteca

• Note que: se garantiza que los lectores sólo leen

• Si lectores y escritores leyeran y escribieran, volveriamos al problema general de exclusión mútua

Page 43: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

43

Lectores tienenPrioridad

Escritores puede entrar en inanición

Page 44: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

44

Escritores tienen prioridad,

Escritores tienen prioridad, es decir una vez que un escritor declara su deseo de entrar, no se permite que ningún nuevo lector entre

Page 45: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

45

Problema típico con semáforos

• ¿Qué pasaría si el programador se equivoca usando las funciones semWait() y semSignal() en el consumidor?

n = 0s = 1void consumer(){ while (true) { semSignal(s); semWait(s); take(); senWait(n); }}

void producer(){ while (true) { produce(); semWait(s); append(); semSignal(s) senWait(n); }}

Page 46: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

46

Monitores

• Un monitor es un módulo de software que evita errores de programación

• Carácterísticas principales:– Variables locales son accesadas sólo dentro del monitor; es decir por la

funciones del monitor

– Para ingresar al monitor, un proceso invoca algunas de las funciones del monitor

– Sólo un proceso puede estar ejecutándose en el monitor => exclusión mútua

• Los monitores necesitan usar variables de condición:– Suponga que un proceso dentro del monitor necesita suspenderse hasta que una

condición se haga verdadera

– Las variables de condición proveen el mecanismo de sincronización para suspender un proceso dentro del monitor y reanudar su ejecución en otro momento

Page 47: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

47

Variables de condición

• cwait(c): suspende la ejecución del proceso llamador en la variable de condición c. El monitor queda libre para ser usado por otro proceso

• csignal(c): resume la ejecución de algún proceso bloqueado por un cwait() sobre la misma variable c. Si hay varios procesos bloqueados, elegir cualquiera; si no hay ninguno bloqueado, no hacer nada

• Note que las funciones cwait() y csignal() se parecen a semWait() y semSignal(), PERO NO son iguales y cumplen una función distinta

Page 48: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

48

Page 49: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

49

Solución al problema productor/consumidor con monitor

notfull v.c. para dormir el productor cuando buffer está llenonotempty v.c. para dormir al consumidor cuando el buffer está vacío

Page 50: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

50

Solución (continuación)

Page 51: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

51

Solución al problema de los filósofos con monitores

Monitor dinning_philosophersstate[5] of {THINKING, HUNGRY, EATING};Cond self[5];

void get_forks(int i) { state[i] = HUNGRY; test(i); if (state[i] != EATING then cwait(self[i]);}void put_forks(int i) { state[i] = THINKING; test((i+4) mod 5); test((i+1) mod 5);}void test(int i) { if (state[i+4 mod 5] != EATING && state[i] == HUNGRY && state[i+1 mod 5] != EATING) { state[i] = EATING; csignal(self[i]); }}

Void philosopher(int i){ while (true) { think(); get_forks(i); eat(); put_forks(i); }}

void main() { state[0] = state[1] =… THINKING parbegin(philosopher(0),... )}

Page 52: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

52

Paso de Mensajes

• Los mecanismos de sincronización que hemos visto hasta ahora están basados en variables compartidas (globales), es decir la comunicación es implícita

• El paso de mensajes es un mecanismo de sincronización donde la comunicación es explícita.

• Paso de mensajes significa que un proceso envía información a otro proceso con el cual no comparten memoria

• Dos primitivas básicas

send (destination, message)

receive (source, message)

Page 53: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

53

Sincronización

• El paso de mensajes implica necesariamente un nivel básico de sincronización: el receptor de la información no puede recibirla antes que el enviador la envíe.

• Blocking send, blocking receive– Tanto el enviador como el receptor se bloquean hasta que el mensaje llegue al

receptor

• Nonblocking send, blocking receive– El enviador continúa su ejecución después de enviarla

– El receptor se bloquea hasta que llegue

• Nonblocking send, nonblocking receive– Ninguno se bloquea

Page 54: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

54

Direccionamiento

• Direccionamiento directo– La primitiva send() incluye el identificador del proceso destino

– La primitiva receive() podría (o no) saber quien le envía el mensaje y tomaria la información del mensaje fuente

– Asi, podría enviar una confirmación de recepción del mesaje

• Direccionamiento indirecto– Los mensajes no se envia de un proceso a otro, sino a una estructura de datos

compartida consistente de colas que almacenan temporalmente mensajes

– Mailboxes

– Asi, un proceso deposita un mensaje en el mailbox y otro lo recupera

– Permite tener más modelos de comuniucación, como se presenta a continuación

Page 55: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

55

Page 56: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

56

Formato de mensaje

Page 57: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

57

Exclusión mútua con paso de mensajes• Asumimos blocking receive() y nonbloquing send()

• Se crea un “mailbox” mutex

• Para entrar a la SC, un proceso debe recibir un mensaje

• Cuando sale de la SC pone devuelta el mensaje en el mailbox

• Asumimos si dos o más procesos hacen un receive() al mismo tiempo, sólo uno de ellos lo recibe

Page 58: 1 Concurrencia: Exclusión Mútua y Sincronización Capítulo 5.

58

Solución al problema del productor/consumidor