Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre...

61
1 Tema 10: Sincronización y comunicación Asignatura: Sistemas Informáticos Industriales

Transcript of Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre...

Page 1: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

1

Tema 10: Sincronización y comunicación

Asignatura: Sistemas Informáticos Industriales

Page 2: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Índice

2

1. Concurrencia

2. Problemas de la concurrencia

1. Condiciones de carrera

2. Interbloqueos

3. Modelos clásicos de la comunicación y sincronización

1. Sección crí@ca

2. Modelo productor-consumidor

3. Modelo lectores-escritores

4. Modelo cliente-servidor

4. Mecanismos de sincronización y comunicación

5. Sincronización con semáforos

6. Mutex y variables condicionales

7. Cerrojos sobre ficheros

8. BibliograPa

Page 3: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Concurrencia

11

• Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo).• Real: si hay un proceso por procesador (paralelismo real).

Razones que justifican la concurrencia

• Facilita la programación: ya que permite que las aplicaciones se estructuren como un conjunto de procesos que cooperan entre sí para alcanzar un objetivo común.– Ej.: compilador y ensamblador.

• Acelera los cálculos: Una tarea se podría dividir en procesos para ejecutarla con mayor rapidez, de modo que cada proceso resuelva una parte más pequeña del problema.

• Posibilita el uso interactivo a múltiples usuarios que trabajan de forma simultánea desde varios terminales.

• Mejor aprovechamiento de los recursos, especialmente de la CPU, ya que se pueden aprovechar las fases de E/S de unos procesos para realizar las fases de procesamiento de otros.

Page 4: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Concurrencia

12

• Implícita: la realiza el SO (gestor de recursos)– Procesos independientes– Compiten por recursos (pero lo ignoran)– Control de acceso transparente y asociado al recurso

• Ej. Un proceso usa la memoria asignada por el sistema opera@vo sin preocuparse de la asignada a otros procesos

• Explícita: la realizan los procesos – Procesos cooperantes – Comparten recursos (son conscientes de ello)– Coordinan el acceso al recurso– Usan mecanismos de sincronización y/o comunicación proporcionados por el SO o por el

lenguaje de programación• Ej. Threads y variables en memoria compar@da • Ej. Procesos u@lizan un fichero como base de datos• Ej. Procesos distribuidos colaborando para jugar al mus en red

Coordinación en acceso a recursos compar9dos

Page 5: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Problemas de la concurrencia

13

• Condiciones de carrera

• Interbloqueos

Page 6: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Problemas de la concurrencia

14

Condición de carrera

• Acceso de varios procesos de forma concurrente y sin coordinación a recursos compar9dos

Page 7: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Problemas de la concurrencia

15

• El Sistema Operativo realiza:– Lee el último PID.– Incrementa el valor.– Almacena el nuevo PID.

Registro o posición de memoriaProcesador 1 Procesador 2

PID = 500Lee PID

PID = 500

Condición de carrera

• Acceso de varios procesos de forma concurrente y sin coordinación a recursos compartidos

Ejemplo 1: Asignación del sistema operativo de PIDs

Page 8: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Problemas de la concurrencia

16

• El Sistema Opera7vo realiza:– Lee el úl7mo PID.– Incrementa el valor.– Almacena el nuevo PID.

Registro o posición de memoriaProcesador 1 Procesador 2

PID = 500Lee PID

PID = 500Incrementa y

asigna PID

PID = 501

Lee PIDPID = 500

Condición de carrera

• Acceso de varios procesos de forma concurrente y sin coordinación a recursos compartidos

Ejemplo 1: Asignación del sistema operativo de PIDs

Page 9: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Problemas de la concurrencia

17

• El Sistema Opera7vo realiza:– Lee el úl7mo PID.– Incrementa el valor.– Almacena el nuevo PID.

Registro o posición de memoriaProcesador 1 Procesador 2

PID = 500

PID = 501

Lee PIDPID = 500

Incrementa y asigna PID

PID = 501

Escribe PID

Lee PID

Incrementa y asigna PID

PID = 500

PID = 501

Condición de carrera

• Acceso de varios procesos de forma concurrente y sin coordinación a recursos compar7dos

Ejemplo 1: Asignación del sistema operativo de PIDs

Page 10: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Problemas de la concurrencia

18

