Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Monitores y Semaforos
Monitores y Semaforos
Semáforos
Índice:
Unidad Temática 8 – Soluciones a nivel del sistema operativo
– Semáforos
– Problemas del uso inadecuado de semáforos
Sincronización de hilos.
Problemas del uso inadecuado de semáforos – Resuelven la exclusión mutua, pero no resuelven el problema de cómo detener
S02 Sistemas operativos II
Los semáforos
Soluciones a nivel del sistema operativo – Constituyen una de las primeras soluciones a la sección crítica a nivel del S.O.
Semáforos – Fueron definidos originalmente por Dijkstra en 1965
Tabla de procesos
i-1 i i+1
Reservar un semáforo S; S.contador = S.contador-1; S.contador= S.contador+1;
contador = -3 S.contador = valor; si S.contador < 0 si S.contador <= 0
... ... entonces
PCB 8 entonces
cola Pasar a suspendido al p=extraer proceso de S.cola;
proceso en ejecución;
Si S.contador Pasar p a preparado
Insertarlo en S.cola;
Estado: SUSP
Evento: Sem-i si no
Semáforo “i” PCB 4 PCB 2
...
P. siguiente Planificador:
Realizar cambio de modo de ejecución (núcleo -> usuario).
selección del próximo
Recuperar contexto de usuario.
proceso
Para resolver el problema de la sección crítica Los semáforos no sólo sirven para resolver el problema de la sección crítica
– Definimos un semáforo compartido, denominado “mutex”, inicializado a 1 Pueden servir para sincronizar procesos en general, por ejemplo:
– Código de los N procesos/hilos: (1) Establecer un cierto orden (precedencia) en la ejecución de zonas de código
de diferentes procesos/hilos
S02 Sistemas operativos II
/* Sección crítica */
void *hilo1(void *p) { void *hilo2(void *p) {
V(mutex);
... ...
/* Sección restante */ Esta solución cumple: F1; P(sinc);
(a) Exclusión mutua V(sinc); F2;
} ... ...
(b) Progreso
} } }
(c) Espera limitada, si la cola
del semáforo es FIFO
Semáforos como mecanismo de sincronización Ejemplos
Ejemplos Ejemplos
Ejemplos Ejemplos
Ejemplo 2: Lectores/Escritores. Solución a la primera variante Ejemplo 2: Lectores/Escritores. Solución a la segunda variante
– Variables compartidas: – Variables compartidas:
semaforo mutex(1), esc(1); semaforo mutex(1), mutex2(1), esc(1), turno(1);
int nlectores = 0; int nlectores = 0, nescritores = 0;
S02 Sistemas operativos II
sem_init(&mutex,0,1);
sem_init(&vacio,0,N);
sem_init(&lleno,0,0);
…
Sincronizació
Sincronización de pthreads.
pthreads. Mutexes Sincronizació
Sincronización de pthreads.
pthreads. Mutexes
donde
donde – Creamos/destruimos los atributos attr con los que luego crearemos el mutex
– Para crear el mutex, tenemos dos opciones: – Esos atributos pueden modificarse mediante funciones específicas.
con los atributos attr (previamente creados con phread_mutexattr_init) P.e. utilizando la función pthread_mutexattr_setpshared podemos modificar el
o con los atributos por defecto (PTHREAD_MUTEX_INITIALIZER) atributo pshared para conseguir que el mutex pueda ser usado por otros procesos
Cierre y apertura de mutexes: Ejemplo: acceso concurrente a una variable por parte de dos hilos
– Código del programa principal:
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
int pthread_mutex_unlock(pthread_mutex_t *mutex);
S02 Sistemas operativos II
Sincronizació
Sincronización de pthreads.
pthreads. Mutexes Indice
Ejemplo:
– Código de los hilos: Soluciones a nivel del sistema operativo
Semáforos
void *hilo1(void *p) { void *hilo2(void *p) {
Problemas del uso inadecuado de semáforos
S02 Sistemas operativos II
Sincronizació
Sincronización de pthreads.
pthreads. Variables de condición Sincronizació
Sincronización de pthreads.
pthreads. Variables de condición
Especificación de las operaciones de acceso: En resumen, POSIX establece que el uso correcto es el siguiente:
– La invocación de espera(c,m) ejecuta una apertura del mutex “m” y – Dentro de una sección crítica, protegida por “mutex”, un cierto hilo (hilo1) comprueba si
se cumple una condición y, en su caso, se suspende en “cond”
suspende al hilo invocante en la variable de condición “c”
El hilo tiene que ser el propietario de “m” antes de invocar esta operación
– Dentro de una sección crítica protegida por el mismo “mutex”, otro hilo (hilo2) despierta
S02 Sistemas operativos II
Sincronizació
Sincronización de pthreads.
pthreads. Variables de condición Sincronizació
Sincronización de pthreads.
pthreads. Variables de condición
donde
donde – Creamos/destruimos los atributos attr con los que luego crearemos la variable
– Para crear la variable cond, tenemos dos opciones: de condición
con los atributos attr (previamente creados con phread_condattr_init) – Esos atributos pueden modificarse mediante funciones específicas.
o con los atributos por defecto (PTHREAD_COND_INITIALIZER) P.e. utilizando la función pthread_condattr_setpshared podemos modificar el
atributo pshared para conseguir que la condición pueda ser usada por otros procesos
Sincronizació
Sincronización de pthreads.
pthreads. Variables de condición Sincronizació
Sincronización de pthreads.
pthreads. Ejemplos
– Programa principal:
– Cuando hay más de un hilo del tipo “Hilo 1”, se recomienda: int main ( ) {
pthread_t prod, cons;
Hilo 1 Hilo 2
...
pthread_mutex_lock(&m); pthread_mutex_lock(&m); pthread_create(&prod, &atributos, func_prod, NULL);
while (! condición) ... pthread_create(&cons, &atributos, func_cons, NULL);
pthread_cond_wait(&c, &m); // Se produce la condición pthread_join(prod,NULL);
// Resto de la S.C. pthread_cond_broadcast(&c); pthread_join(cons,NULL);
pthread_mutex_unlock(&m); pthread_mutex_unlock(&m); }
Sincronizació
Sincronización de pthreads.
pthreads. Ejemplos Sincronizació
Sincronización de pthreads.
pthreads. Ejemplos
void *func_prod(void *p) { void *func_cons(void *p) { void buffer_insertar(int item) { void buffer_extraer(int *item){
int item; int item; pthread_mutex_lock(&mutex); pthread_mutex_lock(&mutex);
S02 Sistemas operativos II
pthread_mutex_unlock(&mutex); pthread_mutex_unlock(&mutex);
} }