Click here to load reader
Upload
eduardoe-sanchez
View
101
Download
0
Embed Size (px)
Citation preview
Concurrencia en UNIX / LINUX
Sincronización de procesos concurrentes
Semáforos UNIX System V y POSIX
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).
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
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.
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.
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);
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
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.
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);
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");
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.