Comunicación entre procesos IPC Unidad 3.6

34
Comunicación entre procesos Sistemas Operativos I Ing. José Alberto Morales Mancilla

Transcript of Comunicación entre procesos IPC Unidad 3.6

Page 1: Comunicación entre procesos IPC Unidad 3.6

Comunicación entre procesosSistemas Operativos I

Ing. José Alberto Morales Mancilla

Page 2: Comunicación entre procesos IPC Unidad 3.6

Comunicación 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 información entre procesos concurrentes.

Page 3: Comunicación entre procesos IPC Unidad 3.6

Comunicación entre procesos (IPC)

El sistema operativo UNIX define tres clases de herramientas de comunicación entre procesos IPC:

Los semáforos. La memoria compartida. Los mensajes.

Page 4: Comunicación entre procesos IPC Unidad 3.6

Comunicación 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 IPC´s incluyendo su borrado están las funciones shmctl y msgctl.

Page 5: Comunicación entre procesos IPC Unidad 3.6

Comunicación entre procesos

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

Page 6: Comunicación entre procesos IPC Unidad 3.6

Semáforos

¿Qué es un semáforo para UNIX?

Es una variable entera con operaciones atómicas de inicialización, de incremento y decremento con bloqueo.

Page 7: Comunicación entre procesos IPC Unidad 3.6

Semáforos

UNIX define tres operaciones fundamentales sobre semáforos:

semget crea o toma el control de un semáforo. semctl operaciones de lectura y escritura del estado

del semáforo. Destrucción del semáforo. semop operaciones de incremento y decremento

con bloqueo. Operaciones P y V sobre el semáforo.

Page 8: Comunicación entre procesos IPC Unidad 3.6

Semáforos

Como el lenguaje C no tiene ningún tipo “semáforo” predefinido, si se desea utilizar semáforos se tienen que crear mediante una llamada al sistema semget. Esta llamada permite crear un conjunto de semáforos en lugar de uno solo.

Al crear un semáforo se devuelve un número identificador.

Page 9: Comunicación entre procesos IPC Unidad 3.6

Semáforos

La función semget nos permite además abrir un semáforo que ya esté creado. Así por ejemplo si un proceso crea un semáforo, otros procesos pueden sincronizarse con el usando el semáforo con semget.

Para darle un valor inicial al semáforo se utiliza la función semctl.

Page 10: Comunicación entre procesos IPC Unidad 3.6

Semget

Mediante semget vamos a poder crear o acceder a un conjunto de semáforos unidos bajo un identificador común. Semget tiene la siguiente declaración:#include <sys/types.h>

#include<sys/ipc.h>

#include <sys/sem.h>

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

Page 11: Comunicación entre procesos IPC Unidad 3.6

Semget

Si la llamada funciona correctamente, devolverá un identificador con el que podemos acceder a los semáforos en sucesivas llamadas. Si algo falla, semget devolverá el valor -1 y en errno estará el código de error producido.

Page 12: Comunicación entre procesos IPC Unidad 3.6

Semget

Key es la llave que indica a qué grupo de semáforos 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 núcleo para los semáforos.

Page 13: Comunicación entre procesos IPC Unidad 3.6

Semget

Nsems es el total de semáforos que van a estar agrupados por el identificador devuelto por semget.

Semflg es una máscara de bits que indican el modo de adquisición 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.

Page 14: Comunicación entre procesos IPC Unidad 3.6

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 */}

Page 15: Comunicación entre procesos IPC Unidad 3.6

Semáforo

semctl también se utiliza para destruir el semáforo.

UNIX no ofrece las funciones clásicas P y V o equivalentes sino que dispone de una función semop que permite realizar una gama de operaciones incluyendo las P y V.

Page 16: Comunicación entre procesos IPC Unidad 3.6

Llamadas al sistema para semáforos

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.

Page 17: Comunicación entre procesos IPC Unidad 3.6

Apertura o creación de un semáforo.

semget devuelve el identificador del semáforo correspondiente a la clave key. Puede ser un semáforo ya existente o bien semget crea uno nuevo.Sintaxis:

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

Page 18: Comunicación entre procesos IPC Unidad 3.6

Apertura o creación de un semáforo

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.

2. Key no está asociada a ningún semáforo existente y se cumple que (semflg & IPC_CREAT) es cierto.

A un semáforo puede accederse siempre que se tengan los permisos adecuados.

Page 19: Comunicación entre procesos IPC Unidad 3.6

Apertura o creación de un semáforo.

nsems significa cuántos semáforos tiene el conjunto creado.

Los 9 bits inferiores de semflg contienen los permisos estilo UNIX de acceso al semáforo (usuario, grupo, otros).

Page 20: Comunicación entre procesos IPC Unidad 3.6

Apertura o creación de un semáforo

semflg es una máscara que puede contener IPC_CREAT o IPC_EXCL, que hace crear al semáforo, pero fracasando si ya existía.

Ejemplo:

