Publicado el 9 de Julio del 2019
505 visualizaciones desde el 9 de Julio del 2019
217,5 KB
38 paginas
SISTEMAS OPERATIVOS:
COMUNICACIÓN Y
SINCRONIZACIÓN ENTRE
PROCESOS
Hilos y mecanismos de comunicación y sincronización
Contenido
2
¨ Comunicación y sincronización.
¨ Semáforos.
¨ El problema de los lectores escritores.
¤ Solución con semáforos.
¨ Mutex y variables condición.
Sistemas Operativos.- Hilos y Sincronización
Mecanismos de comunicación
3
¨ Los mecanismos de comunicación permiten la
transferencia de información entre dos procesos.
¨ Archivos
¨ Tuberías (pipes, FIFOS)
¨ Variables en memoria compartida
¨ Paso de mensajes
Sistemas Operativos.- Hilos y Sincronización
Mecanismos de sincronización
4
¨ Los mecanismos de sincronización permiten forzar a un
proceso a detener su ejecución hasta que ocurra un evento
en otro proceso.
¨ Construcciones de los lenguajes concurrentes (procesos
ligeros)
¨ Servicios del sistema operativo:
¤ Señales (asincronismo)
¤ Tuberías (pipes, FIFOS)
¤ Semáforos
¤ Mutex y variables condicionales
¤ Paso de mensajes
¨ Las operaciones de sincronización deben ser atómicas
Sistemas Operativos.- Hilos y Sincronización
Semáforos POSIX
¨ Mecanismo de sincronización para procesos y/o
5
threads en la misma máquina
¨ Semáforos POSIX de dos tipos:
¤ Semáforos con nombre: puede ser usado por distintos
procesos que conozcan el nombre. No requiere memoria
compartida.
¤ Semáforos sin nombre: pueden ser usados solo por el
procesos que los crea (y sus threads) o por procesos que
tengan una zona de memoria compartida.
#include <semaphore.h>
sem_t *semaforo; //nombrados
sem_t semaforo; // no nombrado
Sistemas Operativos.- Hilos y Sincronización
Semáforos POSIX
6
¤ Inicializa un semáforo sin nombre
¨ int sem_init(sem_t *sem, int shared, int val);
¨ int sem_destroy(sem_t *sem);
¨ sem_t *sem_open(char *name, int flag, mode_t mode,
¤ Cierra un semáforo con nombre.
¤ Destruye un semáforo sin nombre
int val);
¤ Abre (crea) un semáforo con nombre.
¨ int sem_close(sem_t *sem);
¨ int sem_unlink(char *name);
¨ int sem_wait(sem_t *sem);
¤ int sem_trywait (sem_t *sem)
¨ int sem_post(sem_t *sem);
¤ Borra un semáforo con nombre.
¤ Realiza la operación wait sobre un semáforo.
¤ Intenta hacer wait, pero si está bloqueado vuelve sin hacer nada y da -1
¤ Realiza la operación signal sobre un semáforo.
Sistemas Operativos.- Hilos y Sincronización
Secciones críticas con semáforos
7
sem_wait(s); /* entrada en la seccion critica */
< seccion critica >
sem_post (s); /* salida de la seccion critica */
¨ El semáforo debe tener valor inicial 1 o superior
Valor del
semáforo (s)
P0
P1
P2
1
0
-1
-2
-1
0
1
wait(s)
wait(s)
wait(s)
desbloquea
signal(s)
desbloquea
signal(s)
Sistemas Operativos.- Hilos y Sincronización
signal(s)
Ejecutando código de la sección crítica
Proceso bloqueado en el semáforo
Operaciones sobre semáforos
8
sem_wait(s) {
s = s - 1;
if (s <= 0) {
<Bloquear al proceso>
}
}
sem_post(s) {
s = s + 1;
if (s > 0)
}
}
<Desbloquear a un proceso bloqueado por la
operacion wait>
Sistemas Operativos.- Hilos y Sincronización
Semáforos sin nombre.
Ejemplo: Productor-consumidor.
#define MAX_BUFFER 1024 /* tamanio del buffer */
#define DATOS_A_PRODUCIR 100000 /* datos a producir */
9
sem_t elementos;
sem_t huecos;
int buffer[MAX_BUFFER];
/* elementos en el buffer */
/* huecos en el buffer */
/* buffer comun */
void main(void)
{
pthread_t th1, th2; /* identificadores de threads */
/* inicializar los semaforos */
sem_init(&elementos, 0, 0);
sem_init(&huecos, 0, MAX_BUFFER);
Productor
Sistemas Operativos.- Hilos y Sincronización
Consumidor
Productor-consumidor con semáforos
10
/* crear los procesos ligeros */
pthread_create(&th1, NULL, Productor, NULL);
pthread_create(&th2, NULL, Consumidor, NULL);
/* esperar su finalizacion */
pthread_join(th1, NULL);
pthread_join(th2, NULL);
sem_destroy(&huecos);
sem_destroy(&elementos);
exit(0);
}
Sistemas Operativos.- Hilos y Sincronización
11
Semáforos sin nombre.
Productor-consumidor: Hilo productor
void Productor(void) /* codigo del productor */
{
int pos = 0; /* posicion dentro del buffer */
int dato; /* dato a producir */
int i;
for(i=0; i < DATOS_A_PRODUCIR; i++ ) {
dato = i; /* producir dato */
sem_wait(&huecos); /* un hueco menos */
buffer[pos] = i;
pos = (pos + 1) % MAX_BUFFER;
sem_post(&elementos); /* un elemento mas */
}
pthread_exit(0);
}
Sistemas Operativos.- Hilos y Sincronización
12
Semáforos sin nombre.
Productor-consumidor: Hilo consumidor
void Consumidor(void) /* codigo del Consumidor */
{
int pos = 0;
int dato;
int i;
for(i=0; i < DATOS_A_PRODUCIR; i++ ) {
sem_wait(&elementos); /* un elemento menos */
dato = buffer[pos];
pos = (pos + 1) % MAX_BUFFER;
sem_post(&huecos); /* un hueco mas */
/* cosumir dato */
}
pthread_exit(0);
Sistemas Operativos.- Hilos y Sincronización
}
Problema de los lectores-escritores
13
¨ Problema que se plantea cuando se
tiene un área de almacenamiento
compartida.
¤ Múltiples procesos leen información.
¤ Múltiples procesos escriben información.
¨ Condiciones:
¤ Cualquier número de lectores pueden leer
de la zona de datos concurrentemente.
¤ Solamente un escritor puede modificar la
información a la vez.
¤ Durante una escritura ningún lector puede
realizar una consulta.
Sistemas Operativos.- Hilos y Sincronización
Lector
Lector
Escritor
Lector
Escritor
Recurso
Diferencias con otros problemas
14
¨ Exclusión mutua:
¤ En el caso de la exclusión mutua solamente se
permitiría a un proceso acceder a la información.
¤ No se permitiría concurrencia entre lectores.
¨ Productor consumidor:
¤ En el productor/consumidor los dos procesos modifican
la zona de datos compartida.
¨ Objetivos de restricciones adicionales:
¤ Proporcionar una solución más eficiente.
Sistemas Operativos.- Hilos y Sincronización
Alternativas de gestión
15
¨ Los lectores tienen prioridad.
¤ Si hay algún lector en la sección crítica otros lectores
pueden entrar.
¤ Un escritor solamente puede entrar en la sección crítica
si no hay ningún proceso.
¤ Problema: Inanición para escritores.
¨ Los escritores tienen prioridad.
¤ Cuando un escritor desea acceder a la sección crítica
no se admite la entrada de nuevos lectores.
Sistemas Operativos.- Hilos y Sincronización
Los lectores tienen prioridad
16
int nlect; semaforo lec=1; semaforo = escr=1;
Lector
for(;;) {
semWait(lec);
nlect++;
if (nlect==1)
semWait(escr);
semSignal(lec);
realizar_lect();
semWait(lec);
nlect--;
if (nlect==0)
semSignal(escr);
semSignal(lec);
}
Escritor
for(;;) {
semWait(escr);
realizar_escr();
semSignal(escr);
}
Sistemas Operativos.- Hilos y Sincronización
Semáforos sin nombre.
Lectores-escritores con semáforos
17
int dato = 5; /* recurso */
int n_lectores = 0; /* num lectores
*/
sem_t sem_lec; /* control el
acceso n_lectores */
sem_t mutex; /* controlar el
acceso a dato */
void main(void) {
pthread_create(&th3, NULL,
Lector, NULL);
pthread_create(&th4, NULL,
Escritor, NULL);
pthread_join(th1, NULL);
pthread_join(th2, NULL);
pthread_join(th3, NULL);
pthread_join(th4, NULL);
/* cerrar todos los semaforos
*/
sem_destroy(&mutex);
sem_destroy(&sem_lec);
exit(0);
}
pthread_t th1, th2, th3, th4
sem_init(&mutex, 0, 1);
sem_init(&sem_lec, 0, 1);
pthread_create(&th1, NULL, Lector,
NULL);
pthread_create(&th2, NULL,
Escritor, NULL);
Sistemas Operativos.- Hilos y Sincronización
Semáforos sin nombre.
Lectores-escritores:Hilo lector y escritor
18
void Lector(void) { /* codigo del lector
void Escritor(void) { /*
codigo del escritor */
sem_wait(&mutex);
dato = dato + 2; /*
modificar el recurso */
sem_post(&mutex);
pthread_exit(0);
}
*/
sem_wait(&sem_lec);
n_lectores = n_lectores + 1;
if (n_lectores == 1)
sem_wait(&mutex);
sem_post(&sem_lec);
printf(``%d\n'', dato); /* leer dato
*/
sem_wait(&sem_lec);
n_lectores = n_lectores - 1;
if (n_lectores == 0) sem_post(&mutex);
sem_post(&sem_lec);
pthread_exit(0);
}
Sistemas Operativos.- Hilos y Sincronización
Semáforos con nombre
Nombrado
19
¨ Permiten sincronizar procesos distintos sin usar
memoria compartida.
¨ El nombre de un semáforo es una cadena de caracteres (con las
mismas restricciones de un nombre de fichero).
¤ Si el nombre (ruta) es relativa, solo puede acceder al semáforo el proceso que lo
crea y sus hijos.
¤ Si el nombre es absoluto (comienza por “/”) el semáforo puede ser compartido
por cualquier proceso que sepa su nombre y tenga permisos.
¨ Mecanismo habitual para crear semáforos que
comparten padres e hijos
¤ Los “sin nombre” no valen -> los procesos NO comparten memoria.
Sistemas Operativos.- Hilos y Sincronización
Semáforos con nombre
Creación y uso
20
¨ Para crearlo:
sem_t *sem_open(char *name, int flag, mode_t mode,int val);
¤ Flag = O_CREAT lo crea.
¤ Flag: O_CREAT | O_EXECL. Lo crea si no existe. -1 en caso de que exista.
¤ Mode: permisos de acceso;
¤ Val: valor incial del semáforo (>=0);
¨ Para usarlo:
sem_t *sem_open(char *name, int flag);
¤ Con flag 0. Si no existe devuelve -1.
¨ Importante:
¤ Todos los procesos deben conocer “name” y usar el mismo.
Sistemas Operativos.- Hilos y Sincronización
Semáforos con nombre:
Lectores - Escritores
21
int dato = 5; /* recurso */
int n_lectores = 0; /* num lectores */
sem_t *sem_lec; sem_t *mutex;
/* Crea los procesos */
for (i = 1; i< atoi(argv[1]); ++i){
pid = fork();
if (pid ==-1)
{ perror("No se puede crear el proceso");
exit(-1);}
else if(pid==0) { /child
lector(getpid()); break;
}
escritor(pid); /* parent */
}
sem_close(mutex); sem_close(sem_lec);
sem_unlink("/tmp/sem_1");
sem_unlink("/tmp/sem_2");
int main (int argc, char *argv[]) {
int i, n= 5; pid_t pid;
/* Crea el semáforo nombrado */
if((mutex=sem_open("/tmp/sem_1", O_CREAT, 0644,
1))==(sem_t *)-1)
{ perror("No se puede crear el semaforo"); exit(1); }
if((sem_lec=sem_op
Comentarios de: Hilos y mecanismos de comunicación y sincronización (0)
No hay comentarios