INSTITUTO POLITÉCNICO NACIONAL
ESCUELA SUPERIOR DE CÓMPUTO
(ESCOM)
Asignatura: Sistemas Operativos.
Profesor: David Araujo Diaz.
Practica 4
Problemas de sincronización entre procesos/hilos.
Integrantes del equipo:
Buendia Velazco Abel.
No. de lista: 2.
Carpio Becerra Erick Gustavo.
No. de lista: 4.
Domínguez Páez Alejando Yael.
No. de lista: 9.
Portela Nájera Jesús Bambino.
No. de lista: 23.
Velázquez Diaz Luis Francisco.
No. de lista: 36.
Grupo: 4CM3.
Ciclo escolar 2023-B
[TÍTULO DEL DOCUMENTO] [Fecha de publicación]
OBJETIVO
Los integrantes del equipo deberán de implementar y utilizar un mecanismo de
semáforos con el propósito de sincronizar dos o más procesos mediante el uso de
un sistema operativo LINUX/UNIX.
DESCRIPCIÓN
Para iniciar hablaremos un poco sobre los semáforos, los semáforos son una
herramienta de sincronización que ofrece una solución al problema de la sección
crítica (porción de código de un programa de computador en la cual se accede
a un recurso compartido que no debe ser accedido por más de un proceso o
hilo en ejecución). Un semáforo provee una simple pero útil abstracción para
controlar el acceso de múltiples procesos a un recurso común en programación
paralela, o entornos multiusuarios.
Tipos de semáforos
Semáforos binarios: Propuesto por Dijkstra en 1968, da la solución al problema de
la exclusión mutua con la introducción del concepto de semáforo binario. Esta
técnica permite resolver la mayoría de los problemas de sincronización entre
procesos y forma parte del diseño de muchos sistemas operativos y de lenguajes
de programación concurrentes. Un semáforo binario es un indicador de condición
(S) que registra si un recurso está disponible o no. Un semáforo binario sólo puede
tomar dos valores: O y 1. Si, para un semáforo binario. S=1 entonces el recurso
está disponible y la tarea lo puede utilizar; si S=0 el recurso no está disponible y el
proceso debe esperar.
Semáforos con múltiples variables: En este caso el semáforo se inicializa con el
número total de recursos disponibles (n) y las operaciones de WAIT y SIGNAL se
diseñan de modo que se impida el acceso al recurso protegido por el semáforo
cuando el valor de éste es menor o igual que cero. Cada vez que se solicita y obtiene
un recurso, el semáforo se decrementa y se incrementa cuando se libera uno de
ellos. Si la operación de espera se ejecuta cuando el semáforo tiene un valor menor
que uno, el proceso debe quedar en espera de que la ejecución de una operación
señal libere alguno de los recursos.
Al igual que en los semáforos binarios, la ejecución de las operaciones son
indivisibles, esto es, una vez que se ha empezado la ejecución de uno de estos
procedimientos se continuará hasta que la operación se haya completado.
PRACTICA 4 1
[TÍTULO DEL DOCUMENTO] [Fecha de publicación]
Diferencias entre semáforo binario y semáforo de múltiples variables
• La variable de un semáforo binario solo tiene permitido tomar los valores 0
(ocupado) y 1 (libre) en cambio un semáforo con múltiples variables puede
tomar cualquier valor entero, puede variar en un dominio no restringido.
• Semáforos binarios son más fáciles de poner en práctica en comparación con
el semáforo con múltiples variables.
• Semáforo binario permite sólo un hilo para acceder al recurso a la vez, pero
un semáforo con múltiples variables permite n hilos que acceden a la vez.
• Las 2 operaciones que se definen para los semáforos binarios son TAKE y
RELEASE y las 2 operaciones que se definen para los semáforos con
múltiples variables son WAIT y SIGNAL.
• El semáforo binario resulta adecuado cuando hay que proteger un recurso
que pueden compartir varios procesos, pero cuando lo que hay que proteger
es un conjunto de recursos similares, se puede usar un semáforo con
múltiples variables para que lleve la cuenta del número de recursos
disponibles.
• En los semáforos binarios muchos procesos pueden estar en suspensión en
la lista, mientras que en los semáforos con múltiples variables los procesos
avanzan sin demora.
Funciones para gestionar un semáforo
Para hacer entender mejor este punto, lo tomaremos desde un letreo de parking
(estacionamiento), mientras que haya plazas libres, deja entrar a los procesos o
hilos y cuando hay 0 plazas hay que esperar a que otros salgan para poder entrar.
Ahora sí, haremos una explicación sobre las funciones wait y signal.
La función wait comprueba que el valor del semáforo, si es negativo o cero el
proceso se suspende sin consumir recursos hasta que el valor deje de ser negativo.
Si el valor es positivo el proceso o hilo, sigue ejecutándose y se decrementa en una
unidad el valor del semáforo. Siguiendo con la analogía del parking, hacer un wait
es coger el ticket del aparcamiento cuando hay sitio.
La función signal incremental el valor del semáforo, este comportamiento debe
realizarse cuando se ha salido de la zona de exclusión mutua. En nuestro caso sería
similar a entregar el ticket y salir del parking.
PRACTICA 4 2
[TÍTULO DEL DOCUMENTO] [Fecha de publicación]
DESARROLLO DE LA PRACTICA
REALIZACIÓN DE LA PRUEBA DE ESCRITORIO
IMAGEN 1
PROCESO PROCESO
Q P
Listos
S.cola_de_bloqueados IMAGEN 2
PROCESO PROCESO P
Q
Listos
Wait (S)
Cuando un proceso debe
esperar a un semáforo S, se
bloquea y se pone en la cola
del semáforo S.
S.cola_de_bloqueados
PRACTICA 4 3
[TÍTULO DEL DOCUMENTO] [Fecha de publicación]
IMAGEN 3
PROCESO
Q
Listos
Wait (S)
Cuando un proceso debe
esperar a un semáforo S, se
bloquea y se pone en la cola
del semáforo S.
PROCESO
P
S.cola_de_bloqueados
IMAGEN 4
PROCESO Q
Listos
PROCESO
P
S.cola_de_bloqueados
PRACTICA 4 4
[TÍTULO DEL DOCUMENTO] [Fecha de publicación]
IMAGEN 5
PROCESO PROCESO Q
P
Listos Signal (S)
La operación Signal quita
(FIFO) un proceso de la
cola y lo pone en la cola de
procesos listos y puede
pasar a la ejecución.
S.cola_de_bloqueados
CÓDIGO FUENTE
Para la implementación del semáforo en LINUX/UNIX usamos como ejemplo el
proceso que mencionamos en las funciones Signal y Wait que es el
estacionamiento, en este caso usaremos a “padre” e “hijo2 para simular el proceso
y como se había mencionado anteriormente, si en el estacionamiento hay un lugar
disponible, entra el proceso (en este caso padre) y el siguiente proceso (en este
caso hijo) esperaría hasta que el primer proceso termine y de el lugar para la
inicialización del siguiente proceso.
/* Librerias que se usaran para la compilacion correcta
del programa
*/
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/sem.h>
/*
Funciones auxiliares para inicializar, hacer wait y hacer Signal
PRACTICA 4 5
[TÍTULO DEL DOCUMENTO] [Fecha de publicación]
Funcionan con arrays de semaforos, si solo hay uno ese parametro
es 0
*/
//Primero tenemos los prototipos de las funciones
void error(char* errorInfo);
void doSignal(int semid, int numSem); //Funcion wait
void doWait(int semid, int numSem); //Funcion signal
void initSem(int semid, int numSem, int valor);
//Ahora hacemos las definiciones de las funciones
void error(char* errorInfo) {
fprintf(stderr,"%s",errorInfo);
exit(1);
}
void doSignal(int semid, int numSem) {
struct sembuf sops; //Signal
sops.sem_num = numSem;
sops.sem_op = 1;
sops.sem_flg = 0;
if (semop(semid, &sops, 1) == -1) {
perror(NULL);
error("Error al hacer Signal");
}
}
void doWait(int semid, int numSem) {
struct sembuf sops;
sops.sem_num = numSem; // Sobre el primero,
sops.sem_op = -1; // un wait (resto 1)
sops.sem_flg = 0;
if (semop(semid, &sops, 1) == -1) {
perror(NULL);
error("Error al hacer el Wait");
}
}
void initSem(int semid, int numSem, int valor) { //iniciar un
semaforo
if (semctl(semid, numSem, SETVAL, valor) < 0) {
perror(NULL);
error("Error iniciando semaforo");
}
}
PRACTICA 4 6
[TÍTULO DEL DOCUMENTO] [Fecha de publicación]
// Programa principal
int main() {
puts("Sincronizacion con Semaforos ");
int semaforo; //Declaracion de variable
//Creamos un semaforo y damos permisos para compartirlo
if((semaforo=semget(IPC_PRIVATE,1,IPC_CREAT | 0700))<0) {
perror(NULL);
error("Semaforo: semget");
}
initSem(semaforo,0,1);
puts("Hay un lugar disponible");
switch (fork())
{
case -1:
error("Error en el fork");
case 0: // Hijo
doWait(semaforo,0);
puts("Entro el hijo, el padre espera");
sleep(5);
puts("El hijo sale");
doSignal(semaforo,0);
exit(0);
default: // Padre
doWait(semaforo,0);
puts("Entro el padre, el hijo espera");
sleep(5);
puts("El padre sale");
doSignal(semaforo,0);
}
sleep(20);
//Liberacion del semaforo
if ((semctl(semaforo, 0, IPC_RMID)) == -1) {
perror(NULL);
error("Semaforo borrando");
}
return 0;
}
PRACTICA 4 7
[TÍTULO DEL DOCUMENTO] [Fecha de publicación]
PRUEBA DE PANTALLA (CAPTURAS DE PANTALLA)
Al ejecutar el programa, lo primero que hace es validar si hay lugares disponibles
para que se pueda ejecutar el proceso:
Ya que se valido y encontro un lugar disponible, el primer proceso puede entrar a
ejecutarse:
Entra en ejecucion el primer proceso, por lo cual el segundo tendra que esperar a
que termine para que el pueda entrar e inicie su ejecucion:
Una vez que haya salido el primer proceso, puede entrar el segundo a ejecurtarse
sin problemas:
Finalmente, el primer proceso termina su ejecicion y ambos se han ejecutado de
forma exitosa.
PRACTICA 4 8
[TÍTULO DEL DOCUMENTO] [Fecha de publicación]
CONCLUSIONES
En conclusión, los semáforos en Linux son una herramienta fundamental para la
sincronización y la gestión de los procesos en un sistema operativo. Estos
mecanismos se utilizan para evitar problemas de concurrencia en el acceso a
recursos compartidos, permitiendo que los procesos accedan a ellos de manera
segura y ordenada. Los semáforos se basan en el uso de variables compartidas y
su estado es utilizado por los procesos para decidir si pueden o no acceder a un
recurso determinado.
Los semáforos son una parte fundamental del modelo de programación concurrente
y paralela en Linux, y permiten la creación de aplicaciones robustas y escalables.
Es importante tener en cuenta que el uso de semáforos requiere un conocimiento
profundo de los mecanismos de sincronización y la programación en general, ya
que un mal uso de los semáforos puede llevar a problemas de bloqueo o deadlock.
En resumen, los semáforos en Linux son una herramienta poderosa para la gestión
de procesos y recursos compartidos, pero su uso debe ser cuidadoso y responsable
para garantizar la estabilidad y el rendimiento del sistema.
PRACTICA 4 9
[TÍTULO DEL DOCUMENTO] [Fecha de publicación]
REFERENCIAS/BIBLIOGRAFIA
Pozo, D. (2016, septiembre 28). Sistemas Operativos: Semáforos. Ciencia de la
Computación.
[Link]
semaforos/
Semáforos en Linux — Programación concurrente en Linux. (s/f). [Link].
Recuperado el 20 de marzo de 2023, de
[Link]
/Recursos/P04/Semaforos_Linux.html
(S/f). [Link]. Recuperado el 20 de marzo de 2023, de
[Link]
Carceler, V. (s/f). Procesos. Plone site. Recuperado el 20 de marzo de 2023, de
[Link]
Fernandez, M. A. P. (2007, noviembre 8). Sincronización entre procesos.
[Link]. [Link]
comunicacion/sincro-comunicacion
PRACTICA 4 10