Você está na página 1de 7

SISTEMAS

OPERATIVOS

TALLER No. 7
SEMAFOROS EN
LINUX

Contenido
El primer mtodo de sincronizacin de procesos, es el llamado semforo. La sincronizacin
de procesos es necesaria en los casos de acceso a un recurso crtico y escaso, para ello el
semforo especifica cuantos procesos puede acceder a dicho recurso en un momento dado.
Objetivo Especifico

1.

Introducir al estudiante el concepto de semforo.


Familiarizarse con las funciones de LINUX/UNIX para manejo de semforos.
Resolver problemas relacionados con la sincronizacin de proceso utilizando
semforos.

Introduccin Terica

Semforos
Los semforos constituyen un proceso de sincronizacin de procesos ms que de
comunicacin de informacin propiamente dicha. Con ellos se pueden resolver problemas de
exclusin mutua, en los que un recurso es compartido por varios procesos.
Un semforo, S, no es otra cosa que una variable que puede tomar valores enteros positivos
(semforo en verde) o cero (semforo en rojo) y que se puede manipular mediante las
operaciones Decremento e Incremento:

Decremento. Si S=0, entonces el proceso que realiza la operacin de


decremento se bloquea y permanece en estado de espera. Si no, se decrementa
una unidad el valor del semforo S (S=S-1).
Incremento. Si existe algn proceso que est bloqueado por causa de una
operacin de decremento sobre 5, entonces uno de ellos despierta y no se
incrementa el valor del semforo. En caso contrario se incrementa en una unidad
el valor del semforo S (S=S+1).

En realidad, tanto el valor del incremento como el del decremento pueden ser superiores a la
unidad.
La forma habitual de utilizar semforos para resolver problemas de seccin critica es como
se indica a continuacin:
Si a una misma seccin critica pueden acceder simultneamente n procesos, se puede
resolver el problema utilizando un semforo con valor inicial igual a n. Entonces, cada
proceso que entre en dicha seccin critica decrementar el valor del semforo una unidad.

TALLER No. 7
SEMAFOROS EN
LINUX

SISTEMAS
OPERATIVOS

Dicho semforo seguir teniendo un valor positivo (semforo en verde) mientras haya
menos de n procesos en la seccin crtica. Cuando intente acceder a ella el proceso n+1,
se encontrar el semforo con valor cero (semforo en rojo). Al salir de la seccin crtica,
un proceso realizar una operacin incremento sobre el semforo, con lo que el proceso
bloqueado entrar en esa seccin crtica y el semforo seguir con valor cero (en rojo)
para otros procesos.
Este mecanismo comunicacin requiere dos condiciones para garantizar que su
funcionamiento sea correcto:
Las operaciones incremento y decremento han de ser atmicas. Esto significa
que el sistema operativo no permite que una operacin incremento o decremento
pueda ser interrumpida por otra operacin incremento o decremento. As se
garantiza que cuando dos procesos compitan por un semforo solamente uno
pueda acceder a modificar su estado.
Debe existir algn mecanismo que permita memorizar las peticiones de
operaciones decremento no satisfechas y despertar a los procesos en
espera. Las llamadas al sistema relacionadas con los semforos son las que se
indican a continuacin:
2.

Llamada al Sistema de Semforos

semget() Crea un semforo o permite el acceso a uno ya existente.


semctl() Realiza operaciones de inicializacin y control de semforos.
semop() Realiza operaciones incremento y decremento sobre un semaforo.
3.

Creacin y acceso a grupos de semforos: semget.

En realidad, el sistema operativo LINUX/UNIX no opera con semforos individuales