• El Sistema Operativo realiza:– Lee el último PID.– Incrementa el valor.– Almacena el nuevo PID.

Registro o posición de memoriaProcesador 1 Procesador 2

PID = 500

PID = 501

PID = 501

Lee PIDPID = 500

Incrementa y asigna PID

PID = 501

Escribe PID

Lee PID

Incrementa y asigna PID

PID = 500

PID = 501

Escribe PID

Condición de carrera

• Acceso de varios procesos de forma concurrente y sin coordinación a recursos compartidos

Ejemplo 1: Asignación del sistema opera9vo de PIDs

Page 11: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Problemas de la concurrencia

19

Threadprincipal

S2 = 51 + … + 100 S1 = 1 + … + 50

Thread 2 (ni=51, nf=100)Thread 1 (ni=1, nf=50)

suma_total = S1 + S2

Ejemplo 2: Suma de n números calculada por dos threads

Condición de carrera

Page 12: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Problemas de la concurrencia

20

int suma_total = 0; // Variable compartida

void suma_parcial(int ni, int nf) {int j = 0;int suma = 0;

for (j = ni; j <= nf; j++)suma = suma + j;

suma_total = suma_total + suma;

pthread_exit(0); }

LD .R1, /suma_totalLD .R2, /sumaADD .R1, .R2ST .R1, /suma_total

Ejemplo 2: Suma de n números calculada por dos threads

Page 13: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Problemas de la concurrencia

21

int suma_total = 0; // Variable compartida

void suma_parcial(int ni, int nf) {int j = 0;int suma = 0;

for (j = ni; j <= nf; j++)suma = suma + j;

suma_total = suma_total + suma;

pthread_exit(0); }

LD .R1, /suma_totalLD .R2, /sumaADD .R1, .R2ST .R1, /suma_total

LD .R1, /suma_totalLD .R2, /sumaADD .R1, .R2ST .R1, /suma_total

.R1 = 0 .R2 = 1275

Thread #1

Ejemplo 2: Suma de n números calculada por dos threads

suma_total = 1275

Page 14: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Problemas de la concurrencia

22

int suma_total = 0; // Variable compartida

void suma_parcial(int ni, int nf) {int j = 0;int suma = 0;

for (j = ni; j <= nf; j++)suma = suma + j;

suma_total = suma_total + suma;

pthread_exit(0); }

LD .R1, /suma_totalLD .R2, /sumaADD .R1, .R2ST .R1, /suma_total

LD .R1, /suma_totalLD .R2, /sumaADD .R1, .R2ST .R1, /suma_total

LD .R1, /suma_totalLD .R2, /sumaADD .R1, .R2ST .R1, /suma_total

.R1 = 0 .R2 = 1275 .R1 = 1275 .R2 = 3775

Thread #1 Thread #2

suma_total = 5050

Ejemplo 2: Suma de n números calculada por dos threads

suma_total = 1275 ¡Correcto!

Page 15: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Problemas de la concurrencia

23

int suma_total = 0; // Variable compartida

void suma_parcial(int ni, int nf) {int j = 0;int suma = 0;

for (j = ni; j <= nf; j++)suma = suma + j;

suma_total = suma_total + suma;

pthread_exit(0); }

LD .R1, /suma_totalLD .R2, /sumaADD .R1, .R2ST .R1, /suma_total

LD .R1, /suma_totalLD .R2, /suma

.R1 = 0 .R2 = 1275

Thread #1

Thread #2

Ejemplo 2: Suma de n números calculada por dos threads

Page 16: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Problemas de la concurrencia

24

int suma_total = 0; // Variable compartida

void suma_parcial(int ni, int nf) {int j = 0;int suma = 0;

for (j = ni; j <= nf; j++)suma = suma + j;

suma_total = suma_total + suma;

pthread_exit(0); }

LD .R1, /suma_totalLD .R2, /sumaADD .R1, .R2ST .R1, /suma_total

LD .R1, /suma_totalLD .R2, /suma

LD .R1, /suma_totalLD .R2, /sumaADD .R1, .R2ST .R1, /suma_total.R1 = 0 .R2 = 1275

.R1 = 0 .R2 = 3775

Thread #1

Thread #2

suma_total = 3775

Ejemplo 2: Suma de n números calculada por dos threads

