Actualizado el 21 de Marzo del 2018 (Publicado el 23 de Febrero del 2018)
697 visualizaciones desde el 23 de Febrero del 2018
234,6 KB
31 paginas
Creado hace 18a (19/12/2006)
Tema 6 : IPC del Unix
System V
Sistemas Operativos:
Programación de Sistemas
Oscar Déniz Suárez
Alexis Quesada Arencibia
Francisco J. Santana Pérez
Curso 2006-07
Introducción
El paquete de comunicación entre procesos
(IPC) del UNIX System V se compone de tres
mecanismos:
Semáforos, para sincronizar procesos
Memoria compartida, para compartir el espacio de
direcciones virtuales de los procesos
Colas de mensaje, para intercambiar datos con un
formato determinado entre procesos
Las estructuras IPC están en el núcleo, como
los pipes, y no en el sistema de archivos, como
las FIFO
Formación de claves
Cada IPC posee un identificador único
Al crear un IPC es necesario especificar
una clave de tipo key_t, que el núcleo
usa para generar el identificador del IPC
(key_t es un entero)
Diferentes llamadas a la función de
creación de un IPC con la misma clave
devuelven el mismo identificador, lo que
permite compartir un IPC entre procesos
Formación de claves
¿ cómo asegurar que todos los procesos que
quieran usar la misma estructura IPC utilicen la
misma clave ?
En caso de procesos creados con fork => comparten
el identificador. Además si el proceso hijo realiza un
exec, se puede pasar el identificador mediante un
parámetro al exec
Un proceso crea el IPC y guarda la clave en un
fichero accesible a los otros procesos
Poner la clave en un archivo cabecera (.h) común.
Apoyarse en la función de la biblioteca de C ftok
Formación de claves
Creación de una clave mediante ftok
#include <types.h>
#include <sys/ipc.h>
key_t ftok (char *path, char id);
ftok devuelve una clave basada en
path y en id
IPC desde el shell
Ordenes ipcs e ipcrm
Ipcs => mostrar información (-q, -m, -s)
lpcrm => eliminar mecanismos IPC (-q, -m, -s)
Desventajas del IPC del Unix
System V
Tiene una interfaz de programación compleja
No se mantiene contador del número de
procesos que está usando una estructura
Por lo tanto, no hay un método automático para
reclamar estructuras IPC abandonadas
Si un proceso crea y usa una estructura y
termina sin eliminarla apropiadamente, la
estructura permanece hasta que:
Se reinicie el sistema
Se elimina específicamente con el comando
Otro proceso la elimina
ipcrm
Semáforos
Mecanismo de sincronización
Dijkstra, 1965
atómicas
Tipo abstracto de datos que admite dos
operaciones:
• P (espera o wait)
• V (señal o signal)
Importante: las operaciones P y V son
Semáforos
Creación de un semáforo: llamada semget
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semget (key_t key, int nsems, int semflg);
donde:
Key es la clave que identifica al grupo de semáforos
Nsems es el número de semáforos a crear
Semflg es una máscara de bits (IPC_CREAT,
IPC_EXCL, permisos)
Ejemplo:
int semid=semget(IPC_PRIVATE, 1, IPC_CREATE | 0600)
Semáforos
La llamada semctl nos da acceso a la
información administrativa y de control que
dispone el núcleo de un semáforo
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semctl (int semid, int semnum, int cmd, union semun
arg);
semnum es el nº del semáforo del conjunto en
con que se quiere operar (entre 0 y nsems-1)
cmd indica la operación a realizar. Según el
valor de cmd arg contendrá otras opciones
Semáforos
Las operaciones más interesantes son:
GETVAL, retorna el valor actual del semáforo
SETVAL, modifica el valor del semáforo (un
cuarto parámetro entero especifica el nuevo
valor)
IPC_RMID, destruye el semáforo
Semáforos
La llamada semop nos permite realizar
nsops es el número de elementos del array sops
operaciones atómicas sobre el conjunto de
semáforos
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semop (int semid, struct sembuf *sops, int nsops);
donde:
semid identifica al grupo de semáforos sobre los que se
sops es un puntero a un array de estructuras que
va a realizar la operación
indican las operaciones que se lrealizarán sobre los
semáforos
Semáforos
Las operaciones se especifican mediante una
estructura de tipo sembuf
struct sembuf{
ushort sem_num; /* número del semáforo*/
short sem_op; /*operación (inc. o dec.)*/
short sem_flg; /*máscara de bits*/
}
semop >0 => incremento y desbloqueo
semop <0 => bloqueo y/o decremento según sem_flg (IPC_WAIT,
IPC_NOWAIT, SEM_UNDO)
semop =0 => el proceso se bloquea hasta que el semáforo sea 0 (a menos
que se especifique IPC_NOWAIT en sem_flg)
Semáforos
Ejercicio práctico:
Vamos a crear un proceso padre y un proceso hijo
que escriban por pantalla un cierto número de veces
N que pasamos como argumento mediante la línea
de órdenes “Soy el proceso Padre con PID XXX” y
“Soy el proceso Hijo con PID YYY” respectivamente.
Con independencia del proceso que escriba primero,
siempre deben visualizarse en pantalla todos los
mensajes de cada proceso sin que estos se
entremezclen.
Memoria compartida
La forma más rápida de comunicar dos procesos es
La memoria convencional que puede direccionar un
El proceso que vincula un segmento de memoria
UNIX System V proporciona un sistema de memoria
Para trabajar con memoria compartida es necesario
hacer que compartan una zona de memoria
proceso es local al mismo, y cualquier intento de
acceso desde otro proceso provocará una violación de
segmento
compartida entre varios procesos
crear un vínculo (attachment) entre la memoria local del
proceso y el segmento compartido
compartida cree estar trabajando con ella como si fuera
cierta área de memoria local
Memoria compartida
Para crear una zona de memoria compartida
usamos la llamada shmget
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget (key_t key, int size, int shmflg);
donde:
Key es la clave que identifica al segmento de memoria
size especifica el tamaño del segmento (será
shmflg es una máscara de bits (IPC_CREAT,
(IPC_PRIVATE o una clave devuelta por ftok)
redondeado al valor de PAGE_SIZE)
IPC_EXCL, permisos)
Memoria compartida
Al terminar de usar el segmento de memoria, debemos
Antes de usar la memoria compartida, tenemos que asignarle un
espacio de direcciones virtuales de nuestro proceso; es lo que se
conoce como atarse al segmento de memoria compartida
desatarnos de él
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
char *shmat (int shmid, char *shmaddr, int shmflg);
int shmdt (char *shmaddr);
donde:
shmid es el identificador del segmento
Shmaddr es la dirección virtual donde queremos que empiece la zona de
memoria compartida (cuando toma el valor 0, es el núcleo el que elige
la dirección virtual de inicio)
(SHM_RDONLY)
shmflg es una máscara de bits que indica la forma de acceso
Memoria compartida
Para controlar una zona de memoria
compartida usamos la llamada shmctl
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int shmctl (int shmid, int cmd, struct shmid_ds
*buf);
Memoria compartida
Algunas operaciones son:
IPC_STAT: lee la estructura de control asociada a
shmid y la deposita en la estructura apuntada por
buff.
IPC_RMID: elimina el identificador de memoria
compartida especificado por shmid del sistema,
destruyendo el segmento de memoria compartida y
las estructuras de control asociadas. El segmento
desaparecerá cuando el último proceso que lo utiliza
notifique su desconexión del segmento
compartida (sólo superusuario)
compartida (sólo superusuario)
SHM_LOCK: bloquea la zona de memoria
SHM_UNLOCK: desbloquea la región de memoria
Memoria compartida
Ejercicio práctico:
Vamos a crear un proceso padre y un
proceso hijo de forma que el proceso hijo
escriba un valor entero en una zona de
memoria compartida y el proceso padre lo
lea y lo imprima por pantalla una vez que el
proceso hijo haya terminado.
Colas de mensajes
Son listas de mensajes gestionadas por el
núcleo
La comunicación tiene lugar entre procesos
lanzados en la misma máquina
Pueden existir múltiples procesos lectores y
escritores
La “sincronización” es responsabilidad del núcleo
Los mensajes tienen este tipo:
Tipo del mensaje (long)
DATOS del mensaje
Colas de mensajes
Los mensajes se pueden extraer en orden
El receptor puede esperar:
FIFO, pero también en otro orden
el siguiente mensaje (orden FIFO)
el siguiente mensaje de cierto tipo
El núcleo impone límites máximos a:
el número de bytes de un mensaje
el número de bytes en una cola
el número de colas en el sistema
el número de mensajes en el sistema
Memoria compartida
Para crear una cola de mensaje usamos la
llamada msgget
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgget (key_t key, int msgflg);
donde:
Key es la clave que identifica la cola de mensajes
shmflg es una máscara de bits (IPC_CREAT,
(IPC_PRIVATE o una clave devuelta por ftok)
IPC_EXCL, permisos)
Colas de mensajes
Para escribir y leer mensajes usamos,
respectivamente, las llamadas msgsnd y
msgrcv
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgsnd (int msgid, void *msgp, int msgsz, int
msgflg);
int msgrcv (int msgid, void *msgp, int msgsz, long
msgtyp, int msgflg);
Colas de mensajes
int msgsnd (int msgid, void *msgp, int msgsz, int
msgflg);
int msgrcv (int msgid, void *msgp, int msgsz, long
msgtyp, int msgflg);
donde:
msgid es el identificador de la cola
Msgp es un puntero a la zona de memoria donde está el
mensaje a escribir o leido
Msgsz es el tamaño del mensaje en bytes (sin contar el
tamaño del campo “tipo del mensaje”)
Colas de mensajes
int msgsnd (int msgid, void *msgp, int msgsz, int
msgflg);
int msgrcv (int msgid, void *msgp, int msgsz, long
msgtyp, int msgflg);
msgtyp solo aparece en la operación de lectura y puede
tomar los valores siguientes:
• 0, leer el primer mensaje que haya en la cola
• >0, leer el primer mensaje de tipo msgtyp que haya en la cola
• <0, lee el primer mensaje cuyo tipo sea el menor valor menor
o igual que el valor absoluto de msgtyp
Colas de mensajes
El campo msgflg tiene distintos sign
Comentarios de: Tema 6 - IPC del Unix System V - Sistemas Operativos: Programación de Sistemas (0)
No hay comentarios