You are on page 1of 34

Semforos

Comunicacin entre procesos


Sistemas Operativos
M.C. Jos Alberto Morales Mancilla

Comunicacin entre procesos (IPC)


Los procesos en UNIX no comparten memoria, ni siquiera los padres con los hijos. Por tanto hay que establecer un mecanismo, en caso de que se quiera comunicar informacin entre procesos concurrentes.

Comunicacin entre procesos (IPC)


El sistema operativo UNIX define tres clases de herramientas de comunicacin entre procesos IPC: Los semforos. La memoria compartida. Los mensajes.

Comunicacin entre procesos (IPC)


Existen funciones shmget y msgget para crear o enlazarse a un segmento de memoria compartida o a una cola de mensajes respectivamente. Para alterar las propiedades de estos IPCs incluyendo su borrado estn las funciones shmctl y msgctl.

Comunicacin entre procesos


Para enviar o recibir mensajes, se utilizan las funciones msgsnd y msgcrv.

Semforos
Qu es un semforo para UNIX?

Es una variable entera con operaciones atmicas de inicializacin, de incremento y decremento con bloqueo.

Semforos
UNIX define tres operaciones fundamentales sobre semforos: semget crea o toma el control de un semforo. semctl operaciones de lectura y escritura del estado del semforo. Destruccin del semforo. semop operaciones de incremento y decremento con bloqueo. Operaciones P y V sobre el semforo.

Semforos Como el lenguaje C no tiene ningn tipo semforo predefinido, si se desea utilizar semforos se tienen que crear mediante una llamada al sistema semget. Esta llamada permite crear un conjunto de semforos en lugar de uno solo. Al crear un semforo se devuelve un nmero identificador.

Semforos
La funcin semget nos permite adems abrir un semforo que ya est creado. As por ejemplo si un proceso crea un semforo, otros procesos pueden sincronizarse con el usando el semforo con semget.

Para darle un valor inicial al semforo se utiliza la funcin semctl.

Semget
Mediante semget vamos a poder crear o acceder a un conjunto de semforos unidos bajo un identificador comn. Semget tiene la siguiente declaracin:
#include <sys/types.h> #include<sys/ipc.h> #include <sys/sem.h> int semget(key_t, int nsems, int semflg);

Semget
Si la llamada funciona correctamente, devolver un identificador con el que podemos acceder a los semforos en sucesivas llamadas. Si algo falla, semget devolver el valor -1 y en errno estar el cdigo de error producido.

Semget
Key es la llave que indica a qu grupo de semforos queremos acceder. Esta llave puede crearse mediante una llamada a ftok. Si key toma el valor IPC_PRIVATE, la llamada crea un nuevo identificador sujeto a la disponibilidad de entradas libres en la tabla que gestiona el ncleo para los semforos.

Semget
Nsems es el total de semforos que van a estar agrupados por el identificador devuelto por semget. Semflg es una mscara de bits que indican el modo de adquisicin del identificador. Si el bit IPC_CREAT est activo, la facilidad IPC se crear en el supuesto de que otro proceso no la haya creado ya.

Ejemplo
int llave, semid; If ((llave = ftok (auxiliar,K)) == (key_t)-1) { /* Error al crear la llave */ } if (( semid = semget (llave, 4, IPC_CREAT | 0600)) == -1) { /* Error al crear el identificador */ }

Semforo
semctl tambin se utiliza para destruir el semforo.

UNIX no ofrece las funciones clsicas P y V o equivalentes sino que dispone de una funcin semop que permite realizar una gama de operaciones incluyendo las P y V.

Llamadas al sistema para semforos Para el uso correcto de todas las funciones, se debe incluir el archivo de cabecera <sys/sem.h> Las tres funciones devuelven -1 si algo ha salido mal y en tal caso la variable errno informa el tipo de error.

Apertura o creacin de un semforo. semget devuelve el identificador del semforo correspondiente a la clave key. Puede ser un semforo ya existente o bien semget crea uno nuevo. Sintaxis:

int semget (key_t key, int nsems, int semflg);

Apertura o creacin de un semforo


1. key vale IPC_PRIVATE. Este valor obliga a semget a crear un nuevo y nico identificador, nunca devuelto por llamadas anteriores a semget hasta que sea liberado con semctl. Key no est asociada a ningn semforo existente y se cumple que (semflg & IPC_CREAT) es cierto. A un semforo puede accederse siempre que se tengan los permisos adecuados.

2.

Apertura o creacin de un semforo.


nsems significa cuntos semforos tiene el conjunto creado. Los 9 bits inferiores de semflg contienen los permisos estilo UNIX de acceso al semforo (usuario, grupo, otros).