Page 17: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Problemas de la concurrencia

25

int suma_total = 0; // Variable compartida

void suma_parcial(int ni, int nf) {int j = 0;int suma = 0;

for (j = ni; j <= nf; j++)suma = suma + j;

suma_total = suma_total + suma;

pthread_exit(0); }

LD .R1, /suma_totalLD .R2, /sumaADD .R1, .R2ST .R1, /suma_total

LD .R1, /suma_totalLD .R2, /suma

LD .R1, /suma_totalLD .R2, /sumaADD .R1, .R2ST .R1, /suma_total.R1 = 0 .R2 = 1275

.R1 = 0 .R2 = 3775

ADD .R1, .R2ST .R1, /suma_total

.R1 = 0 .R2 = 1275

Thread #1

Thread #2

suma_total = 3775 suma_total = 1275

Ejemplo 2: Suma de n números calculada por dos threads

Page 18: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Problemas de la concurrencia

26

Condiciones de carrera

• Acceso de varios procesos de forma concurrente y sin coordinación a recursos compartidos

• El resultado final depende del orden de ejecución de las instrucciones

• El código debe ejecutarse en exclusión mutua, de forma atómica, de forma completa e indivisible

• Ningún proceso o thread puede acceder a los recursos compartidos cuando esté ejecutando código que pueda dar lugar a condiciones de carrera

• Los procesos deben sincronizar sus ejecuciones y realizar una ejecución ordenada àOtros procesos deben esperar a ejecutar el código con condiciones de carrera mientras haya otro accediendo al recurso compartido

¿Cómo evitarlo?

Page 19: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Problemas de la concurrencia

27

Interbloqueos

• Bloqueo permanente de un conjunto de procesos que compiten por recursos o que se comunican o sincronizan entre sí

P

Q

BA

Recurso

Proceso

Page 20: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Modelos clásicos de la comunicación y la sincronización

28

• Acceso a la sección crítica• Comunicación de datos:

– El problema del productor-consumidor– El problema de los lectores-escritores– Comunicación cliente-servidor

Modelos de comunicación y sincronización

Mecanismos de los Sistemas Operativos

Page 21: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Sección crí*ca

29

• Código con problemas de carrera de varios procesos vinculados a recursos compartidos

• Mecanismo de sincronización que permita a los procesos cooperar sin problemas. El mecanismo debe proteger la sección crítica.

• Cada proceso solicita permiso para entrar en la sección crítica• Cuando un proceso sale de la sección debe indicarlo para que puedan entrar

otros

Entrada en la sección críticaCódigo de la sección críticaSalida de la sección crítica

Definición

¿Cómo se consigue?

Funcionamiento

Estructura

Page 22: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Sección crí*ca

30

int suma_total = 0; // Variable compartida

void suma_parcial(int ni, int nf) {int j = 0;int suma = 0;

for (j = ni; j <= nf; j++)suma = suma + j;

// Entrada a la sección críticasuma_total = suma_total + suma;// Salida de la sección crítica

pthread_exit(0); }

LD .R1, /suma_totalLD .R2, /sumaADD .R1, .R2ST .R1, /suma_total

Ejemplo 2: Suma de n números calculada por dos threads

Page 23: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Modelo productor-consumidor

31

• Uno o más procesos (productores) generan cierto tipo de datos que son consumidos por otros procesos (consumidores)– Ejemplo: compilador, ensamblador

• Se requiere un mecanismo de comunicación para que productores y consumidores intercambien información

• Sincronizar:– Cuando el mecanismo se llene, el productor se debe bloquear– Cuando el mecanismo este vacío, el consumidor se debe bloquear

• Se requieren servicios para que los procesos puedan comunicarse y servicios para que se sincronicen al acceder al mecanismo de comunicación

Mecanismo de comunicación

ProcesoProductor

ProcesoConsumidor

Flujo de datos

Page 24: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Modelo lectores-escritores

32

• Existe un recurso (archivo, registro, etc.) que va a ser utilizado y compartido por una serie de procesos concurrentes– Algunos procesos acceden sin modificarlo (lectores)– Algunos procesos acceden para modificarlo (escritores)

• Restricciones en estos problemas:– 1 escritor exclusivamente tiene acceso al recurso al mismo tiempo (ni lectores ni escritores

pueden acceder a él)– Múltiples lectores