sino con grupos que pueden constar de uno o ms semforos.
La llamada a semget permite crear un grupo de semforos o acceder a uno ya existente:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semget(key_t key,int nsems,int semflg);
Cuando funciona correctamente devuelve un identificador que permite el acceso posterior
a los semforos. Si se produce algn tipo de fallo devuelve el entero -1 y deja en errno el
cdigo del error ocurrido.
El parmetro key es de tipo key _t (definido en sys/types.h y equivalente a un entero
largo). Es una clave que el sistema necesita para organizar las estructuras de datos
relacionadas con la comunicacin entre procesos. En funcin de su valor se crea un
grupo nuevo o se accede a uno ya existente:
1. Creacin de un grupo de semforos nuevo: se utiliza la

constante IPC_PRIVATE.
2. Acceso a un grupo de semforos existente: se utiliza la clave de

TALLER No. 7
SEMAFOROS EN
LINUX

SISTEMAS
OPERATIVOS

dicho conjunto. Esta clave puede obtenerse con la orden ipcs desde el
shell del sistema operativo.

El parmetro nsems hace referencia al nmero total de semforos que se agrupan bajo el
identificador que devuelve semget.
El valor semflg es el correspondiente a una mscara de bits que indica el modo de
adquisicin y los permisos que se otorgan para el acceso al grupo de semforos (utilizando
4 cifras). Se pueden combinar el modo de adquisicin y los permisos utilizando la
operacin OR entre bits (1).
IPC_CREAT es el modo de adquisicin que se utiliza cuando se desea crear un
nuevo grupo de semforos. Se puede combinar con los permisos deseados de la
siguiente forma:
IPC_CREAT|0400
Para acceder a un grupo de semforos que ya existe en el sistema, no es
necesario indicar ningn modo de adquisicin especial.
As, para crear 5 semforos con permisos de lectura y escritura nicamente para el
usuario se puede utilizar la siguiente llamada al sistema:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semid;
semid=semget(IPC_PRIVATE,5,IPC_CREAT|0600);
En la variable entera semid queda almacenado el valor del identificador del grupo de
semforos.
4.

Control de semforos: semctl.

La llamada al sistema semctl permite realizar operaciones de control sobre un semforo


concreto de un grupo:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semctl (int semid,int semnum,int cmd,semun arg);
Donde semid es el identificador del grupo de semforos y semnum el nmero de
semforo al que se quiere acceder dentro de los del grupo.
El parmetro cmd especifica la operacin de control de que se trata:
SETVAL. Asignacin de un valor a un semforo. El parmetro arg es el valor que
se desea asignar al semforo en cuestin. De esta manera se puede asignar el
valor 3 al semforo 0 del grupo 4 con la siguiente instruccin:
semcti(4,0,SETVAL,3);
GETVAL. Obtencin del valor de un semforo. En este caso, semctl devuelve un

TALLER No. 7
SEMAFOROS EN
LINUX

SISTEMAS
OPERATIVOS

entero con el valor del semforo. Entonces, el siguiente cdigo permite almacenar
en el entero s el valor del semforo 0 del grupo 4.
int s;
s=semcti(4,0,GETVAL,0);
IPC_RMID. Eliminacin de un grupo de semforos. Si algn proceso est utilizando
uno o ms semforos del grupo especificado, la eliminacin no tendr lugar hasta
que deje de utilizarlos.
Para eliminar el grupo de semforos 4, la llamada al sistema correspondiente es:
semcti(4,0,IPC_RMID,0);
El tipo semun corresponde a una unin de datos y aparece definido en el
archivo de cabecera sem.h de la forma que se indica:
union semun{
int val;
struct semid ds *buffer;
ushort *array;
};
Cuando se produce algn fallo, la llamada a semctl devuelve -1 y deja en errno el
cdigo del error producido.
5.

Operaciones Incremento y Decremento: semop.

La llamada a semop permite realizar sobre un semforo las operaciones incremento


(up) y decremento (down) de manera atmica.
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semop (int semid,struct sembuf *sops,int nsops};
El parmetro semid corresponde a un identificador de un grupo de semforos.
El puntero sops a estructuras de tipo sembuf contiene las acciones que se han de operar
sobre los semforos.
El nmero total de operaciones que se van a realizar se indica en la variable nsops.
La estructura sembuf est definida de la siguiente forma en el archivo de cabecera sem.h:
struct sembuf {
ushort sem_num; /* Nmero del semforo dentro del grupo*/
short sem_op;
/* Operacin */
short sem flg;
/* Mscara de bits */
};