Apertura o creacin de un semforo semflg es una mscara que puede contener IPC_CREAT o IPC_EXCL, que hace crear al semforo, pero fracasando si ya exista. Ejemplo:
int semid=semget(IPC_PRIVATE,1,IPC_CREAT|0744);

Operaciones de control sobre semforos semctl es una funcin para realizar operaciones sobre semforos: int semctl (int semid, int semnum, int cmd..); semid es un identificador de semforo devuelto por semget y semnun es el semforo del conjunto sobre el que se quiere trabajar.

Operaciones de control sobre semforos.


cmd es la operacin aplicada, a continuacin puede aparecer un parmetro opcional segn la operacin definida por cmd. Las operaciones que nos interesan son: GETVAL semctl retorna el valor actual del semforo. SETVAL se modifica el valor del semforo (un cuarto parmetro entero da el nuevo valor).

Operaciones de control sobre semforos

IPC_RMID destruye el semforo.

Ejemplos: valor = semctl(semid, semnum, GETVAL); semctl(semid,semnum, SETVAL, nuevo valor);

Operaciones sobre semforos.


semop realiza atmicamente un conjunto de operaciones sobre semforos, pudiendo bloquear al proceso llamador.
int semop(int semid, struct sembuf* sops, unsigned nsops); semid es el identificador del semforo y sops es un apuntador a un vector de operaciones, nsops indica el nmero de operaciones solicitadas.

Operaciones sobre semforos. La estructura sembuf tiene estos campos:


struct sembuf{ unsigned short sem_num; //nmero de semforo dentro del conjunto short sem_op; //clase de operacin segn sea <0, >0, ==0 short sem_flg; //modificadores de operacin };

Operaciones P y V. Semop
Sem_num es el nmero del semforo y se utiliza como ndice para acceder a l. Su valor est en un rango 0..N-1, donde N es el total de semforos que hay agrupados bajo el identificador.

Operaciones P y V. Semop
Sem_op es la operacin a realizar sobre el semforo especificado en sem_num. Si sem_op es negativo, el valor del semforo se decrementar, lo que equivale a una operacin P. Si sem_op es positivo, el valor del semforo se incrementar, lo que equivale a una operacin V. Si sem_op vale 0, el valor del semforo no sufre ninguna alteracin.

Ejemplo
struct sembuf operacin; int semid; semid=semget(IPC_PRIVATE,3,IPC_CREAT|0600); semctl(semid,0,SETVAL,1); semctl(semid,1,SETVAL,0); semctl(semid,2,SETVAL,0); operacin.sem_num=1; /*cerramos el semaforo */ operacin.sem_op=-1; //operacin P semop(semid,&operacin,1); operacin.sem_num=0;/*abrimos el semaforo*/ operacin.sem_op=1;

Destruccin del semforo

semctl(semid,0,IPC_RMID,0);

Ejemplo
#include <stdio.h #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #define SEM_HIJO 0 #define SEM_PADRE 1 void main(void) { int i=30, semid, pid; char argv[10]; struct sembuf operacin; key_t llave; printf(Dame el identificador ); scanf (%s,&argv); printf(\n %s, argv); llave = ftok (argv,K);

Creacin de semforos

if (( semid = semget (llave, 2, IPC_CREAT | 0600 )) == -1) { perror ( semget ); exit (-1); }

Inicializacin de semforos
/* Cerrar el semforo del proceso hijo */ semctl ( semid, SEM_HIJO, SET_VAL, 0); /* abrir el semforo del proceso padre */ semctl ( semid, SEM_PADRE, SET_VAL, 1);

Creacin del proceso hijo


if (( pid = fork()) == -1) { perror (fork ); exit (-1); } else if (pid == 0) { while (i) { operacin.sem_num = SEM_HIJO; operacin.sem_op = -1; operacin.sem_flg = 0; semop (semid, &operacin, 1); printf (proceso hijo %d\n, i--); /*abrir proceso padre */ operacin.sem_num = SEM_PADRE; operacin.sem_op = 1; semop (semid, &operacin, 1); } semctl (semid, 0, IPC_RMID,0); }

Ejecucin del proceso padre


else { while (i) { operacin.sem_num = SEM_PADRE; operacin.sem_op = -1; semop ( semid, &operacin, 1); printf( proceso padre %d\n, i--); /* abrir proceso hijo */ operacin.sem_num = SEM_HIJO; operacin.sem_op = 1; semop ( semid, &operacin, 1); } semctl (semid,0,IPC_RMID,0); } }

You might also like