• Se requieren servicios de sincronización para que lectores y escritores se sincronicen en el acceso al recurso

Recurso

EscritorLector Lector EscritorLector

Page 25: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Modelo cliente-servidor

33

• Los procesos servidores ofrecen una serie de servicios a otros procesos clientes• El sistema operativo debe ofrecer servicios que permitan la comunicación• Servidor local

– Reside en la misma máquina que el cliente– Comunicación basada en memoria compartida o archivos

• Servidor remoto– Reside en distinta máquina– Comunicación a través de una red de interconexión: paso de mensajes

• Mecanismos para que el servidor ejecute las peticiones concurrentes de los diversos clientes de forma coordinada

Procesocliente

Procesoservidor

Computador ComputadorPetición

Respuesta

Page 26: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Mecanismos de sincronización y comunicación

34

• Sincronización: Los procesos deben esperar la ocurrencia de un determinado evento. Servicios para bloquear bajo determinadas circunstancias la ejecución de un proceso– Semáforos– Señales– Tuberías– Mutex y variables condicionales– Cerrojos– Paso de mensajes

• Comunicación: Los procesos pueden intercambiar datos entre ellos– Archivos– Tuberías– Variables en memoria comparIda– Paso de mensajes– Sockets (procesos remotos)

Page 27: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Tuberías

35

• Mecanismo de comunicación y sincronización– Pseudoarchivo mantenido por SO– El proceso ve la tubería como un conducto con dos extremos: uno se utiliza para

escribir datos y el otro para leer– Flujo de datos unidireccional y FIFO– Capacidad de almacenamiento (típico 4 KB)– Implementadas como memoria compartida– Múltiples lectores y escritores– Misma máquina

Page 28: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Tuberías

38

• Sección crítica con tuberías• Las tuberías se utilizan para sincronizar procesos

– Ya que las lecturas y escrituras de una tubería son atómicas y la lectura bloquea a un proceso si la tubería está vacía

• Solución: se crea una tubería en la que se inserta un dato que hace de testigo– Una vez creada la tubería e insertado el testigo en la misma, los

procesos deben proteger el código de la sección crítica:

Leer el dato de la tuberíaCódigo correspondiente a la sección críticaEscribir el dato en la tubería

• Ejemplo #1 en Bitbucket: sección crítica para sumas parciales con threads

Page 29: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Tuberías

39

• Productor-consumidor con tuberías UNIX

Page 30: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Ejercicio: Tuberías

40

• Ejercicio: ls | wc con pipes

Page 31: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Sincronización con semáforos

41

• Objeto con un valor entero, al que se le puede asignar un valor inicial no negativo• Se usa generalmente en sistemas con memoria compartida, en la misma máquina

Definición: semáforo

wait(s){s = s - 1;if (s < 0)Bloquear al proceso;

}

signal(s){s = s + 1;if ( s <= 0)Desbloquear a un proceso bloqueado en la operación wait

}

Operaciones atómicas

El nº de procesos bloqueados en cada instante = |s| si es s negativo

Dijkstra (1965)

Page 32: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Sincronización con semáforos

42

• Se debe proteger el código de la sección crítica de la siguiente forma:

wait (s);Sección críticasignal (s);

Sección crí0ca

Si el valor inicial del semáforo es 1, sólo se permite a un único proceso acceder a la sección críBca

Valor del semáforo (s) P0 P1 P2

1

0

-1

wait(s) wait(s)

Ejecutando código de la sección crítica

Proceso bloqueado en el semáforo

Page 33: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Sincronización con semáforos

43

• Se debe proteger el código de la sección crítica de la siguiente forma:

wait (s);

Sección crítica

signal (s);

Sección crí0ca

Si el valor inicial del semáforo es 1, sólo se permite a un único proceso acceder a la sección críBca

Valor del semáforo (s) P0 P1 P2

1

0

-1

-2

-1

0

1

wait(s) wait(s)

wait(s)

signal(s)

signal(s)

signal(s)

Ejecutando código de la sección crítica

Proceso bloqueado en el semáforo

Page 34: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Sincronización con semáforos

44

• Se utiliza un almacén o buffer circular compartido por ambos procesos– El productor fabrica un dato y lo inserta en un buffer– El consumidor retira del buffer los elementos insertados por el productor

