Departamento de Informática Taller de Sistemas Operativos Universidad Técnica Federico Santa María Comunicación entre Procesos Pipes y Sistema de IPC de System V 1 Departamento de Informática Taller de Sistemas Operativos Universidad Técnica Federico Santa María A) Pipes 2 Departamento de Informática Taller de Sistemas Operativos Universidad Técnica Federico Santa María Características • Son el mecanismo más antiguo de IPC y lo proveen todos los sistemas Unix • Proveen canal unidireccional para flujo de datos entre dos procesos • Sólo puede ser usado entre procesos con un antecesor común que crea la pipe (heredando descriptores comunes). write Raúl Monge read V-3 1 Departamento de Informática Taller de Sistemas Operativos Universidad Técnica Federico Santa María Función: pipe #include <unistd.h> int pipe(int filedes[2]); return: 0 si OK, -1 si existe error • Devuelve dos descriptores: – fildes[0] abierto para lectura – filedes[1] abierto para escritura • Buffering se realiza en el kernel • Normalmente el proceso que llama pipe luego llama a fork • Dependiendo de dirección de flujo cada proceso cierra uno de los descriptores usando close • Podrían existir múltiples lectores y escritores Raúl Monge V-4 Departamento de Informática Taller de Sistemas Operativos Universidad Técnica Federico Santa María Ejemplo de Pipe int main (void) { int n, fd[2]; pid_t pid; char linea[MAXLINEA]; if (pipe(fd) < 0) error_sys(“error en creación de pipe”); if ( (pid =fork()) < 0) error_sys(“error en el fork”); else if { // soy el papa close (fd[0]); // papa no lee, sólo escribe write(fd[1], “Hola mundo\n”); } else { // soy el hijo close (fd[1]); // hijo sólo leerá n = read(fd[0], linea, MAXLINEA); write(STDOUT_FILENO, linea, n); } exit(0); } Raúl Monge V-5 Departamento de Informática Taller de Sistemas Operativos Universidad Técnica Federico Santa María Excepciones • Si se intenta escribir en una pipe que no está abierta para lectura, se genera la señal SIGPIPE. – Se genera en errno el error EPIPE • Si se lee de una pipe cerrada para escritura después de leer todos los datos en el buffer, se genera EOF. • Si existen múltiples escritores, es posible que se entremezclen los datos escritos por los diferentes procesos (depende de tamaño del buffer). Raúl Monge V-6 2 Departamento de Informática Universidad Técnica Federico Santa María Taller de Sistemas Operativos Redireccionamiento de una Pipe a la E/S Estándar • Necesario cuando procesos se conectan a través de la E y S estándar. • Conexión puede ser controlada por un proceso sin modificar el código de programa. • Para hacerlo hay que cerrar el descriptor de STDIN o STDOUT y llamar a dup o dup2. Raúl Monge V-7 Departamento de Informática Universidad Técnica Federico Santa María Taller de Sistemas Operativos Ejemplo de Redireccionamiento if ((pid = fork()) < 0) { error_sys(“error en fork”); } else if (pid == 0) ... /* código del papa */ } else { /* es el hijo */ close (STDIN_FILENO); /* se cierra entrada estándar */ if (dup2(fd[0],STDIN_FILENO) < 0) error_sys(“error en dup2”); close(fd[0]); /* ahora entrada estándar se realiza desde la salida de la pipe */ ... execv(...) /* se carga cualquier programa */ exit(1) } Raúl Monge V-8 Departamento de Informática Universidad Técnica Federico Santa María Taller de Sistemas Operativos FIFO o Pipe con Nombre • Similares a una pipe, pero permiten conectar procesos que no tienen ancestro común que creó la pipe. • Usa la estructura de nombres del sistema de archivos • Existen en el directorio como un archivo especial de tipo FIFO. Raúl Monge V-9 3 Departamento de Informática Taller de Sistemas Operativos Universidad Técnica Federico Santa María Función: mkfifo #include <sys/types.h> #include <sys/stat.h> int mkfifo(const char *pathname, mode_t mode); return: 0 si OK, -1 si existe error • Funciona similar la creación de un archivo con creat • mode tiene igual función que en la función open • Está sujeta al mismo sistema de control de acceso que un archivo (usuario y grupo dueño). • FIFO creado con mkfifo puede ser luego abierto por cualquier proceso que tenga el permiso. Raúl Monge V-10 Departamento de Informática Taller de Sistemas Operativos Universidad Técnica Federico Santa María Sistema de IPC de System V Semáforos y Memoria Compartida 11 Departamento de Informática Universidad Técnica Federico Santa María Taller de Sistemas Operativos Objetos de IPC de System V • Semáforo. Usado para sincronizar los procesos. • Segmento de memoria compartida. Permite que diferentes procesos mapean un mismo segmento a su espacio de memoria. • Cola de mensajes. Permite que procesos en una máquina puedan enviar y recibir mensajes (no lo veremos en el curso). Raúl Monge V-12 4 Departamento de Informática Universidad Técnica Federico Santa María Taller de Sistemas Operativos Identificadores y Claves • Cada objeto de IPC está asociado a una estructura en el kernel que se referencia internamente por un número entero no negativo denominado identificador. • El identificador puede cualquier número • Al crear un objeto, se debe especificar una clave de tipo key_t.que se convierte por el kernel en el identificador para referenciar al objeto. • Procesos que comparten un objeto deben conocer la clave o identificador. Raúl Monge V-13 Departamento de Informática Universidad Técnica Federico Santa María Taller de Sistemas Operativos Asignación de Clave • Un objeto se crea normalmente por el servidor usando función XXXget. – Si clave es IPC_PRIVATE, el sistema crea un nuevo objeto usando un identificador libre. – Si se usa otro valor para clave, entonces se crea si esa clave no está asociada con objeto existente. • Función de creación devuelve el identificador del objeto, usado referenciarlo en otras funciones. – Si existe se produce un error. Raúl Monge V-14 Departamento de Informática Universidad Técnica Federico Santa María Taller de Sistemas Operativos Compartición de un Objeto • Servidor crea objeto con IPC_PRIVATE y comunica identificador a otros procesos (e.g. grabandolo en un archivo o lo pasa en variable de ambiente a un descendiente) • Procesos acuerdan usar la misma clave. Se produce un problema si clave está ocupada. • Usando función ftok para generar una clave a partir de un nombre de ruta (pathname). Raúl Monge V-15 5 Departamento de Informática Universidad Técnica Federico Santa María Taller de Sistemas Operativos Concepto de Semáforo • Corresponde a un contador para control el acceso a un objeto de datos compartido • En el acceso se verifica el valor del semáforo – Si es positivo, se decrementa y retorna la función (operación P) – Sino lo es, bloquea al proceso • Al salir el semáforo se incrementa. Si existe un proceso bloqueado se despierta uno de ellos. • ????? Raúl Monge V-16 Departamento de Informática Universidad Técnica Federico Santa María Taller de Sistemas Operativos Semáforos en System V • Un semáforo tiene asociado un conjunto de uno o más valores, que se especifican al crearlo (semget). • La creación es independiente de la inicialización de los valores (semctl). • Semáforos existen más allá de la vida de un proceso, por lo tanto hay que preocuparse de destruirlos cuando termina la aplicación. Raúl Monge V-17 Departamento de Informática Universidad Técnica Federico Santa María Taller de Sistemas Operativos Función: semget #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> int semget(key_t key, int nsems, int flag); return: ID del semáforo si OK, -1 si existe error • Reglas de uso de clave e identificador ya fue explicado • nsems especifica el número de semáforos (cliente puede dejar valor en 0) • flag permite controlar permisos de acceso y modo de creación. Raúl Monge V-18 6 Departamento de Informática Universidad Técnica Federico Santa María Taller de Sistemas Operativos Función: semctl #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> int semctl(int semid, int snum, int cmd, ... /* union semun arg */); return: 0 si OK, -1 si existe error (excepto en comando GET y GETALL) • Se especifica identificador y número del semáforo • Con cmd se pueden especificar diferentes comandos (e.g. GETVAL, SETVAL, IPC_RMID) • Con arg se pueden especificar argumentos para el comando. Raúl Monge V-19 Departamento de Informática Universidad Técnica Federico Santa María Taller de Sistemas Operativos Función: semop #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> int semop(int semid, struct sembuf semoparray[], size_t nops); return: 0 si OK, -1 si existe error • Se especifica identificador del semáforo (grupo) • El arreglo semoparray es un arreglo de operaciones • Estructura sembuf especifica la operación para cada semáforo. Raúl Monge V-20 Departamento de Informática Universidad Técnica Federico Santa María Taller de Sistemas Operativos Ejemplo de Semáforo (1/4) class semaforo_t { int sid; key_t key; void semcall(int); public: semaforo_t (key_t); void init(int); void P(void) {semcall(-1);} void V(void) {semcall(1);} int remove(void); }; Raúl Monge V-21 7 Departamento de Informática Universidad Técnica Federico Santa María Taller de Sistemas Operativos Ejemplo de Semáforo (2/4) semaforo_t::semaforo_t (key_t k) { key = k; if ( (sid = semget (k, 1, 0666 | IPC_CREAT)) < 0) sys_err(“fallo semget”); } void semaforo_t::init (int val) { union semun arg; arg.val = val; if ( (semctl(sid, 0, SETVAL, arg)) < 0) sys_err(“fallo semctl”); } Raúl Monge V-22 Departamento de Informática Universidad Técnica Federico Santa María Taller de Sistemas Operativos Ejemplo de Semáforo (3/4) void semaforo_t::semcall (int val) { struct sembuf sb; sb.sem_num = 0; sb.sem_op = val; sb.sem_flg = 0; if ((semop(sid, &sb, 1) < 0) sys_err(“error en semop”); } Raúl Monge V-23 Departamento de Informática Universidad Técnica Federico Santa María Taller de Sistemas Operativos Ejemplo de Semáforo (4/4) int semaforo_t::remove (void) { return semctl(sid, 0, IPC_RMID); /* retorna 0 si OK, -1 si no éxito */ } Raúl Monge V-24 8 Departamento de Informática Universidad Técnica Federico Santa María Taller de Sistemas Operativos Memoria Compartida • Permite compartir una región de memoria entre dos o más procesos. • Es la forma de IPC más rápida • Es necesario sincronizar el acceso para mantener la consistencia de los datos (normalmente se usan semáforos) Raúl Monge V-25 Departamento de Informática Universidad Técnica Federico Santa María Taller de Sistemas Operativos Función: shmget #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> int shmget(key_t key, int size, int flag); return: ID del segmento si OK, -1 si existe error • Reglas de uso de clave e identificador ya fue explicado • Con size se especifica el tamaño mínimo en bytes del segmento compartido (cliente puede especificar 0) • Con flag se controla el permiso de acceso. • Identificador de retorno se usa para referenciar en otras funciones el segmento de memoria compartida. Raúl Monge V-26 Departamento de Informática Universidad Técnica Federico Santa María Taller de Sistemas Operativos Función: shmctl #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> int shmctl(int shmid, int cmd, struct shmid_ds *buf); return: 0 si OK, -1 si existe error • Con shmid se especifica identificador del segmento • Con cmd se puede especificar un comando – IPC_SET permite controlar permisos de acceso – IPC_RMID permite remover un segmento (usado por servidor) – SHM_LOCK y SHM_UNLOCK permite asegurar segmento en memoria (sólo el superusuario) Raúl Monge V-27 9 Departamento de Informática Universidad Técnica Federico Santa María Taller de Sistemas Operativos Funciones: shmat y shmdt #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> void* shmat(int shmid, void *addr, int flag); return: puntero al segmento si OK, -1 si existe error void* shmdt(void *addr); return: 0 si OK, -1 si existe error • shmat se liga a un segmento existente y devuelve un puntero como malloc – addr == NULL lo hace en dirección disponible (recomendado) – flag permite controlar permiso de aacceso • shmdt actúa como free. Raúl Monge V-28 10