int semid=semget(IPC_PRIVATE,1,IPC_CREAT|0744);

Page 21: Comunicación entre procesos IPC Unidad 3.6

Operaciones de control sobre semáforos

semctl es una función para realizar operaciones sobre semáforos:

int semctl (int semid, int semnum, int cmd..);

semid es un identificador de semáforo devuelto por semget y semnun es el semáforo del conjunto sobre el que se quiere trabajar.

Page 22: Comunicación entre procesos IPC Unidad 3.6

Operaciones de control sobre semáforos.

cmd es la operación aplicada, a continuación puede aparecer un parámetro opcional según la operación definida por cmd.

Las operaciones que nos interesan son:

GETVAL semctl retorna el valor actual del semáforo.

SETVAL se modifica el valor del semáforo (un cuarto parámetro entero da el nuevo valor).

Page 23: Comunicación entre procesos IPC Unidad 3.6

Operaciones de control sobre semáforos

IPC_RMID destruye el semáforo.

Ejemplos:

valor = semctl(semid, semnum, GETVAL);

semctl(semid,semnum, SETVAL, nuevo valor);

Page 24: Comunicación entre procesos IPC Unidad 3.6

Operaciones sobre semáforos.

semop realiza atómicamente un conjunto de operaciones sobre semáforos, pudiendo bloquear al proceso llamador.

int semop(int semid, struct sembuf* sops, unsigned nsops);

semid es el identificador del semáforo y sops es un apuntador a un vector de operaciones, nsops indica el número de operaciones solicitadas.

Page 25: Comunicación entre procesos IPC Unidad 3.6

Operaciones sobre semáforos.

La estructura sembuf tiene estos campos:struct sembuf{

unsigned short sem_num; //número de semáforo dentro del conjunto

short sem_op; //clase de operación según sea <0, >0, ==0

short sem_flg; //modificadores de operación

};

Page 26: Comunicación entre procesos IPC Unidad 3.6

Operaciones P y V. Semop

Sem_num es el número del semáforo y se utiliza como índice para acceder a él. Su valor está en un rango 0..N-1, donde N es el total de semáforos que hay agrupados bajo el identificador.

Page 27: Comunicación entre procesos IPC Unidad 3.6

Operaciones P y V. Semop

Sem_op es la operación a realizar sobre el semáforo especificado en sem_num. Si sem_op es negativo, el valor del semáforo se decrementará, lo que equivale a una operación P. Si sem_op es positivo, el valor del semáforo se incrementará, lo que equivale a una operación V. Si sem_op vale 0, el valor del semáforo no sufre ninguna alteración.

Page 28: Comunicación entre procesos IPC Unidad 3.6

Ejemplo

struct sembuf operación;

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);

operación.sem_num=1; /*cerramos el semaforo */

peración.sem_op=-1;

semop(semid,&operación,1);

operación.sem_num=0;/*abrimos el semaforo*/

Operación.sem_op=1;

Page 29: Comunicación entre procesos IPC Unidad 3.6

Destrucción del semáforo

semctl(semid,0,IPC_RMID,0);

Page 30: Comunicación entre procesos IPC Unidad 3.6

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 operación;

key_t llave;

printf(“Dame el identificador “);

scanf (“%s”,&argv);

printf(“\n %s”, argv);

llave = ftok (argv,’K’);

Page 31: Comunicación entre procesos IPC Unidad 3.6

Creación de semáforos

if (( semid = semget (llave, 2, IPC_CREAT | 0600 )) == -1)

{

perror (“ semget “);

exit (-1);

}

Page 32: Comunicación entre procesos IPC Unidad 3.6

Inicialización de semáforos

/* Cerrar el semáforo del proceso hijo */

semctl ( semid, SEM_HIJO, SET_VAL, 0);

/* abrir el semáforo del proceso padre */

semctl ( semid, SEM_PADRE, SET_VAL, 1);

Page 33: Comunicación entre procesos IPC Unidad 3.6

Creación del proceso hijo

if (( pid = fork()) == -1) {perror (“fork” );exit (-1);

}else if (pid == 0) {

while (i) { operación.sem_num = SEM_HIJO; operación.sem_op = -1; operación.sem_flg = 0; semop (semid, &operación, 1); printf (“proceso hijo %d\n”, i--);/*abrir proceso padre */ operación.sem_num = SEM_PADRE;

operación.sem_op = 1; semop (semid, &operación, 1); } semctl (semid, 0, IPC_RMID,0);

}

Page 34: Comunicación entre procesos IPC Unidad 3.6

Ejecución del proceso padre

else {

while (i) {

operación.sem_num = SEM_PADRE;

operación.sem_op = -1;

semop ( semid, &operación, 1);

printf(“ proceso padre %d\n”, i--);

/* abrir proceso hijo */

operación.sem_num = SEM_HIJO;

operación.sem_op = 1;

semop ( semid, &operación, 1);

}

semctl (semid,0,IPC_RMID,0);

}

}