Productor-consumidor

Productor

Consumidor

Page 35: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Sincronización con semáforos

45

• Productor-consumidor con buffer circular y acotado– El buffer se trata como una cola circular– El buffer es de tamaño limitado

• Es necesario evitar que ocurra una de las siguientes situaciones:– El consumidor saque elementos cuando el buffer está vacío– El productor coloque elementos si el buffer está lleno– El productor sobrescriba un elemento que aún no ha sido sacado del buffer– El consumidor saque elementos del buffer que ya fueron extraídos– El consumidor saque un elemento mientras el productor lo está insertando

• Dos tipos de recursos, cada recurso se representa con un semáforo:– Elementos– Huecos

• Cuando un thread necesita un recurso de un cierto tipo, hace una operación wait• Cuando un thread libera el recurso, hace una operación signal• Los valores iniciales de estos dos semáforos coinciden con el número de recursos

disponibles inicialmente (huecos y elementos)

Productor-consumidor

Page 36: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Sincronización con semáforos

46

Productor-consumidor/* tamaño del buffer */#define TAMAÑO_DEL_BUFFER 8

Productor() {int posicion = 0;for(;;) {

Producir un dato;wait(huecos);/* se inserta en el buffer */buffer[posicion] = dato;posicion = (posicion + 1) % TAMAÑO_DEL_BUFFER;signal(elementos);

}}

Consumidor(){int posicion = 0;for(;;) {

wait(elementos);/* se extrae del buffer */dato = buffer[posicion];posicion = (posicion + 1) %

TAMAÑO_DEL_BUFFER;signal(huecos);Consumir el dato extraído;

}}

Page 37: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Sincronización con semáforos

47

Productor-consumidor/* tamaño del buffer */#define TAMAÑO_DEL_BUFFER 8

Productor() {int posicion = 0;for(;;) {

Producir un dato;wait(huecos);/* se inserta en el buffer */buffer[posicion] = dato;posicion = (posicion + 1) % TAMAÑO_DEL_BUFFER;signal(elementos);

}}

Consumidor(){int posicion = 0;for(;;) {

wait(elementos);/* se extrae del buffer */dato = buffer[posicion];posicion = (posicion + 1) %

TAMAÑO_DEL_BUFFER;signal(huecos);Consumir el dato extraído;

}}

elementos = 5huecos = 3

C

P

Page 38: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Sincronización con semáforos

48

Productor-consumidor/* tamaño del buffer */#define TAMAÑO_DEL_BUFFER 8

Productor() {int posicion = 0;for(;;) {

Producir un dato;wait(huecos);/* se inserta en el buffer */buffer[posicion] = dato;posicion = (posicion + 1) % TAMAÑO_DEL_BUFFER;signal(elementos);

}}

Consumidor(){int posicion = 0;for(;;) {

wait(elementos);/* se extrae del buffer */dato = buffer[posicion];posicion = (posicion + 1) %

TAMAÑO_DEL_BUFFER;signal(huecos);Consumir el dato extraído;

}}

elementos = 8huecos = 0

C P

Page 39: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Sincronización con semáforos

49

Productor-consumidor/* tamaño del buffer */#define TAMAÑO_DEL_BUFFER 8

Productor() {int posicion = 0;for(;;) {

Producir un dato;wait(huecos);/* se inserta en el buffer */buffer[posicion] = dato;posicion = (posicion + 1) % TAMAÑO_DEL_BUFFER;signal(elementos);

}}

Consumidor(){int posicion = 0;for(;;) {

wait(elementos);/* se extrae del buffer */dato = buffer[posicion];posicion = (posicion + 1) %

TAMAÑO_DEL_BUFFER;signal(huecos);Consumir el dato extraído;

}}

elementos = 0huecos = 8

C P

Page 40: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Sincronización con semáforos

50

Lectores-escritores

• Hay dos semáforos:– Exclusión mutua en el acceso al recurso compartido

• Valor inicial a 1 para que si un escritor consigue acceder, se evita que ningún otro (lector / escritor) acceda al recurso

– Acceso al contador de lectores• n_lectores representa el número de lectores que están accediendo a la vez al recurso

compartido• A esta variable se accede en exclusión mutua con sem_lectores (valor inicial 1)