TALLER No. 7
SEMAFOROS EN
LINUX

SISTEMAS
OPERATIVOS

Si sem_op es positivo, el semforo sem_num se incrementa en ese valor. Si es negativo,


se decrernenta. Si es cero, su valor no se modifica.
Cuando se intenta decrementar un semforo de valor O (semforo en rojo) el proceso se
bloquea a la espera de que otro proceso incremente el valor de dicho semforo (semforo
en verde).
Si la llamada no se realiza con xito, la funcin devuelve -1 y deja en errno el cdigo del
error que tuvo lugar.
Ejemplo:

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
. .
int main (int argc,char *argv[]) {
int semid;
struct sembuf operacion;
/* Creacin de un grupo de 2 semforos */
semid=semget(IPC_PRIVATE,2,IPC_CREAT|060);
/* Asignacin de valores a la variable operacin: */
operacion.sem_num=0;
/* Actuar sobre el semforo 0 */
operacion.sem_op=-1;
/* Restar 1 */
operacion.sem_flg=0;
/* Ejecucin de una operacin down sobre el semforo: */
semop(semid,&operacion,1);
}
El cdigo anterior permite efectuar una operacin decremento de 1 unidad (down) sobre el
semforo 0 dentro de los que estn agrupados bajo el identificador servid. Si el semforo
tiene un valor igual a 0, entonces no se decremento y el proceso permanece bloqueado
hasta que otro proceso haga una operacin incremento sobre dicho semforo.

SISTEMAS
OPERATIVOS

TALLER No. 7
SEMAFOROS EN
LINUX

Taller Propuesto :
Ejecute el programa (Sin semforos) cuyo cdigo fuente se entrega. El objetivo es que el
proceso padre muestre en pantalla lneas de diez caracteres '+' y el hijo lneas con diez
caracteres 'o'. Debido a una falta de sincronizacin entre los procesos, ambas salidas se
mezclan. Utilizar semforos para arreglar el problema de forma que el proceso hijo no
entre en la seccin crtica mientras el padre est dentro de la suya y, al revs, el proceso
padre no debe entrar en la seccin crtica mientras el hijo est dentro de la suya. Adems,
las secciones crticas de los procesos padre e hijo deben ejecutarse de manera
alternativa.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main (int argc, char *argv[])
{
int i=0,j,pid;
/* Se crea un proceso hijo */ pid=fork();
/* Se comprueba que no hubo error en fork() */
if (pid == -1) {
perror("fork!");
exit(-1);
}
if (pid==0)
{
/* Proceso HIJO */
while (i<3)
{
/* Comienzo de la seccin critica: */
for (j=0;j<10;j++)
{
write(STDOUT_FILENO,"o",1);
sleep(1);
}
/* Fin de la seccin critica */
i++;
}
}
else
{
/* Proceso PADRE */
while (i<3)
{
/* Comienzo de la seccin critica: */
for (j=0;j<10;j++)
{
write(STDOUT_FILENO,"+",1);
sleep(1);
}
/* Fin de la seccin critica */
i++;
}
}
}

SISTEMAS
OPERATIVOS

TALLER No. 7
SEMAFOROS EN
LINUX

Ejemplo de ejecucin programa sin semforos en LINUX.

Figura 1. Proceso padre y proceso hijo sin semforos.

Ejemplo de ejecucin programa con semforos en LINUX.

Preguntas:
1. Que cambios debo hacer en el programa anterior para el manejo de semforos y
obtener un resultado como la figura No. 2 ?

Bibliografa:

Unix Networking Programming, R. Stevens

Comunicaciones en Unix, Jean Marie Riflet

Ayuda en lnea Sistema Operacional Linux.

http://www.udb.edu.sv/

Você também pode gostar