11

Click here to load reader

LabSemaforos

Embed Size (px)

Citation preview

Page 1: LabSemaforos

Concurrencia en UNIX / LINUX

Sincronización de procesos concurrentes

Semáforos UNIX System V y POSIX

Page 2: LabSemaforos

Semáforos UNIX SV• Son más potentes que los formulados por Dijkstra.

– P.ej. Se pude conocer el valor del contador asociado.• ¡No uses nunca esta posibilidad! Si lo haces, te estás engañando

a ti mismo, pues demuestras que no te fías de manejo de los semáforos que haces en tu código.

• Son más complejos de manipular.• Se pueden crear varios semáforos (un array) con

un único identificador– Con una única función se ejecutan primitivas sobre todos

los semáforos con un mismo identificador.– Los semáforos con un mismo identificador se distinguen

entre sí por el índice (posición).

Page 3: LabSemaforos

Gestión de Semáforos• Al igual que la memoria compartida y cualquier otro recurso del Sistema

Informático, los semáforos son gestionados por el S.O..• Se trata de un recurso limitado. Una vez que ya no se necesite, ha de

liberarse.• Conceptualmente, podemos considerar que el S.O. sigue la pista a los

semáforos mediante una tabla, asignando cada semáforo con una fila donde se lo describe

Libre

Libre

Ocupado

Estado Permisosrwxrwxrwx

3

2

1

Otros atributos

Grupo propietario

Usuario propietario

Cola de procesos que esperan

Contadorid

Page 4: LabSemaforos

Uso de los Semáforos UNIX SV• Para operar correctamente, deben incluirse las siguientes cabeceras:

#include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h>

• Las funciones que los piden, inicializan, operan y los liberan son bastante complicadas, y para simplificar su utilización, se han construido las siguientes funciones (disponibles en la página web):Id_sem=inicia (valor): pide un semáforo al S.O.. Si se ha podido asignar

uno, se le inicializa con el valor indicado. Devuelve el identificador (número entero) del semáforo, que será lo que se use a partir de ese momento para referirse a él.

P(id_sem): realiza la función P (esperar) sobre el semáforo cuyo identificador se le pasa como argumento.

V(id_sem): realiza la función V (señalar) sobre el semáforo cuyo identificador se le pasa como argumento.

Borra_s(id_sem): libera el semáforo indicado.

Page 5: LabSemaforos

Semáforos POSIX Binarios• La declaración del semáforo es a través variables

del tipo pthread_mutex_t• Si son declarados como variables externas se

pueden inicializar de forma estática. Por ejemplo:pthread_mutex_tmutex=PTHREAD_MUTEX_INITIALIZER;

• Las funciones que los manipulan son:pthread_mutex_init(·) Inicialización.pthread_mutex_lock(·) Operación P.pthread_mutex_unlock(·) Operación V.pthread_mutex_destroy(·) Libera el semáforo.

Page 6: LabSemaforos

Semáforos POSIX Genéricos• Pueden utilizarse para sincronizar hilos y/o procesos

pesados, aunque sólo trabajaremos aquí con hilos.• Se declaran como variables de tipo sem_t.

• Se manejan con las siguientes funciones:sem_init(sem_t *sem, int pshared, unsigned intvalue);

– Como segundo argumento se pasa un valor indicativo de si el semáforo sincronizará hilos del mismo o diferente proceso. Por defecto se pone un valor 0 a dicho valor ya que sólo serán usados dentro del mismo proceso

sem_wait(sem_t * sem); Función Psem_post(sem_t * sem); Función Vsem_destroy(sem_t * sem);

Page 7: LabSemaforos

Semáforos POSIX - Código• Para trabajar correctamente se deben incluir los

siguientes ficheros de cabecera#include <pthread.h>#include <semaphore.h>

• Para compilar hilos y semáforos POSIX se usa la siguiente línea de comandos– LINUX

gcc programa.c -lpthread– Duero

gcc programa.c -lpthread -lrt

Page 8: LabSemaforos

Comandos SHELL• ps para visualizar los procesos e hilos creados

– IMPORTANTE: algunas versiones de LINUX no permiten visualizar información sobre hilos con el comando ps.

• Visualización de los recursos IPC (inter porcesscomunication) con ipcs– aparece la memoria compartida, los semáforos y las colas de

mensajes (otro recurso de comunicación entre procesos que no hemos visto) que están asignados actualmente.

• Liberar los semáforos que no se han devuelto por un mal funcionamiento de nuestro programa con el comando ipcrm (también ipcclean e ipcfree, dependiendo de la máquina).– Se aplican todos los comentarios hechos sobre la memoria

compartida.

Page 9: LabSemaforos

Creación de Hilos – Hilos del sistema• Crear hilos con pthread_create(&id, NULL, función, args)• Atributos de los hilos.

– La gestión de hilos en POSIX distingue entre la creación de un• Hilo de usuario: los diferentes hilos se asociarán a un único proceso ligero (LWP).• Hilo del sistema: se creará un nuevo LWP y el hilo se asociará a él.

– Para ello utiliza el atributo contentionscope:• PTHREAD_SCOPE_PROCESS: hilo de usuario (hilo no vinculado. • PTHREAD_SCOPE_SYSTEM: hilo de sistema (hilo vinculado). Estos hilos se vinculan en a un

proceso ligero (LWP) y son gestionados por el sistema operativo.• La función pthread_attr_init crea un nuevo atributo para los hilos. Por defecto los

hilos son de usuario.– Para cambiarlo se debe crear una nueva estructura de atributos mediante la función

pthread_attr_init(). – A continuación se obtiene el valor del ámbito por defecto con la función

pthread_attr_getscope() y se cambian con pthread_attr_setscope().– Finalmente se utilizan los nuevos atributos para crear los hilos.

• Crear los hilos con pthread_create(&tid,&atributos,mifuncion,(void *) misargs);

Page 10: LabSemaforos

Hilos del Sistema – Un ejemplo#include <stdio.h>#include <pthread.h>#include <errno.h>main (){pthread_t tid;int misargs[2];int tipohilo;pthread_attr_t atributos;void *mifuncion(void *arg);//Creo mi propia estructura de atributos para luego modificarla if (pthread_attr_init(&atributos) != 0) {

perror("En creación de estructura de atributos.");exit(-1);

}// Compruebo el campo contentionscope con pthread_attr_getscope()if (pthread_attr_getscope(&atributos, &tipohilo) != 0) {

perror("En la obtención de atributos.");exit(-1);

}printf("Atributo de ambito por defecto: %s\n", (tipohilo==PTHREAD_SCOPE_SYSTEM) ? "de núcleo" : "de usuario");// Cambio el ámbito en mis atributosif (pthread_attr_setscope(&atributos, PTHREAD_SCOPE_SYSTEM) != 0) {perror("En el cambio de atributos.");exit(-1);

}if (pthread_attr_getscope(&atributos, &tipohilo) != 0) {

perror("En la obtención de atributos.");exit(-1);

}printf("Nuevo atributo de ambito: %s\n", (tipohilo==PTHREAD_SCOPE_SYSTEM) ? "de núcleo" : "de usuario");// Ahora ya se pueden crear los hilos con el nuevo atributoprintf("Crear hilo...\n");

Page 11: LabSemaforos

Material en el WEB de la asignatura• http://www.infor.uva.es/~isaac/SO/Practicas/semaforos-memoria.html

– Ejemplos listos para compilar• Encontraréis el código de las primitivas para usar los semáforos

UNIX System V.– Prácticas propuestas.– Prácticas para evaluar.