• En esta solución los lectores son prioritarios:– Sólo el primer lector debe esperar a que el recurso esté libre– Sólo el último lector debe liberar el recurso

• Hay soluciones que dan prioridad a los escritores

Page 41: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Sincronización con semáforos

51

Lectores-escritores

Lector() {

wait(sem_lectores);n_lectores = n_lectores + 1;if (n_lectores == 1)

wait(sem_recurso);signal(sem_lectores);

< consultar el recurso compartido >

wait(sem_lectores);n_lectores = n_lectores - 1;if (n_lectores == 0)

signal(sem_recurso);signal(sem_lectores);

}

Escritor(){

wait(sem_recurso);/* se puede modificar el recurso */signal(sem_recurso);

}

Page 42: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Sincronización con semáforos

52

POSIX – Semáforos sin nombre

Variable del 6po sem_t. Include: #include <semaphore.h>

Semáforos sin nombre: para threads dentro de un proceso o procesos que lo heredan a través de fork

Creación e inicialización: Deben iniciarse antes de su usoint sem_init (sem_t *sem, int shared, int val);

shared: indica si se puede u6lizar para threads o cualquier otro 6po0: sólo puede u6lizarse entre threads creados dentro del proceso que inicia el semáforoDis6nto de 0: se puede u6lizar para procesos que lo hereden por medio de fork

Cierre y eliminación:int sem_destroy (sem_t *sem)

Wait y signal:int sem_wait (sem_t *sem);int sem_post (sem_t *sem);

Page 43: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Sincronización con semáforos

53

POSIX – Semáforos con nombre

Semáforos con nombre:El nombre sigue la convención de nombrado utilizada para ficherosPoseen nombre, dueño y permisos similares a los de un fichero

Creación e inicialización:sem_t *sem_open (char *name, int flag, mode_t mode, int val);

flag: 0 si se va a usar uno ya creado → no se requieren los 2 últimos params; Si flagtiene O_CREAT: requiere los 2 últimos paramsmode: permisos

sem_t *sem_open(char *name, int flag); // Se abre si existesem_open establece una conexión entre un semáforo con nombre y una variable de tipo semáforo

Cierre y eliminación:int sem_close (sem_t *sem); Cierra la asociación proceso-semáforoint sem_unlink (char *name); Elimina el semáforo cuando todos los procesos lo han cerrado

Wait y signal: Igual que los semáforos sin nombre.

Page 44: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Mutex y variables condicionales

54

• Mutex: se utilizan para obtener acceso exclusivo a recursos compartidos y para asegurar la exclusión sobre secciones críticas

• Dos operaciones atómicas sobre un mutex:– lock: intenta bloquear el mutex

• Si el mutex ya está bloqueado por otro proceso, el proceso se bloquea

• Si el mutex no está bloqueado, el mutex se bloquea sin bloquear al proceso

– unlock: desbloquea el mutex• Si existe procesos bloqueados en él, se desbloqueará a uno de ellos

que será el nuevo proceso que adquiera el mutex• Esta operación la debe ejecutar el proceso ligero que adquirió con

anterioridad el mutex mediante lock (CON POSESIÓN)

Mecanismos para la sincronización de procesos ligeros

Page 45: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Mutex y variables condicionales

55

• Dos acciones atómicas:

mutex_lock(m) {

if (<<no hay llave>>)<<esperar llave>>;

<< abrir, entrar, cerrar y llevármela >}

mutex_unlock(m) {

if (<<alguien espera>>)<<entregar llave>>;

else<< devolver llave a cerradura >>

}

Page 46: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Mutex y variables condicionales

56

lock(m); // Entrada a la sección crítica< sección crítica > unlock(m); // Salida de la sección crítica

La operación unlock() la debe hacer el mismo thread que ejecutó lock()

Sección crí2ca con Mutex

Page 47: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Mutex y variables condicionales

57

Variable de tipo: pthread_mutex_t (#include pthread.h)

Inicialización y destrucción:int pthread_mutex_init (pthread_mutex_t* mutex, pthread_mutexattr_t* attr)

Si attr es NULL → atributos por defecto

int pthread_mutex_destroy (pthread_mutex_t* mutex)

Bloqueo y desbloqueo:int pthread_mutex_lock(pthread_mutex_t* mutex)

int pthread_mutex_unlock(pthread_mutex_t* mutex)

Mutex POSIX

Page 48: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Mutex y variables condicionales

58

Lectores – escritores con Mutex

Lector(){

lock(mutex_lectores);n_lectores++;if(n_lectores==1)

lock(mutex_recurso);unlock(mutex_lectores);

//Consulta recurso comparCdo

lock(mutex_lectores);n_lectores--;if(n_lectores==0)

unlock(mutex_recurso);unlock(mutex_lectores);

}

Escritor(){

lock(mutex_recurso);

//Consulta recurso comparCdo

unlock(mutex_recurso);}

Page 49: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Mutex y variables condicionales

59

Variables condicionales

Variable condicional: variable de sincronización asociada a un mutex que se utiliza para bloquear a un proceso hasta que ocurra algún evento

Se ejecutan entre lock() y unlock()

Dos operaciones atómicas para esperar y señalizar:n c_wait: bloquea al proceso que ejecuta la llamada y le expulsa del mutex

dentro del cual se ejecuta, permitiendo que algún otro proceso adquiera el mutex

Bloqueo del proceso y liberación del mutex de forma atómican c_signal: desbloquea a uno o varios procesos suspendidos en la variable

condicionalEl proceso que se despierta compite de nuevo por el mutex

Page 50: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Mutex y variables condicionales

60

Variables condicionales

Situación 7pica de variables condicionales y mutex conjuntamente:� Conjunto de threads compiten por el acceso a una sección crí?ca (se

protege con un mutex)� Dentro de la sección crí?ca, podría ocurrir que un thread no puede

con?nuar con su ejecución dentro de la misma, porque no se cumple una condición

Por ej.: buffer común lleno / vacío� Entonces, el thread debe:� bloquearse ya que no puede con?nuar� liberar el mutex para que otro thread entre en la sección crí?ca y modifique

la situación que bloqueó al thread

Page 51: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Mutex y variables condicionales

61

Variables condicionales

A veces el thread que está (o posee)la sección crítica no puede continuar, porque "no se da" cierta

condición que sólo podría cambiar otro threaddesde dentro de la sección crítica.

Es preciso pues:Liberar temporalmente el mutex que protege la sección crítica......mientras se espera a que la condición se dé.

Todo ello:Sin abandonar la sección crítica......y de forma atómica.

Permiten liberar un mutex sin salir de la sección crítica

Tres acciones atómicascondition_wait(c,m){

mutex_unlock(m);<<esperar aviso>>;mutex_lock(m);

}

condition_signal(c){

if (<<alguien espera>>)<<avisar que siga>>;

else (<<se pierde>>)}

Page 52: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Mutex y variables condicionales

62

Variables condicionales

A: Mientras no pueda seguir, espero

mutex_lock(mutex);<<sección crítica...>>while (<<no puedo continuar>>)

condition_wait(cond,mutex);<<...sección crítica>>mutex_unlock(mutex);

Fundamental utilizar while

B: Si alguien podría seguir, lo indico

mutex_lock(mutex);<<sección crítica...>>if (<<se podría continuar>>)

condition_signal(cond);<<...sección crítica>>mutex_unlock(mutex);

Page 53: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Mutex y variables condicionales

63

Solución general con variables condicionales

mutex_lock(mutex);while (<<no puedo continuar (condición variables control)>>)

condition_wait(cond, mutex);<<modifica variables de control>>mutex_unlock(mutex);

<<...sección crítica del problema>>mutex_lock(mutex);<<modifica variables de control>>condition_signal(cond);mutex_unlock(mutex);

Page 54: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Mutex y variables condicionales

64

Variables condicionales POSIX

Variable de tipo: pthread_cond_t

Inicialización y destrucción:int pthread_cond_init (pthread_cond_t* cond, pthread_condattr_t* attr)

Si attr es NULL → atributos por defectoint pthread_cond_destroy (pthread_cond_t* cond)

Operación c_wait sobre una variable condicional:int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)

Suspende al proceso ligero hasta que otro ejecute c_signal sobre la variable condicional pasada como primer argumentoDe forma atómica se libera el mutex pasado como argumentoCuando el proceso se despierte competirá de nuevo por el mutex

Operación c_signal sobre una variable condicional:int pthread_cond_signal(pthread_cond_t *cond)

Se desbloquea a un proceso suspendido en la var condicional indicada. Si no hay ningún proceso ligero esperando sobre esa var no tiene efecto

Page 55: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Mutex y variables condicionales

65

Productor-consumidor con mutex y variables condicionales

Productor(){

int pos=0;for(num_datos){

//producir un datolock(mutex);while(num_elem==TAM_BUFFER)

c_wait(lleno,mutex);buffer[pos]=dato;pos=(pos+1)%TAM_BUFFER;num_elem++;if(num_elem==1)

c_signal(vacio);unlock(mutex);

}}

Consumidor(){

int pos=0;for(num_datos){

lock(mutex);while(num_elem==0)

c_wait(vacio,mutex);dato=buffer[pos];pos=(pos+1)%TAM_BUFFER;num_elem--;if(num_elem==TAM_BUFFER-1)

c_signal(lleno);unlock(mutex);

}}

Page 56: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Cerrojos sobre ficheros

66

Servicio del SO que permite coordinar la coutilización de ficheros

• Para procesos independientes• Permite establecer cerrojos sobre regiones

de fichero

Cerrojos de tipo:• Compartido

• No puede solapar con otro exclusivo• Sólo se puede (debe) hacer read de la

región• Exclusivo

• No puede solapar con ningún otro• Se puede hacer read y write

Modalidad:• Consultivo (advisory): sólo afecta los procesos que los usan (preferible)• Obligatorio (mandatory): afectan a procesos que no los usan (¡peligroso!)

Regiones relativas a:principio, posición actual o final de fichero

Page 57: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Cerrojos sobre ficheros

67

Servicio POSIX

int fcntl(int fd, int cmd, struct flock *flockptr);

cmd: F_GETLK (comprueba si existe un cerrojo)F_SETLK (establece cerrojo; no bloqueante, asíncrono)F_SETLKW (establece cerrojo; bloqueante, síncrono)

El cerrojo se establece sobre la región y con la modalidad indicada en:struct flock {

short l_type; /* F_RDLCK (compartido), F_WRLCK (exclusivo), F_UNLCK (elimina) */

short l_whence; /* SEEK_SET, SEEK_CUR, SEEK_END */off_t l_start; /* Desfase relativo a l_whence */off_t l_len; /* Tamaño. 0 == hasta EOF */pid_t l_pid; /* Sólo F_GETLK, primer pid con lock*/

}

Page 58: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Cerrojos sobre ficheros

68

Cerrojos fcntl

• Los cerrojos se asocian al proceso• Si el proceso cierra un descriptor cualquiera del fichero (que puede• tener más de uno) se pierden los cerrojos• Los cerrojos no se heredan• No funcionan en sistemas de ficheros en red, como NFS

Servicio POSIX

Page 59: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Cerrojos sobre ficheros

69

Lectores-Escritores con cerrojo sobre fichero

Page 60: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Resumen del uso más adecuado de los mecanismos de sincronización y comunicación

70

Page 61: Tema 10: Sincronización y comunicación · 2018-12-28 · Concurrencia 11 • Aparente: siempre que hay más de un proceso por procesador (pseudoparalelismo). • Real: si hay un

Bibliografía

71

1. Sistemas Operativos: una visión aplicada. 2ª edición. J. Carretero, F. García, P. De Miguel, F. Pérez. 2007. McGraw-Hill. (ISBN: 84-481-5643-9) Biblioteca UPM.Tema 6: “Comunicación y sincronización de procesos”

2. Problemas de Sistemas Operativos de 2º. 13ª edición. P. De Miguel Anasagasti. Biblioteca UPM.Tema “Comunicación y sincronización”. Problemas 4.1 – 4.25.

3. Modern Operating Systems. 3ª edición. Tanenbaum. (ISBN: 01-360-0663-9). Biblioteca UPM.

Tema 2.3. Interprocess Communication.

4. Vídeo “Introducción a la concurrencia” (en inglés): https://www.youtube.com/watch?v=iKtvNJQoCNw

5. Vídeo “Condiciones de carrera” (en inglés): https://www.youtube.com/watch?v=Nen47rzZMZY

6. Vídeo “Introducción a los semáforos” (en inglés): https://www.youtube.com/watch?v=KZU4ANBoLTY