Está en la página 1de 48

SISTEMAS OPERATIVOS II

PROGRAMACIN CON LLAMADAS AL SISTEMA POSIX


(INTRODUCCIN A LA PROGRAMACIN CON UNIX /LINUX)

1- LLAMADAS AL SISTEMA : 1.1- Interfaz del programador: La interfaz del sistema operativo con el programador es la que recupera los servicios y llamadas al sistema que los usuarios pueden utilizar directamente desde sus programas. Esta es, quizs, una de las partes ms importante de un sistema operativo, ya que recupera la visin que como mquina extendida tiene el usuario del sistema operativo. Las interfaces ms utilizadas son: POSIX y Win32.

1.2- Concepto de llamada al sistema La interfaz con el sistema operativo y los programas de usuario est definida por el conjunto de operaciones extendidas que el sistema operativo ofrece. Estas instrucciones se han llamado tradicionalmente llamadas al sistema, aunque ahora pueden implementarse de varias formas. Para esconder realmente lo que los sistemas operativos hace, debemos examinar con detenimiento esta interfaz. Las llamadas disponibles en la interfaz varan de un sistema operativo a otro (aunque los conceptos subyacentes tienden a ser similares). 1.3- Implementacin: Las llamadas al sistema se realizan de diversas formas de acuerdo a cada arquitectura de equipo. En una IBM 360/370 existe una llamada al sistema especial que hace un trap directamente al SO. Los 8 bits menos significativos son un nmero que identifica el tipo de llamada. El CP/M no posee una instruccin de llamada al sistema especial: se carga en el registro C el nmero de funcin y se realiza un salto a la direccin 5 de memoria. A menudo se necesita pasar al SO informacin adicional al tipo de llamada al sistema. Por ejemplo, para leer una imagen de entrada en tarjetas debemos especificar el archivo o dispositivo a usar y la direccin y longitud del buffer de memoria del cual ser ledo. El dispositivo o archivo puede ya estar implcito en la llamada al sistema y como las tarjetas tienen siempre 80 caracteres, podra no ser necesario el dato de longitud. Dos mtodos generales son usados para pasar parmetros al SO, el ms simple es a travs de registros, y el otro, a travs de bloques o tabla en memoria.

Las llamadas al sistema estn disponibles generalmente en assembler. La mayora de los sistemas permiten realizar llamadas al sistema desde l enguajes de alto nivel (Pascal, Fortran, C, etc.), en los cuales una llamada realmente involucra funciones predefinidas o llamadas a subrutinas. Ellas pueden generar una llamada a una rutina especial de ejecucin que realiza una o varias llamada al sistema. Algunos lenguajes como el C se han definido de forma tal de reemplazar el assembler por instrucciones de alto nivel, permitiendo que las llamadas sean accedidas directamente. Un ejemplo de cmo se usan las llamadas al sistema es considerar escribir un programa que lea datos de un archivo y los copie a otro. 1) El programa necesita primeramente los nombres de los 2 archivos: el de entrada y el de salida. Esto puede especificarse de 2 formas: que el programa pregunte al usuario los nombres, el cual en un sistema interactivo requiere un secuencia de llamadas al sistema, primero para escribir la pregunta en la pantalla y luego para leer lo que se contesta va teclado; en un sistema batch se especifican los nombres con tarjetas de control, en el cual debe haber un mecanismo para pasar estos nombres al programa.
1 DE 48 CTEDRA SISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II
2) Luego se debe abrir el archivo de entrada y crear el de salida. Cada una de estas operaciones requiere llamadas al sistema. Debe tambin preverse errores como la no existencia del archivo de entrada o la existencia de proteccin de acceso al mismo. (Se necesitan llamadas al sistema para manejar cada situacin). 3) Una vez abiertos los archivos, se entra en un loop de lectura que lee el archivo de entrada (una llamada al sistema) y escribe sobre el de salida (otra llamada al sistema). Cada una de estas operaciones debe retornar informacin sobre posibles errores. (Lectura: fin de archivo, error de paridad en la lectura; Escritura: sin espacio en disco, fin de cinta fsico, impresora sin papel). 4) Luego de copiar todo el archivo, el programa debe cerrar los mismos (otra llamada al sistema), escribir un mensaje en la consola (otra llamada) y terminar normalmente Como vemos, los programas hacen uso intensivo de los servicios del SO: toda interaccin entre el programa y su ambiente de trabajo lo realizan a travs de pedidos al SO. Sin embargo los usuarios, normalmente no alcanzan a ver estos detalles.

1.4- Llamadas al sistemas en Linux: Una llamada al sistema es normalmente una demanda al sistema operativo (ncleo) para que haga una operacin de hardware/sistema especifica o privilegiada. Por ejemplo, en Linux-1.2, se han definido 140 llamadas al sistema. Las llamadas al sistema como close() se implementan en la libc de Linux. Esta aplicacin a menudo implica la llamada a una macro que puede llamar a syscall(). Los parmetros pasados a syscall() son el nmero de la llamada al sistema seguida por el argumento necesario. Los nmeros de llamadas al sistema se pueden encontrar en <linux/unistd.h> mientras que <s ys/syscall.h> actualiza con una nueva libc. Si aparecen nuevas llamadas que no tienen una referencia en libc aun, puede usar syscall(). Como ejemplo, puede cerrar un fichero usando syscall() de la siguiente forma (no aconsejable): #include <syscall.h> extern int syscall(int, ...); int my_close(int filedescriptor) { return syscall(SYS_close, filedescriptor); } En la arquitectura i386, las llamadas al sistema estn limitadas a 5 argumentos adems del nmero de llamada al sistema debido al nmero de registros del procesador. Si usa Linux en otra arquitectura puede comprobar el contenido de <asm/unistd.h> para las macros syscall, para ver cuntos argumentos admite su hardware o cuantos escogieron los desarrolladores. Estas macros syscall se pueden usar en lugar de syscall(), pero esto no se recomienda ya que esa macro se expande a una funcin que ya puede existir en una biblioteca. Por consiguiente, slo los desarrolladores del ncleo deberan jugar a con las macros syscall. Como demostracin, aqu tenemos el ejemplo de close() usando una macro syscall. #include <linux/unistd.h> _syscall1(int, close, int, filedescriptor); La macro syscall1 expande la funcin close(). As tenemos close() dos veces, una vez en libc y otra vez en nuestro programa. El valor devuelto por syscall() o un una macro syscall es -1 si la llamada al sistema fall y 0 en caso de xito. Un vistazo a la variable global errno sirve para comprobar que ha ocurrido si la llamada al sistema fall. Las siguiente llamadas al sistema estn disponibles en BSD y SYS-V pero no estn disponibles en Linux: audit(), auditon(), auditsvc(), fchroot(), getauid(), getdents(), getmsg(),
2 DE 48 CTEDRA SISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II
mincore(), poll(), putmsg(), setaudit(), setauid(). 1.5- POSIX: POSIX (IEEE96) es un estndar de interfaz de sistemas operativos portables basado en el sistema operativo UNIX. Aunque UNIX era prcticamente un estndar industrial, haba bastantes diferencias entre las distintas implementaciones de UNIX, lo que provocaba que las aplicaciones no se pudieran transportar fcilmente entre distintas plataformas UNIX. Este problema motiv a los desarrolladores y usuarios a implementar un estndar internacional con el propsito de conseguir la portabilidad de las aplicaciones en cuanto a cdigo fuente. POSIX se ha desarrollado entro de la IEEE con la referencia 1003 y tambin est siendo desarrollado como estndar internacional con la referencia ISO/IEC 9945. POSIX es una familia de estndares en evolucin, cada uno de los cuales cubre diferentes aspectos de los sistemas operativos. POSIX es una interfaz ampliamente utilizada. Se encuentra disponible en todas las versiones de UNIX y Linux, inclusive Windows NT ofrece un subsistema que permite programar aplicaciones POSIX. POSIX en una especificacin estndar, no define una implementacin. Los distintos sistemas operativos pueden ofrecer los servicios POSIX con diferentes implementaciones. Caractersticas ms relevantes: Algunos tipos de datos utilizados por las funciones no se definen como parte del estndar, pero se defiene como parte de la implementacin. Estos tipos se encuentran definidos en el archivo de cabecera <sys/types.h>. Estos tipos acaban con el sufijo _t. Por ejemplo: uid_t, es un tipo que se emplea para almacenar un identificador de usuario (UID).

Los nombres de las llamadas al sistemas en POSIX son en general cortos y con todas sus letras en minsculas. Ejemplo: fork, close, read. Las funciones, normalmente devuelven cero si se ejecutaron con xito, o 1 en caso de error. Cuando una funcin devuelve 1, se almacena en una variable global, denominada errno, el cdigo de error. Este cdigo de error es un valor entero. La variable errno se encuentra definida en el archivo de cabecera <errno.h>. La mayora de los recursos gestionado por el sistema operativo se referencias mediante descriptores. descriptor es un nmero entero mayor o igual que cero. Un

3 DE 48 CTEDRA SISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II

GESTIN DE P ROCESOS/T HREAD CON POSIX

1 - S ERVICIOS PARA LA GESTIN DE PROCESOS : (CARRETERO PEREZ ) 1.1- Identificacin de procesos: POSIX identifica cada proceso por medio de un entero nico denominado Identificador de Proceso (Process ID, PID) de tipo pid_t. a- Obtener el identificador de un proceso: pid_t getpid(void); b- Obtener el identificador del proceso padre: pid_t getppid(void) Ejemplo: #include <sys/types.h> #include <stdio.h> main(){ pid_t id_proceso; pid_t id_padre; id_proceso = getpid(); id_padre = getppid(); printf("Identificador de proceso: %d\n", id_proceso); printf("Identificador del proceso padre %d\n", id_padre); } 1.2- Entorno de un proceso: Viene definido por una lista de variables que se pasan al mismo en el momento de comenzar su ejecucin. Estas variables se denominan variables de entorno y son accesibles a un proceso a travs de la variable externa environ, declarada de la siguiente forma. extern char **environ; Esta variable apunta a una lista de variables de entorno. Esta lista no es ms que un vector de punteros a cadenas de caracteres de la forma nombre=valor, donde nombre hace referencia al nombre de una variable de entorno y valor al contenido de la misma. Ejemplo: Programa que imprime el entorno de un proceso #include <stdio.h> #include <stdlib.h> extern char **environ; int main(int argc, char **argv)
4 DE 48 CTEDRA SISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II
{ int i; printf("Lista de variables de entorno de %s\n",argv[0]); for (i=0 ; environ[i] != NULL ; i++) printf("environ[%d] = %s\n", i, environ[i]); }

Cada aplicacin interpreta la lista de variables de entorno de forma especfica. POSIX establece el significado de determinadas variables de entorno: HOME: directorio de trabajo inicial del usuario LOGNAME: nombre del usuario asociado al un proceso PATH: prefijo de directorios para encontrar ejecutables TERM: tipo de terminal TZ: informacin de la zona horaria El servicio getenv permite buscar una determinada variable de entorno dentro de la lista de variables de entorno de un proceso. char *getenv(const char *name); Esta funcin devuelve un puntero al valor asociado a la variable de entorno de nombre name. si la variable no se encuentra definida, la funcin devuelve NULL.

Ejemplo: Programa que imprime el valor de la variable HOME #include <stdio.h> #include <stdlib.h> int main(){ char *home = NULL; home = getenv("HOME"); if (home == NULL) printf("$HOME no se encuentra definida\n"); else printf("El valor de $HOME es %s\n", home); } 1.3- Creacin de procesos: La nica forma es invocando la llamada al sistema fork. El SO realiza un clonacin del proceso que lo solicite. El proceso que solicita el servicio se convierte en el proceso padre del nuevo proceso. pid_t fork() La clonacin se realiza copiando la imagen de memoria y la PCB. El proceso hijo es una copia del proceso padre en el instante en que ste solicita al servicio fork. Esto significa que los datos y la pila del proceso hijo son los que tiene el padre en ese instante de ejecucin. Es ms, dado que, al entrar el sistema operativo a tratar el servicio, lo primero que
5 DE 48 CTEDRA SISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II
hace es salva los registro en la PCB del padre, al copiarse la PCB se copian los valores salvado de los registro, por lo que el hijo tiene los mismos valores que el padre.

Esto significa que el contador de programa de los dos procesos tiene el mismo valor, por lo que van a ejecutar la misma instruccin mquina. No hay que caer en el error de pensar que el proceso hijo empieza la ejecucin del cdigo en su punto de inicio, sino que el proceso hijo comienza a ejecutar, al igual que el padre, la sentencia que se encuentra despus de fork(). Las diferencias que existen entre el proceso hijo y el padre son: El proceso hijo tiene su propio identificador(PID). El proceso hijo tiene una nueva descripcin de la memoria. Aunque el hijo tenga los segmentos con el mismo contenido, no tienen por que esta en la misma zona de memoria. El tiempo de ejecucin del proceso hijo es igual a cero. Todas la alarmas pendientes se desactiva en el proceso hijo. El conjunto de seales pendientes se pone en cero. El valor que retorna el sistema operativo como resultado de fork() e distinto en el hijo que el padre (el hijo recibe un 0 y el padre el PID del hijo). Este valor de retorno se puede utilizar mediante una clusula de condicin para que le padre y el hijo sigan flujos de ejecucin distintos.

Las modificaciones que realice el proceso padre sobre sus registros e imagen de memoria despus de fork no afectan al hijo y, viceversa. Sin embargo, el proceso hijo tiene su propia copia de los descriptores del proceso padre.
6 DE 48 CTEDRA SISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II
Esto hace que el hijo tenga acceso a los archivos abiertos por el proceso padre. El padre y el hijo comparte el puntero de posicin de los archivos abiertos en el padre. Ejemplo: Programa que crea un proceso #include #include #include #include <sys/types.h> <stdio.h> <unistd.h> <sys/wait.h>

int main(){ pid_t pid; pid = fork(); if(pid==-1) /* error del fork() */ printf(Error\n); else if(pid==0) printf("Soy el HIJO, Proceso %d; padre = %d \n", getpid(), getppid()); else printf("Soy el PADRE, Proceso %d\n", getpid()); } // Ejemplo: Programa que crea una cadena de procesos // En cada ejecucin del bucle crea un proceso. El proceso padre obtiene el // identificador del hijo, que ser distinto de cero y saldr del bucle utilizando // la sentencia break. El proceso hijo continuar la ejecucin, repitindose // este proceso hasta que se llegue al final del bucle #include <sys/types.h> #include <stdio.h> #include <unistd.h> int main() { pid_t pid; int i; int n = 10; for (i = 0; i < n; i++){ pid = fork(); if (pid != 0) break; } printf("El padre del proceso %d es %d\n", getpid(), getppid()); }

7 DE 48 CTEDRA SISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II
1.4- Ejecutar un programa: El servicio exec de POSIX tiene por objetivo cambiar el programa (el cdigo) que se est ejecutado. Se puede considerar que el servicio tiene dos fases. En la primera se vaca el proceso de casi todo su contenido, mientras en la segunda se carga un nuevo programa. exec no genera ningn proceso nuevo, simplemente cambia el programa que ejecuta el proceso que lo invoc. En el proceso de vaciado de la imagen de memoria se conservan algunos datos como ser: Entorno del proceso que el SO lo incluye en la nueva pila. Ciertos datos de la PCB (PID, PPID, identificador de usuario y descriptores de archivos abiertos). Fase de carga: Asignar al proceso un nuevo espacio de memoria. Cargar el texto y los datos iniciales en los segmentos correspondientes. Crear la pila inicial del proceso con el entorno y los parmetros que se pasa al programa. Llenar la PCB con los valores iniciales de los registro y la descripcin de los nuevo segmentos de memoria.

Prototipos de la familia de funciones exec: int excl(char *path, char *arg, ...); int execv(char *path, char *arg[]); int execle(char *path, char *arg, ...); int execve(char *path, char *arg[], char *envp[]); int execlp(char *file, const char *arg, ); int execvp(char *file, char *argv[]); La nueva imagen se construye a partir de un archivo ejecutable. Si la llamada se ejecuta con xito, sta no devolver ningn valor puesto que la imagen del proceso habr sido reemplazada, caso contrario devuelve 1. La funcin main() del nuevo programa tendr la forma: int main(int argc, char **argv)
8 DE 48 CTEDRA SISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II
donde argc representa el nmero de argumentos que se pasan al programa, incluido el propio nombre del programa, y argv es un vector de cadenas de caracteres, conteniendo cada elemento de este vector un argumento pasado al programa. El primer componente de este vector (argv[0]) representa el nombre del programa. Argumentos: path: apunta al nombre del archivo ejecutable donde reside la nueva imagen del proceso. file : se utiliza para construr el nombre del archivo ejecutable. Si el argumento file contiene el carcter /, entonces el argumento file constituye el nombre del archivo ejecutable. Casa contrario, el prefijo del nombre para el archivo se construye por medio de la bsqueda en los directorios pasados en la variable de entrono PATH. argv contiene los argumentos pasadas al programa y debera acabar con un puntero NULL. envp apunta al entorno que se pasar al nuevo proceso y se obtiene de la variable externa environ. Los descriptores de los archivos abiertos previamente por le proceso que realiza la llamada exec permanecen abiertos en la nueva imagen del proceso, excepto aquellos abiertos con el valor FD_CLOEXEC. Las seales con la accin por defecto seguirn por defecto. Las seales ignoradas seguirn ignoradas por el nuevo proceso y las seales con manejadores activados tomaran la acciones por defecto en la nueva imagen del proceso. Atributos que se mantienen despus de la llamada: PID PPID UID GID EUID EGID Directorio de trabajo actual (Work Directory) Mscara de creacin de archivos. Mscara de seales del proceso. Seales pendientes.

// Ejemplo: Programa que ejecuta el comando ls l #include <sys/types.h> #include <sys/wait.h> #include <stdio.h> #include <unistd.h> int main() { pid_t pid; int status; pid = fork(); switch(pid) { case -1: /* error del fork() */ exit(-1); case 0: /* proceso hijo */ execlp("ls","ls","-l",NULL); perror("exec"); break; default: /* padre */ printf("Proceso padre\n");
9 DE 48 CTEDRA SISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II
while(pid != wait(&status)); } }

// Ejemplo: Programa que ejecuta el comando ls l mediante execvp #include <sys/types.h> #include <stdio.h> #include <unistd.h> int main(int argc, char **argv) { pid_t pid; char *argumentos[3]; argumentos[0] = "ls"; argumentos[1] = "-l"; argumentos[2] = NULL; pid = fork(); switch(pid) { case -1: /* error del fork() */ exit(-1); case 0: /* proceso hijo */ execvp(argumentos[0], argumentos); perror("exec"); break; default: /* padre */ printf("Proceso padre\n"); } }

// Ejemplo: Programa que ejecuta el comando desde el shell #include <sys/types.h> #include <stdio.h> #include <unistd.h> int main(int argc, char **argv) { pid_t pid; pid = fork(); switch(pid) { case -1: /* error del fork() */ perror("fork"); break; case 0: /* proceso hijo */
10 DE 48 CTEDRA S ISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II
if (execvp(argv[1], &argv[1])< 0) perror("exec"); break; default: /* padre */ printf("Proceso padre\n"); } }

2- SERVICIOS POSIX PARA LA GESTIN DE HILOS (THREAD): (CARRETERO PEREZ ) 2.1- Atributos de un thread: Cada hilo en POSIX tiene asociado una serie de atributos que representa sus propiedades. Los valores de estos se almacenan en un objeto atributo de tipo pthread_attr_t. a) Crear un atributo: Permite iniciar una estructura atributo que se puede utilizar para crea nuevos procesos ligeros. int pthread_attr_init(pthread_attr_t *attr);

b) Destruir atributos: int pthread_attr_destroy(pthread_attr_t *attr);

c) Asignar el tamao de la pila: Cada hilo tiene una pila cuyo tamao se pude establecer mediante esta funcin. int pthread_attr_setstacksize(pthread_attr_t *attr, int stacksize);

d) Determinar el tamao de la pila: int pthread_attr_getstacksize(pthread_attr_t *attr, int *stacksize)

e) Establecer el estado de terminacin: int phtread_attr_setdatachstate(pthread_attr_t *attr, int detachstate; Si el valor del argumento detachstate es PTHREAD_CREATE_DETACHED, el proceso ligero que se cree con esos atributos se considerar como independiente y liberar sus recursos cuando finalice su ejecucin. Si el valor del argumento detachstate es PTHREAD_CREATE_JOINABLE, el proceso ligero se crea como no independiente y no liberar sus recursos cuando finalice su ejecucin. En este caso es necesario que otro proceso ligero espere por su finalizacin. Esta espera se consigue mediante el servicio pthread_join.

11 DE 48 CTEDRA S ISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II
2.2- Creacin e identificacin de procesos ligeros: a) Crear un proceso ligero: int pthread_create(pthread_t *thread, pthread_attr_r *attr, void *(*start routine) (void *), void *arg); El primer argumento de la funcin apunta al identificador del proceso ligero que se crea, este identificador viene determinado por el tipo pthread_t. El segundo argumento especifica los atributos de ejecucin asociados al nuevo proceso ligero. Si el valor de este segundo argumento es NULL, se utilizarn los atributos por defecto, que incluyen la creacin del proceso como no independiente. El tercer argumento indica el nombre de la funcin a ejecutar cuando el proceso ligero comienza su ejecucin. Esta funcin requiere un solo parmetro que se especifica con el cuarto argumento, arg. b) Obtener el identificador de un proceso ligero: pthread_t pthread_self()

2.3- Terminacin de procesos ligeros: a) Esperar la terminacin de un proceso ligero: Este servicio es similar a wait, pero a diferencia de ste, es necesario especificar el proceso ligero por el que se quiere esperar, que no tiene por qu ser un proceso ligero hijo. int pthread_join(pthread thid, void **value); La funcin suspende la ejecucin del proceso ligero que la invoca hasta que el proceso ligero con identificador thid finalice su ejecucin. La funcin devuelve en el segundo argumento el valor que pasa el proceso ligero que finaliza su ejecucin en el servicio pthread_exit, que se ver a continuacin. nicamente se pude solicitar el servicio pthread_join sobre procesos ligeros creados como no independientes. b) Finalizar la ejecucin de un proceso ligero: int pthread_exit(void *value) Incluye un puntero a una estructura que es devuelta al proceso ligero que ha ejecutado la correspondiente llamada a pthread_join, lo que es mucho ms genrico que el parmetro que permite el servicio wait.

12 DE 48 CTEDRA S ISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II

En la figura se muestra una jerarqua de procesos ligeros. Se supone que el proceso ligero A es el primario, por lo que corresponde a la ejecucin del main. Los proceso B, C, y D se han creado mediante pthread_create() y ejecutan respectivamente los procedimientos b(), c() y d(). El proceso ligero D se ha creado como no independiente por lo que otro proceso puede hacer una operacin join sobre l. La figura muestra que le proceso ligero C hace una operacin join sobre D, por lo que queda bloqueado hasta que termine.

//Ejemplo //Programa que crea dos procesos ligeros no independientes #include <pthread.h> #include <stdio.h> void *func(void * jj){ printf("Thread %d \n", pthread_self()); pthread_exit(0); } int main() { pthread_t th1, th2; /* se crean dos procesos ligeros con atributos por defecto */ pthread_create(&th1, NULL, func, NULL); pthread_create(&th2, NULL, func, NULL); printf("El proceso ligero principal continua ejecutando\n"); /* se espera su terminacin */ pthread_join(th1, NULL); pthread_join(th2, NULL);

13 DE 48 CTEDRA S ISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II
exit(0); } /* Ejemplo Programa que crea diez procesos ligeros independientes, que liberen sus recursos cuando finalizan ( se han creado con el atributo PTHREAD_CREATE_DETACHED). En este caso no se puede esperar la terminacin de los procesos ligeros, por lo que el proceso ligero principal que ejecuta el cdigo de la funcin main debe continuar su ejecucin en paralelo con ellos. Para evitar que el proceso ligero principal finalice la ejecucin de la funcin main, lo que supone la ejecucin del servicio exit y, por lo tanto, la finalizacin de todo el proceso, junto con todos los procesos ligeros, el proceso ligero principal suspende su ejecucin durante cinco segundo para dar tiempo a la creacin y destruccin delos procesos ligeros que se han creado. La ejecucin de exit supone la finalizacin del proceso que ejecuta la llamada. Esto supone, por lo tanto, la finalizacin de todos sus procesos ligeros, ya que stos slo tienen sentido dentro del contexto de un proceso. */ #include <pthread.h> #include <stdio.h> #include <unistd.h> #define MAX_THREADS 10 void *func(void *jj){ printf("Thread %d \n", pthread_self()); pthread_exit(0); } int main(void) { int j; pthread_attr_t attr; pthread_t thid[MAX_THREADS]; /* Se inicial los atributos y se marcan como independientes */ pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); for(j = 0; j < MAX_THREADS; j ++) pthread_create(&thid[j], &attr, func, NULL); /* El proceso ligero principal no puede esperar la finalizacin */ /* de los procesos ligeros que creado y se suspende durante un */ /* cierto tiempo esperando su finalizacin */ sleep(5); } //Ejemplo //Programa que crea un proceso ligero por cada nmero introducido #include <pthread.h> #include <stdio.h> #define MAX_THREADS 10 struct pal{
14 DE 48 CTEDRA S ISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II
int n; }; void *imprimir(void *n){ struct pal *j = (struct pal *) n; printf("Thread %d %d \n", pthread_self(), j->n); pthread_exit(0); } int main(void) { pthread_attr_t attr; pthread_t thid; int num; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); while(1){ printf("Escribir numero entero :\n"); scanf("%d", &num); /* espera */ pthread_create(&thid, &attr, &imprimir, &num); } }

15 DE 48 CTEDRA S ISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II
COMUNICACIN ENTRE PROCESOS EN LINUX

1- INTRODUCCIN
Los medios IPC (Inter-Process Communication) de Linux proporcionan un mtodo para que mltiples procesos se comuniquen unos con otros. Hay varios mtodos de IPC disponibles para los programadores Linux en C: Pipes UNIX Half-duplex FIFOs (pipes con nombre) Colas de mensajes estilo SYSV Semforos estilo SYSV Segmentos de memoria compartida estilo SYSV Sockets (estilo Berkeley) Seales Los tubos, mensajes y memoria compartida proporcionan un medio de comunicacin de datos entre procesos, mientras que los semforos y las seales se usan para provocar acciones en otros procesos. Estos medios, cuando se usan de forma efectiva, proporciona una base slida para el desarrollo de cliente/servidor en cualquier sistema UNIX (incluido Linux).

2- IPC EN S ISTEMA V
2.1 Conceptos fundamentales: Con Unix Sistema V, AT&T introdujo tres nuevas formas de las facilidades IPC (colas de mensajes, semforos y memoria compartida). Mientras que el comit POSIX aun no ha completado su estandarizacin de estas facilidades, la mayora de las implementaciones soportan stas. Adems, Berkeley (BSD) usa sockets como su forma primaria de IPC, ms que los elementos del Sistema V. Linux tiene la habilidad de usar ambas formas de IPC (BSD y System V). Identificadores IPC Cada objeto IPC tiene un nico identificador IPC asociado con l. Cuando decimos objeto IPC, hablamos de una simple cola de mensaje, semforo o segmento de memoria compartida. Se usa este identificador, dentro del ncleo, para identificar de forma nica un objeto IPC. Por ejemplo, para acceder un segmento particular memoria compartida, lo nico que requiere es el valor del ID que se le ha asignado a ese segmento. La unicidad de un identificador es importante segn el tipo de objeto en cuestin. Para ilustrar esto, supondremos un identificador numrico 12345". No puede haber nunca dos colas de mensajes con este mismo identificador, pero existe la posibilidad que existan una cola de mensajes y un segmento de memoria compartida que poseen el mismo identificador numrico. Claves IPC Para obtener un identificador nico, debe utilizarse una clave. Esta debe ser conocida por ambos procesos cliente y servidor. Este es el primer paso para construir el entorno cliente/servidor de una aplicacin. Cuando usted llama por telfono a alguien, debe conocer su nmero. Adems, la compaa telefnica debe conocer cmo dirigir su llamada al destino. Una vez que el receptor responde a su llamada, la conexin tiene lugar. En el caso de los mecanismos IPC de Sistema V, el telfono" coincide con el tipo de objeto usado (semforo, cola de mensaje, etc). El nmero de telfono, se puede comparar con la clave IPC. La clave puede ser el mismo valor cada vez cada vez que se ejecuta el programa, incluyendo su valor en cdigo. Esta es una desventaja pues la clave requerida puede estar ya en uso. Por eso, la funcin ftok() nos ser til para generar claves no utilizadas para el cliente y el servidor.

FUNCIN DE LIBRERA: ftok(); PROTOTIPO: key_t ftok ( char *nombre, char proj ); 16 DE 48 CTEDRA S ISTEMAS OPERATIVOS II 2006 RETORNA: nueva clave IPC si tuvo xito. -1 si no tuvo xito, dejando errno con el valor de la llamada stat()

SISTEMAS OPERATIVOS II

La clave devuelta por ftok() se genera por la combinacin del nmero del i-nodo y el nmero menor de dispositivo del archivo argumento, con el carcter identificador del segundo argumento. Este no garantiza la unicidad, pero una aplicacin puede comprobar las colisiones y reintentar la generacin de la clave. key_t miclave; miclave = ftok("/tmp/miaplic", 'a'); En el caso anterior el directorio /tmp/miaplic se combina con la letra 'a'. Otro ejemplo comn es usar el directorio actual: key_t miclave; mykey = ftok(".", 'a'); El algoritmo de la generacin de la clave usado est completamente a la discrecin del programador de la aplicacin. Mientras que tome medidas para prevenir las condiciones crticas, bloqueos, etc, cualquier mtodo es viable. Para nuestros propsitos de demostracin, usaremos ftok(). El valor clave que se obtiene, se usa en las llamada al sistema IPC para crear u obtener acceso a los objetos IPC. El comando ipcs ipcs puede utilizarse para obtener el estado de todos los objetos IPC Sistema V. ipcs ipcs ipcs ipcs -q: Mostrar solo colas de mensajes -s: Mostrar solo los semforos -m: Mostrar solo la memoria compartida --help: Otros argumentos

Por defecto, se muestran las tres categoras. Considrese el siguiente ejemplo de salida del comando ipcs: ------ Shared Memory Segments -------shmid owner perms bytes nattch status ------ Semaphore Arrays -------semid owner perms nsems status ------ Message Queues -------msqid owner perms used-bytes messages 0 root 660 5 1 Aqu vemos una simple cola mensaje que tiene un identificador 0. Es propiedad del root, y tiene permisos 660, o -rw-rw--. Hay un mensaje en la cola, y ese mensaje tiene un tamao total de 5 bytes. Los comandos ipcs son una herramienta muy potente que proporciona una introduccin a los mecanismos de almacenamiento del ncleo para objetos IPC. El comando ipcrm Se puede usar el comando ipcrm para quitar un objeto IPC del ncleo. Mientras que los objetos IPC se pueden quitar mediante llamadas al sistema en el cdigo del usuario, aparece a menudo la necesidad, sobre todo en ambientes de desarrollo, de quitar objetos IPC a mano. Su uso es simple:

17 DE 48 CTEDRA S ISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II
ipcrm <msg | sem | shm> <IPC ID> Simplemente especifique si el objeto a eliminar es una cola de mensaje (msg), un semforo (sem), o un segmento de memoria compartida (shm). El identificador de IPC se puede obtener mediante los comandos ipcs. Tiene que especificar el tipo de objeto, dado que los identificadores son nicos dentro de un mismo tipo, pero no entre distintos tipos de objetos.

2.2 Semforos: Conceptos Bsicos Los semforos se pueden describir mejor como contadores q ue se usan para controlar el acceso a recursos compartidos por mltiples procesos. Se usan con ms frecuencia como un mecanismo de cierre para prevenir que los procesos accedan a un recurso particular mientras otro proceso lo est utilizando. Los semforos son a menudo considerados como el ms difcil asir de los tres tipos de objetos Sistema V IPC. Para comprender totalmente los semforos, los discutiremos brevemente antes de comenzar cualquier llamada al sistema y teora operacional. El nombre de semforo es realmente un trmino viejo del ferrocarril, que se usaba para prevenir accidentes, en el cruce de las vas de los viejos carros. Exactamente lo mismo se puede decir sobre un semforo. Si el semforo est abierto (los brazos en alto), entonces un recurso est disponible (los carros cruzaran las vas). Sin embargo, si el semforo est cerrado (los brazos estn abajo), entonces el recurso no estn disponible (los carros deben esperar). Mientras que con este ejemplo simple nos introduce el concepto, es importante darse cuenta de que los semforos en POSIX se llevan a cabo realmente como conjuntos, en lugar de como entidades solas. Por supuesto, un conjunto de semforos dado puede tener slo un semforo, como en nuestro ejemplo del ferrocarril. Quizs otra aproximacin al concepto de semforos, sera pensar en ellos como contadores de recursos. Apliquemos este concepto a otro caso del mundo real. Considere un spooler de impresin, capaz de manipular impresoras mltiples, con cada manejo de la impresora con demandas de la impresin mltiples. Un hipottico manejador del spool de impresin utilizar un conjunto de semforos para supervisar el acceso a cada impresora. Suponemos que en nuestro cuarto de impresoras, tenemos 5 impresoras conectadas. Nuestro manejador del spool asigna un conjunto de 5 semforos a l, uno por cada impresora del sistema. Como cada impresora es capaz de imprimir fsicamente un nico trabajo en un instante, cada uno de nuestros cinco semforos se inicializar con un valor de 1 (uno), lo que significa que estn todas en lnea, y aceptan trabajos. Juan enva una peticin de impresin al spooler. El manejador de la impresin mira los semforos, y encuentra que el primer semforo tiene un valor de uno. Ante enviar la peticin de Juan al aparato fsico, el manejador de impresin decrementa el semforo de la impresora correspondiente. Ahora, el valor de ese semforo es cero. En nuestro ejemplo no se pueden enviar a esa impresora ninguna otra peticin hasta que sea distinto de cero. Cuando el trabajo de Juan se ha realizado, el gestor de impresin incrementa el valor del semforo correspondiente. Su valor vuelve a ser uno (1), lo que indica que el recurso vuelve a estar disponible. Naturalmente, si los cinco semforos tienen valor cero, indica que todas las impresoras estn ocupadas con peticiones y no se pueden atender ms. Aunque este es un ejemplo simple, procure no confundirse con el valor inicial (1) dado a los semforos. En realidad, cuando se ven como contadores de recursos, pueden ser iniciados con cualquier valor positivo, y no estn limitados a valer 0 o 1. Si las impresoras de nuestro ejemplo fuesen capaces de aceptar 10 trabajos de impresin, habramos iniciado sus semforos con el valor 10, decrementndolo en 1 cada vez que lega un trabajo nuevo y reincrementndolo al terminar otro. Como descubriremos en este captulo, el funcionamiento de los semforos tiene mucha relacin con el sistema de memoria compartida, actuando como guardianes para evitar mltiples escrituras en la misma zona de memoria.

18 DE 48 CTEDRA S ISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II
Antes de entrar en las llamadas al sistema relacionadas, repasemos varias estructuras de datos internas usadas en las operaciones con semforos. Estructuras de datos internas Veamos brevemente las estructuras de datos mantenidas por el ncleo para los conjuntos de semforos. El ncleo mantiene unas estructuras de datos internas especiales por cada conjunto de semforos dentro de su espacio de direcciones. Esta estructura es de tipo semid_ds y se define en linux/sem.h como sigue: /* Hay una estructura semid_ds por cada juego de semforos */ struct semid_ds { struct ipc_perm sem_perm; /* permisos .. ver ipc.h */ time_t sem_otime; /* ultimo instante semop */ time_t sem_ctime; /* ultimo instante de cambio */ struct sem *sem_base; /* puntero al primer semforo del array */ struct wait_queue *eventn; struct wait_queue *eventz; struct sem_undo *undo; /* deshacer peticiones del array*/ ushort sem_nsems; /* no. de semaforos del array */ }; Como con las colas de mensaje, las operaciones con esta estructura son ejecutados por llamadas especiales al sistema especial, y no se deben usar directamente. Aqu tenemos las descripciones de los campos ms interesantes: sem_perm Este es un caso de la estructura ipc perm, que se define en linux/ipc.h. Toma la informacin de los permisos para el conjunto de semforos, incluyendo permisos de acceso e informacin sobre el creador del conjunto (uid, etc). sem_otime Instante de la ltima operacin semop(). sem_ctime Instante del ltimo cambio de modo. sem_base Puntero al primer semforo del array (ver siguiente estructura). sem_undo Nmero de solicitudes de deshacer en el array. sem_nsems Nmero de semforos en el conjunto (el array) Estructura sem del ncleo En la estructura semid_ds, hay un puntero a la base del array del semforo. Cada miembro del array es del tipo estructura sem. Tambin se define en linux/sem.h: /* Una estructura por cada juego de semforos */ struct sem {
19 DE 48 CTEDRA S ISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II
short sempid; /* pid de ultima operacin */ ushort semval; /* valor actual */ ushort semncnt; /* num. procesos esperando para incrementarlo */ ushort semzcnt; /* num. procesos esperando que semval sea 0 */ }; sempid El PID (identificador del proceso) que realiz la ltima operacin. semval Valor actual del semforo. semncnt Nmero de procesos esperando la disponibilidad del recurso. semzcnt cantidad de semforos esperando que semval = 0

LLAMADA AL SISTEMA: semget() Se usa para crear un nuevo conjunto o acceder a uno existente. LLAMADA AL SISTEMA: semget(); PROTOTIPO: int semget ( key_t key, int nsems, int semflg ); RETORNA: Identificador IPC del conjunto, si tuvo xito. -1 si existi un error y errno= EACCESS (permiso denegado) EEXIST (no puede crearse pues existe (IPC_EXCL)) EIDRM (conjunto marcado para borrarse) ENOENT (no existe el conjunto ni se indic IPC_CREAT) ENOMEM (No hay memoria suficiente para crear) ENOSPC (Limite de conjuntos excedido)

El primer argumento de semget() es el valor clave (en nuestro caso devuelto por la llamada a ftok()). Este valor clave se compara con los valores clave existentes en el ncleo para otros conjuntos de semforos. Ahora, las operaciones de apertura o acceso depende del contenido del argumento semflg. Desafortunadamente, otro proceso podra haber elegido la misma clave, por lo que ambos accedera al mismo semforo. Usando la constante especial IPC_PRIVATE como valor de la clave se busca garantizar que un nuevo semforo sea crado. Un nuevo conjunto de nsems semforos se crea si key tiene el valor IPC_PRIVATE, o si key no vale IPC_PRIVATE, no hay un conjunto de semforos asociado a key, y el bit IPC_CREAT vale 1 en semflg IPC_CREAT Crea el juego de semforos si no existe ya en el ncleo. IPC_EXCL Al usarlo con IPC CREAT, falla si el conjunto de semforos existe ya. Si se usa IPC_CREAT solo, semget(), bien devuelve el identificador del semforo para un conjunto nuevo creado, o devuelve el identificador para un
20 DE 48 CTEDRA S ISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II
conjunto que existe con el mismo valor clave. Si se usa IPC_EXCL junto con IPC_CREAT, entonces se crea un conjunto nuevo, o si el conjunto existe, la llamada falla con 1. IPC_EXCL es intil por s mismo, pero cuando se combina con IPC_CREAT, se puede usar como una facilidad garantizar que ningn semforo existente se abra accidentalmente para accederlo. Como sucede en otros puntos del IPC del Sistema V, puede aplicarse a los parmetros anteriores, un nmero octal para dar la mscara de permisos de acceso de los semforos. Debe hacerse con una operacin OR binaria. El argumento nsems especifica el nmero de semforos que se deben crear en un conjunto nuevo. Este representa el nmero de impresores en nuestro cuarto de impresin ficticio descrito antes. El mximo nmero de semforos en un conjunto se define en\linux/sem.h" como: #define SEMMSL 32 /* <=512 max num de semforos por id */ Observe que el argumento nsems se ignora si abre explcitamente un conjunto existente. Creemos ahora una funcin de cobertura para abrir o cerrar juegos de semforos: int abrir_conj_semaforos( key_t clave, int numsems ){ int sid; if ( numsems > 0) return semget(clave, numsems, IPC_CREAT | 0660 ); else return(-1); } Vea que se usan explcitamente los permisos 0660. Esta pequea funcin retornar, bien un identificador entero del conjunto de semforos, o bien un -1 si hubo un error. En el ejemplo del final de esta seccin, observe la utilizacin del flag IPC_EXCL para determinar si el conjunto de semforos existe ya o no.

LLAMADA AL SISTEMA: semop() LLAMADA AL SISTEMA: semop(); PROTOTIPO: int semop ( int semid, struct sembuf *sops, unsigned nsops); RETURNS: 0 si tuvo xito (todas las operaciones realizadas) -1 si existi un error y la variable errno = E2BIG (nsops mayor que mx. nmero de opers. permitidas atmicamente) EACCESS (permiso denegado) EAGA IN (IPC_NOWAIT incluido, la operacin no termin) EFAULT (direccin no v_alida en el parmetro sops) EIDRM (el conj. de semforos fue borrado) EINTR (Recibida seal durante la espera) EINVAL (el conj. no existe, o semid invlido) ENOMEM (SEM_UNDO incluido, sin memoria suficiente crear la estructura de retroceso necesaria) ERANGE (valor del semforo fuera de rango)

El primer argumento de semop() es el identificador IPC (en nuestro caso devuelto por una llamada a semget(). El segundo argumento (sops) es un puntero a un array de operaciones para que se ejecuta en el conjunto de semforo, mientras el tercer argumento (nsops) es el nmero de operaciones en ese array.
21 DE 48 CTEDRA S ISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II
El argumento sops apunta a un array del tipo sembuf. Se declara esta estructura en linux/sem.h como sigue: /* La llamada al sistema semop usa un array de este tipo */ struct sembuf { ushort sem_num; /* posicin en el array */ short sem_op; /* operacin del semforo */ short sem_flg; /* flags de la operacin */ }; sem_num Nmero de semforo sobre el que desea actuar, recuerde que en Linux no se crean semforos individuales, sino conjuntos de semforos. Este atributo permite elegir o seleccionar el semforo del conjunto sobre el que se desea actual sem_op Operacin a realizar (positiva, negativa o cero) sem_flg Flags (parmetros) de la operacin Si sem_op es negativo, entonces su valor se resta del valor del semforo. Este pone en correlacin con la obtencin de recursos que controla el semforo o los monitores de acceso. Si no se especifica IPC_NOWAIT, entonces proceso que efecta la llamada duerme hasta que los recursos solicitados estn disponible en el semforo, es decir, que si al Decrementar el semforo este queda con un valor negativo el proceso se bloquea. Si sem_op es positivo, entonces su valor se aade (se suma) al semforo. Este se pone en correlacin con los recursos devueltos al conjunto de semforos de la aplicacin. Siempre se deben devolver los recursos al conjunto de semforos cuando ya no se necesiten ms. Finalmente, si sem_op vale cero (0), entonces el proceso que efecta la llamada dormira hasta que el valor del semforo sea 0. Para explicar la llamada de semop, volvamos a ver nuestro ejemplo de impresin. Supongamos una nica una impresora, capaz de nico un trabajo en un instante. Creamos un conjunto de semforos con nico semforo en l (slo una impresora), e inicializa ese semforo con un valor de uno (nico un trabajo en un instante). Cada vez que deseemos enviarle un trabajo a esta impresora, primeros necesitamos asegura que el recurso est disponible. Hacemos este para intentar obtener una unidad del semforo. Cargamos un array sembuf para realizar la operacin:

struct sembuf sem_lock = { 0, -1, IPC_NOWAIT };

La traduccin de la inicializacin de la anterior estructura indica que se decrementar en una unidad el semforo 0 del conjunto de semforos. En otras palabras, se obtendra una unidad de recursos del nico semforo de nuestro conjunto (miembro 0). Se especifica IPC_NOWAIT, as la llamada o se produce inmediatamente, o falla si otro trabajo de impresin est activo en ese momento. Aqu hay un ejemplo de como usar esta inicializacin de la estructura sembuf con la llamada al sistema semop: if((semop(sid, &sem_lock, 1) == -1) perror("semop");
22 DE 48 CTEDRA S ISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II
El tercer argumento (nsops) dice que estamos slo ejecutando una (1) operacin (hay slo una estructura sembuf en nuestra array de operaciones). El argumento sid es el identificador IPC para nuestro conjunto de semforos. Cuando nuestro trabajo de impresin ha terminado, debemos devolver los recursos al conjunto de semforos, de manera que otros puedan usar la impresora. Esto es similar a hacer un wait() en la teora de los semforos, con la nica diferencia es que se esta especificando como IPC_NOWAIT, lo que significa que la funcin a decrementar el semforo y encontrarse con un valor negativo no bloquea el proceso, simplemente falla y deja que contine su ejecucin. Para que esta llamada al sistema sea equivalente a la operacin wait() en teora de semforos, no se debe indicar IPC_NOWAIT. struct sembuf sem_unlock = { 0, 1, IPC_NOWAIT }; La traduccin de la estructura anteriormente inicializada indica que un valor de 1 se agrega a semforo nmero 0 en el conjunto de semforos. En otras palabras, una unidad de recursos se devolver al conjunto. Esto es equivalente a hacer un signal() en la teora de los semforos LLAMADA AL SISTEMA: semctl()

LLAMADA AL SISTEMA: semctl(); PROTOTIPO: int semctl ( int semid, int semnum, int cmd, union semun arg ); RETURNS: entero positivo si _exito -1 si error: errno = EACCESS (permiso denegado) EFAULT (direccin invlida en el argumento arg) EIDRM (el juego de semforos fue borrado) EINVAL (el conj. no existe, o semid no es vlido) EPERM (El EUID no tiene privilegios para el comando incluido en arg) ERANGE (Valor para semforo fuera de rango) NOTAS: Realiza operaciones de control sobre conjuntos de semforos La llamada al sistema semctl se usa para desempear operaciones de control sobre un conjunto de semforo. Esta llamada es anloga a la llamada al sistema msgctl que se usa para operaciones sobre las colas de mensaje. Si usted compara las listas de argumento de las dos llamadas al sistema, notar que la lista para semctl vara ligeramente con la de msgctl. Las llamados al sistema utilizan un argumento cmd, para la especificacin del comando a ser realizado sobre el objeto IPC. La diferencia con las colas de mensajes es que con los semforos, se soportan los comandos operacionales adicionales, as requieren unos tipos de estructuras de datos ms complejos en el argumento final. El uso del tipo unin confunde a muchos programadores de forma considerable. Nosotros estudiaremos esta estructura cuidadosamente, en un esfuerzo para impedir cualquier confusin. El argumento cmd representa el comando a ejecutar con el conjunto. Como puede ver, incluye los conocidos comandos IPC_STAT/IPC_SET, junto a otros especficos de conjuntos de semforos: IPC_STAT Obtiene la estructura semid ds de un conjunto y la guarda en la direccin del argumento buf en la unin semun.

23 DE 48 CTEDRA S ISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II
IPC_SET Establece el valor del miembro ipc perm de la estructura semid ds de un conjunto. Obtiene los valores del argumento buf de la unin semun. IPC_RMID Elimina el conjunto de semforos. GETALL Se usa para obtener los valores de todos los semforos del conjunto. Los valores enteros se almacenan en un array de enteros cortos sin signo, apuntado por el miembro array de la unin. GETNCNT Devuelve el nmero de procesos que esperan recursos. GETPID Retorna el PID del proceso que realiz la ltima llamada semop. GETVAL Devuelve el valor de uno de los semforos del conjunto. GETZCNT Devuelve el nmero de procesos que esperan la disponibilidad del 100% de recurso. SETALL Coloca todos los valores de semforos con una serie de valores contenidos en el miembro array de la unin. SETVAL Coloca el valor de un semforo individual con el miembro val de la unin. El argumento arg representa un ejemplo de tipo semun. Esta unin particular se declara en linux/sem.h como se indica a continuacin: /* argumento para llamadas a semctl */ union semun { int val; /* valor para SETVAL */ struct semid_ds *buf; /* buffer para IPC_STAT e IPC_SET */ ushort *array; /* array para GETALL y SETALL */ struct seminfo *__buf; /* buffer para IPC_INFO */ void *__pad; }; val Se usa con el comando SETVAL, para indicar el valor a poner en el semforo. buf Se usa con los comandos IPC_STAT/IPC_SET. Es como una copia de la estructura de datos interna que tiene el ncleo para los semforos. array Puntero que se usa en los comandos GETALL/SETALL. Debe apuntar a una matriz de nmeros enteros donde se ponen o recuperan valores de los semforos.
24 DE 48 CTEDRA S ISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II
Los dems argumentos, buf y pad, se usan internamente en el ncleo y no son de excesiva utilidad para el programador. Adems son especficos para el sistema operativo Linux y no se encuentran en otras versiones de UNIX. Ya que esta llamada al sistema es de las ms complicadas que hemos visto, pondremos diversos ejemplos para su uso. La siguiente funcin devuelve el valor del semforo indicado. El ltimo argumento de la llamada (la unin), es ignorada con el comando GETVAL por lo que no la incluimos: int obtener_sem_val( int sid, int semnum ){ return( semctl(sid, semnum, GETVAL, 0)); }

Considrese la siguiente funcin, que se debe usar para iniciar un nuevo semforo: void iniciar_semaforo( int sid, int semnum, int initval){ union semun semopts; semopts.val = initval; semctl( sid, semnum, SETVAL, semopts); } Observe que el argumento final de semctl es una copia de la unin, ms que un puntero a l. Mientras nosotros estamos en el tema de la unin como argumento, me permito demostrar una equivocacin ms bien comn cuando usa este llamado de sistema. Recordamos del proyecto msgtool que los comandos IPC_STAT e IPC_SET se usaron para alterar los permisos sobre la cola. Mientras estos comandos se soportan, en la implementacin de un semforo implementacin, su uso es un poco diferente, como las estructuras de datos internas e recuperan y copian desde un miembro de la unin, ms bien que una entidad simple. Puede encontrar el error en este cdigo? /* Los permisos se pasan como texto (ejemplo: "660") */ void changemode(int sid, char *mode){ int rc; struct semid_ds mysemds; /* Obtener valores actuales */ if((rc = semctl(sid, 0, IPC_STAT, semopts)) == -1){ perror("semctl"); exit(1); } printf("Antiguos permisos: %o\n", semopts.buf->sem_perm.mode); /* Cambiar los permisos del semaforo */ sscanf(mode, "%o", &semopts.buf->sem_perm.mode); /* Actualizar estructura de datos interna */ semctl(sid, 0, IPC_SET, semopts); printf("Actualizado...\n"); } El cdigo intenta de hacer una copia local de las estructuras de datos internas estructura para el conjunto, modifica los permisos, e IPC_SET los devuelve al ncleo. Sin embargo, la primera llamada a semctl devuelve EFAULT, o direccin errnea para el ltimo argumento (la unin!). Adems, si no hubiramos verificado los errores de la llamada, nosotros habramos conseguido un fallo de memoria. Por qu?
25 DE 48 CTEDRA S ISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II
Recuerde que los comandos IPC_SET/IPC_STAT usan el miembro buf de la unin, que es un puntero al tipo semid_ds. Los punteros, son punteros, son punteros y son punteros! El miembro buf debe indicar alguna ubicacin vlida de almacenamiento para que nuestra funcin trabaje adecuadamente. Considere esta versin: void cambiamodo(int sid, char *mode){ int rc; struct semid_ds mysemds; /* Obtener valores actuales de estructura interna */ /* !Antes de nada apuntar a nuestra copia local! */ semopts.buf = &mysemds; /* !Intentemos esto de nuevo! */ if((rc = semctl(sid, 0, IPC_STAT, semopts)) == -1){ perror("semctl"); exit(1); } printf("Antiguos permisos: %o\n", semopts.buf->sem_perm.mode); /* Cambiar permisos */ sscanf(mode, "%o", &semopts.buf->sem_perm.mode); /* Actualizar estructura interna */ semctl(sid, 0, IPC_SET, semopts); printf("Actualizado...\n"); }

3- Memoria Compartida Conceptos bsicos La memoria compartida se puede describir mejor como el mapeo (mapping) de un rea (segmento) de memoria que se combinara y compartir por ms de un de proceso. Esta es por mucho la forma ms rpida de IPC, porque no hay intermediacin (es decir, un tubo, una cola de mensaje, etc). En su lugar, la informacin se combina directamente en un segmento de memoria, y en el espacio de direcciones del proceso llamante. Un segmento puede ser creado por un proceso, y consecutivamente escrito a y ledo por cualquier nmero de procesos. Estructuras de datos internas y de usuario Estructuras de datos que mantiene el ncleo para cada segmento de memoria compartida. Estructura shmid_ds del ncleo Como con la cola de mensaje y los conjuntos de semforos, el ncleo mantiene unas estructuras de datos internas especiales para cada segmento compartido de memoria que existe dentro de su espacio de direcciones. Esta estructura es de tipo shmid_ds, y se define en linux/shm.h como se indica a continuacin: /* Por cada segmento de memoria compartida, el ncleo mantiene una estructura como esta */ struct shmid_ds { struct ipc_perm shm_perm; /* permisos operacion */ int shm_segsz; /* tamanyo segmento (bytes) */ time_t shm_atime; /* instante ultimo enlace */ time_t shm_dtime; /* instante ult. desenlace */ time_t shm_ctime; /* instante ultimo cambio */ unsigned short shm_cpid; /* pid del creador */ unsigned short shm_lpid; /* pid del ultimo operador */
26 DE 48 CTEDRA S ISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II
short shm_nattch; /* num. de enlaces act. */ /* lo que sigue es privado */ unsigned short shm_npages; /* tam. segmento (paginas) */ unsigned long *shm_pages; /* array de ptr. a marcos -> SHMMAX struct vm_area_struct *attaches; /* descriptor de enlaces */ };

Las operaciones sobre esta estructura son realizadas por una llamada especial al sistema, y no deberan ser realizadas directamente. Aqu se describen de los campos ms importantes: shm_perm Este es un ejemplo de la estructura ipc_perm, que se define en linux/ipc.h. Esto tiene la informacin de permisos para el segmento, incluyendo los permisos de acceso, e informacin sobre el creador del segmento (uid, etc). shm_segsz Tamao del segmento (en bytes). shm_atime Instante del ltimo enlace al segmento por parte de algn proceso. shm_dtime Instante del ltimo desenlace del segmento por parte de algn proceso. shm_ctime Instante del ltimo cambio de esta estructura (cambio de modo, etc). shm_cpid PID del proceso creador. shm_lpid PID del ltimo proceso que actu sobre el segmento. shm_nattch Nmero de procesos actualmente enlazados con el segmento. LLAMADA AL SISTEMA: shmget() Para crear un nuevo segmento de memoria compartida, o acceder a una existente, tenemos la llamada al sistema shmget(). LLAMADA AL SISTEMA: shmget(); PROTOTIPO: int shmget ( key_t key, int size, int shmflg ); RETORNA: si tuvo exto retorna el identificador (ID) de segmento de memoria compartida -1 existi un error: errno = EINVAL (Tam. de segmento invalido) EEXIST (El segmento existe, no puede crearse) EIDRM (Segmento borrado o marcado para borrarse) ENOENT (No existe el segmento) EACCES (Permiso denegado) ENOMEM (No hay memoria suficiente)

27 DE 48 CTEDRA S ISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II
Es parecido a las correspondientes para las colas de mensaje y conjuntos de semforos. El argumento primero de shmget() es el valor clave (en nuestro caso vuelto por una llamada a ftok()). Este valor clave se compara entonces con valores claves existentes dentro de el ncleo de otros segmentos compartidos de memoria. En esta situacin, las operaciones de apertura o de acceso dependen de los contenidos del argumento shmflg. IPC_CREAT Crea un segmento si no existe ya en el ncleo. IPC_EXCL Al usarlo con IPC CREAT, falla si el segmento ya existe. Si se usa IPC_CREAT sin nada ms, shmget() retornar, bien el identificador del segmento recin creado, o bien el de un segmento que exista ya con la misma clave IPC. Si se aade el comando IPC_EXCL, en caso de existir un segmento con la misma clave, la llamada al sistema fallar, y si no se crear. De nuevo, puede aadirse un modo de acceso en octal, mediante la operacin OR. Preparemos una funcin para crear o localizar segmentos de memoria compartida: int abrir_segmento( key_t clave, int size ){ int shmid; if((shmid = shmget( clave, size, IPC_CREAT | 0660 )) == -1){ return(-1); } return(shmid); } Observe el uso de los permisos explcitos 0660. Esta sencilla funcin retornar un entero con el identificador del segmento, o -1 si existi un error. Los argumentos son, el valor de la clave IPC y el tamao deseado para el segmento (en bytes). Una vez que un proceso obtiene un identificador de segmento vlido, el siguiente paso es mapear (attach) el segmento en su propio espacio de direcciones. LLAMADA AL SISTEMA: shmat() LLAMADA AL SISTEMA : shmat(); PROTOTIPO: int shmat ( int shmid, char *shmaddr, int shmflg); RETORNA: direccin de acceso al segmento, o -1 si hubo error: errno = EINVAL (Identificador o direccin invlidos) ENOMEM (No hay memoria suficiente para ligarse) EACCES (Permiso denegado)

Si el argumento addr es nulo (0), el ncleo intenta encontrar una zona no mapeada. Es la forma recomendada de hacerlo. Se puede incluir una direccin, pero es algo que solo suele usarse para facilitar el uso con hardware propietario o resolver conflictos con otras aplicaciones. La constante SHM_RND puede pasarse con un OR lgico en el argumento shmflg para forzar una direccin pasada para ser pgina (se redondea al tamao ms cercano de pgina). Adems, si se hace OR con la constante SHM_RDONLY y con el argumento de banderas, entonces el segmento compartido de memoria se mapea, pero marcado como slo lectura. Esta llamada es quizs la ms simple de usar. Considere esta funcin de envoltura, que se pasa un identificador IPC vlido para un segmento, y devuelve la direccin a la que el segmento est enlazado:
28 DE 48 CTEDRA S ISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II
char *ligar_segmento( int shmid ){ return(shmat(shmid, 0, 0)); } Una vez que un segmento ha sido adecuadamente adjuntado, y un proceso tiene un puntero al comienzo del segmento, la lectura y la escritura en el segmento se realizan referenciando el puntero. Tenga cuidado de no perder el valor del puntero original! Si esto sucede, no habr ninguna manera de acceder a la base (comienzo) del segmento. LLAMADA AL SISTEMA: shmctl()

LLAMADA AL SISTEMA: shmctl(); PROTOTYPE: int shmctl ( int shmqid, int cmd, struct shmid_ds *buf ); RETURNS: 0 si xito, -1 si error: errno = EACCES (No hay permiso de lectura y cmd es IPC_STAT) EFAULT (Se ha suministrado una direccin invlida para los comandos IPC_SET e IPC_STAT) EIDRM (El segmento fue borrado durante esta operacin) EINVAL (shmqid invlido) EPERM (Se ha intentado, sin permiso de escritura, el comando IPC_SET o IPC_RMID) Los que valores vlidos de comando son: IPC_STAT Obtiene la estructura shmid_ds de un segmento y la almacena en la direccin del argumento buf. IPC_SET Ajusta el valor del miembro ipc_perm de la estructura, tomando el valor del argumento buf. IPC_RMID Marca un segmento para borrarse. El comando IPC_RMID no quita realmente un segmento del ncleo. Ms bien, marca el segmento para eliminacin. La eliminacin real del mismo ocurre cuando el ltimo proceso actualmente adjunto al segmento termina su relacin con l. Por supuesto, si ningn proceso est actualmente asociado al segmento, la eliminacin es inmediata. Para separar adecuadamente un segmento compartido de memoria, un proceso invoca la llamada al sistema shmdt. LLAMADA AL SISTEMA: shmdt() LLAMADA AL SISTEMA: shmdt(); PROTOTIPO: int shmdt ( char *shmaddr ); RETURNS: -1 si error: errno = EINVAL (Dir. de enlace invlida)

29 DE 48 CTEDRA S ISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II
Cuando un segmento compartido de memoria no se necesita ms por un proceso, se debe separar con una llamado al sistema. Como mencionamos antes, esto no es lo mismo que eliminar un segmento desde el ncleo! Despus de separar con xito, el miembro shm_nattch de la estructura shmid_ds se decrementa en uno. Cuando este valor alcanza el cero (0), el ncleo quitara fsicamente el segmento.

30 DE 48 CTEDRA S ISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II
LLAMADAS AL SISTEMA DE LINUX EN ORDEN ALFABTICO: exit - como exit pero con menos acciones (m+c) accept - aceptar conexiones en un socket (m+c!) access - comprobar permisos de usuario en un fichero (m+c) acct - no implementada aun (mc) adjtimex - obtener/ajustar variables de tiempo internas (-c) afs syscall - reservada para el sistema de ficheros Andrew (-) alarm - envi de SIGALRM tras un tiempo especificado (m+c) bdush - vuelca buffers modificados al disco (-c) bind - nombrar un socket para comunicaciones (m!c) break - no implementada aun (-) brk - cambiar el tamao del segmento de datos (mc) chdir - cambiar el directorio de trabajo (m+c) chmod - cambiar permisos en un fichero (m+c) chown - cambiar propietario de un fichero (m+c) chroot - cambiar el directorio raz (mc) clone - ver fork (m-) close - cerrar un fichero (m+c) connect - enlazar dos sockets (m!c) creat - crear un fichero (m+c) create module - reservar espacio para un modulo del ncleo (-) delete module - descargar modulo del ncleo (-) dup - crear un duplicado de un descriptor de fichero (m+c) dup2 - duplicar un descriptor (m+c) execl, execlp, execle, ... - vease execve (m+!c) execve - ejecutar un fichero (m+c) exit - terminar un programa (m+c) fchdir - cambiar directorio de trabajo por referencia () fchmod - vease chmod (mc) fchown - cambiar propietario de un fichero (mc) fclose - cerrar un fichero por referencia (m+!c) fcntl - control de ficheros/descriptores (m+c) ock - cambiar bloqueo de fichero (m!c) fork - crear proceso hijo (m+c) fpathconf - obtener info. de fichero por referencia (m+!c) fread - leer matriz de datos de un fichero (m+!c) fstat - obtener estado del fichero (m+c) fstatfs - obtener estado del sistema de ficheros por referencia (mc) fsync - escribir bloques modificados del fichero a disco (mc) ftime - obtener fecha del fichero, en segundos desde 1970 (m!c) ftruncate - cambiar tamao del fichero (mc) fwrite - escribir matriz de datos binarios a un fichero (m+!c) get kernel syms - obtener tabla de smbolos del kernel o su tamao (-) getdomainname - obtener nombre de dominio del sistema (m!c) getdtablesize - obtener tamao de la tabla de descriptores de fich. (m!c) getegid - obtener id. de grupo efectivo (m+c) geteuid - obtener id. de usuario efectivo (m+c) getgid - obtener id. de grupo real (m+c) getgroups - obtener grupos adicionales (m+c) gethostid - obtener identificador del huesped (m!c) gethostname - obtener nombre del huesped (m!c)
31 DE 48 CTEDRA S ISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II
getitimer - obtener valor de temporizador (mc) getpagesize - obtener tamao de pagina (m-!c) getpeername - obtener direccin remota de un socket (m!c) getpgid - obtener id. del grupo de procesos padre (+c) getpgrp - obtener id. del grupo padre del proceso (m+c) getpid - obtener id. del proceso (pid) (m+c) getppid - obtener id. del proceso padre (m+c) getpriority - obtener prioridades de usuario/grupo/proceso (mc) getrlimit - obtener limites de recursos (mc) getrusage - obtener uso de recursos (m) getsockname - obtener direccin de un socket (m!c) getsockopt - obtener opciones ajustadas en un socket (m!c) gettimeofday - obtener segundos pasados desde 1970 (mc) getuid - obtener id. de usuario real (uid) (m+c) gtty - no implementada aun () idle - hacer candidato a expulsin al disco a un proceso (mc) init module - incluir un modulo cargable (-) ioctl - manipulacin de un dispositivo de caracter (mc) ioperm - ajusta algunos permisos de e/s (m-c) iopl - ajusta permisos de e/s (m-c) ipc - comunicacin entre procesos (-c) kill - enviar una seal a un proceso (m+c) killpg - enviar una seal a un grupo de procesos (mc!) klog - ver syslog (-!) link - crear un enlace bsico a un fichero (m+c) listen - escuchar conexiones en un socket (m!c) llseek - lseek para ficheros grandes (-) lock - no implementada aun () lseek - cambia el puntero de un fichero abierto (m+c) lstat - obtiene estado de un fichero (mc) mkdir - crea un directorio(m+c) mknod - crea un dispositivo (mc) mmap - mapea un fichero en memoria (mc) modify ldt - lee o escribe tabla de descriptores locales (-) mount - montar un sistema de ficheros (mc) mprotect - controla permisos de acceso a una zona de memoria (-) mpx - no implementada aun () msgctl - control de mensajes ipc (m!c) msgget - obtiene un id. de cola de mensajes (m!c) msgrcv - recibe un mensaje ipc (m!c) msgsnd - enva un mensaje ipc (m!c) munmap - quita un fichero de memoria (mc) nice - cambia prioridad del proceso (mc) oldfstat - a extinguir oldlstat - a extinguir oldolduname - a extinguir oldstat - a extinguir olduname - a extinguir open - abrir un fichero (m+c) pathconf - obtener info. de un fichero (m+!c) pause - dormir hasta la llegada de una seal (m+c) personality - cambiar dominio de ejecucin en iBCS (-) phys - no implementada aun (m)
32 DE 48 CTEDRA S ISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II
pipe - crea una tubera (m+c) prof - no implementada aun () profil - perfil de ejecucin (m!c) ptrace - traza proceso hijo (mc) quotactl - no implementada aun () read - lee datos de un fichero (m+c) readv - lee bloques de un fichero (m!c) readdir - lee un directorio (m+c) readlink - obtener contenido de un enlace simblico (mc) reboot - reiniciar o controlar combinacin CTRL-ALT-DEL (-mc) recv - recibir mensaje de socket conectado (m!c) recvfrom - recibir mensaje de socket (m!c) rename - mover/renombrar fichero (m+c) rmdir - borrar directorio vacio (m+c) sbrk - ver brk (mc!) select - dormir hasta actividad en un descriptor de fichero (mc) semctl - control de semforos ipc (m!c) semget - obtener id. de semforo ipc (m!c) semop - operaciones en conjunto de semforos ipc (m!c) send - enviar mensaje a un socket conectado (m!c) sendto - enviar mensaje a un socket (m!c) setdomainname - ajustar dominio del sistema (mc) setfsgid - ajustar id. grupo del sistema de ficheros () setfsuid - ajustar id. usuario del sistema de ficheros () setgid - ajustar id. real de grupo (gid) (m+c) setgroups - ajustar grupos adicionales (mc) sethostid - ajustar identificador de huesped (mc) sethostname - ajustar nombre de huesped (mc) setitimer - ajustar temporizador (mc) setpgid - ajustar id. de grupo padre (m+c) setpgrp - sin efecto (mc!) setpriority - ajustar prioridad de proceso/usuario/grupo (mc) setregid - ajustar id. de grupo real/efectivo (mc) setreuid - ajustar id. de usuario real/efectivo (mc) setrlimit - ajustar limites para los recursos (mc) setsid - crear sesin (+c) setsockopt - cambiar opciones del socket (mc) settimeofday - poner la hora en segundos desde 1970 (mc) setuid - ajustar id. de usuario real (m+c) setup - iniciar dispositivos y montar la raiz (-) sgetmask - ver siggetmask (m) shmat - enganchar memoria a un segm. de memoria compartida (m!c) shmctl - manipulacin de mem. compartida ipc (m!c) shmdt - liberar memoria compartida en un segmento (m!c) shmget - obtener/crear segmento de memoria compartida (m!c) shutdown - desconectar socket (m!c) sigaction - obtener/ajustar manejador de seales (m+c) sigblock - bloquear seales (m!c) siggetmask - obtener seales bloqueadas (!c) signal - poner manejador de seal (mc) sigpause - usar nueva mascara de seales hasta la prxima seal (mc) sigpending - obtener seales bloqueadas pendientes (m+c) sigprocmask - obtener/ajustar mascara de bloqueos de seales (+c)
33 DE 48 CTEDRA S ISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II
sigreturn - no usada aun () sigsetmask - ajustar mascara de bloqueos de seales (c!) sigsuspend - reemplaza a sigpause (m+c) sigvec - ver sigaction (m!) socket - crea un extremo de comunicacin para socket (m!c) socketcall - llamada general de sockets (-) socketpair - crea dos sockets conectados (m!c) ssetmask - ver sigsetmask (m) stat - obtener estado del fichero (m+c) statfs - obtener estado del sistema de ficheros (mc) stime - obtener segundos desde 1.1.1970 (mc) stty - no implementada aun () swapo_ - detener el intercambio con un dispositivo o fichero (m-c) swapon - iniciar el intercambio con un dispositivo o fichero (m-c) symlink - crear un enlace simblico (m+c) sync - volcar bloques modificados a disco (mc) syscall - ejecutar llamada al sistema (-!c) sysconf - obtener valor de una variable del sistema (m+!c) sysfs - obtener info. sobre sistemas de ficheros usados () sysinfo - obtener info. sobre el sistema (m-) syslog - manipulacin del registro (m-c) system - ejecutar un comando de shell (m!c) time - obtener segundos desde 1.1.1970 (m+c) times - obtener tiempos del proceso (m+c) truncate - cambiar tamao de un fichero (mc) ulimit - obtener/ajustar limites de fichero (c!) umask - ajustar mascara de creacin de ficheros (m+c) umount - desmontar un sistema de ficheros (mc) uname - obtener info. del sistema (m+c) unlink - borrar un fichero no bloqueado (m+c) uselib - usar librera compartida (m-c) ustat - no implementada anu (c) utime - modificar informacin de acceso de un nodo-i (m+c) utimes - ver utime (m!c) vfork - er fork (m!c) vhangup - colgar virtualmente el terminal actual (m-c) vm86 - entrar en modo vm86 (m-c) wait - esperar terminacin de proceso (m+!c) wait3 - espera terminacin de un proceso (bsd) (m!c) wait4 - espera terminacin de un proceso (bsd) (mc) waitpid - espera terminacin de un proceso (m+c) write - escribir datos a un fichero (m+c) writev - escribir bloques de datos a un fichero (m!c) Referencia: (m) hay pgina de manual. (+) cumple norma POSIX. (-) Especfica de Linux. (c) de libc. (!) no es solo una llamada al sistema. Usa otras

34 DE 48 CTEDRA S ISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II
Bibliografa: CARRETERO PREZ J., ANASAGASTI PEDRO DE MIGUEL, GARCA CARBALLERIRA F., PREZ COSTOYA F. Sistemas Operativos, Una visin aplicada. Editorial McGraw Hill. Espaa 2001. ISBN 84-481-3001-4.Proyecto LUCas Gua de programacin de Linux (GULP).Documentacin Oficial de Linux Pginas Man.MARK MITCHELL, JEFFREY OLDHAM, ALEX SAMUEL Advanced Linux Programming First Edition ISBN 07357-1043-0 New Riders Publishing United State of America, June, 2001.-

35 DE 48 CTEDRA S ISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II
APNDICE: Descriptor de archivo: Antes de que un archivo pueda leerse o escribir en l, debe abrirse, momento en el cual se verifican los permisos. Si se permite el acceso, el sistema regresa un entero pequeo llamado descriptor de archivo o entrada de manejo para usarlos en las operaciones subsecuentes. Si se prohbe el acceso, se regresa un cdigo de error. Descriptor de archivo en UNIX: Cuando se abre un archivo en UNIX, se devuelve un descriptor de archivo, que se usa a partir de ese momento para identificar al archivo en otras llamadas al sistema. Esto descriptores son nmeros enteros de 0 a n y son especficos para cada proceso. Cada proceso tiene su tabla de descriptores de archivo (tda), desde la que se apunta a los descriptores internos de los archivos. El descriptor de archivo fd indica el lugar en la tabla, que se rellena de forma ordenada, de manera que siempre se ocupa la primera posicin libre de la misma. cuando se realiza una operacin open, el sistema de archivos busca desde la posicin 0 hasta que encuentra una posicin libre, siendo esa la ocupada. Cuando se cierra un archivo (close), se libera la entrada correspondiente. Cuando se ejecuta una llamada fork se duplica la PCB del proceso. cuando se cambia la imagen de un proceso con la llamada exec, uno de los elementos de la PCB que se conserva es la tabal de descriptores de archivos. Pro lo tanto, basta con que un proceso coloque adecuadamente los descriptores estndar y que luego invoque la ejecucin del mencionado programa, para que ste utilice los archivo previamente seleccionados. ipc - Mecanismos de comunicacin entre procesos del System V (Pginas man) SINOPSIS # include <sys/types.h> # include <sys/ipc.h> # include <sys/msg.h> # include <sys/sem.h> # include <sys/shm.h> DESCRIPCIN Esta pgina del manual hace referencia a la implementacin en Linux de los mecanismos de comunicacin entre procesos del System V (IPC, Inter Process Communication): colas de mensajes, conjuntos de semforos y segmentos de memoria compartida. En la siguiente descripcin, la palabra recurso se refiere a la instancia de uno de dichos mecanismos. Permisos de Acceso a Recursos Para cada recurso el sistema utiliza una estructura de datos comn de tipo struct ipc_perm para almacenar informacin necesaria para determinar permisos al ejecutar una operacin ipc. La estructura ipc_perm, definida en el fichero de cabecera <sys/ipc.h> incluye los siguientes miembros: ushort cuid; /* id del usuario creador */ ushort cgid; /* id de grupo del usuario creador */ ushort uid; /* id del usuario dueo */ ushort gid; /* id de grupo del usuario dueo */ ushort mode; /* permisos de lectura/escritura */ El miembro mode de la estructura ipc_perm define, con los 9 bits ms bajos, los persmisos de acceso al recurso para cualquier proceso que realice una llamada ipc al sistema. Los permisos se interpretan de la siguiente manera: 0400 Lectura para el usuario. 0200 Escritura para el usuario. 0040 Lectura para el grupo.
36 DE 48 CTEDRA S ISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II
0020 Escritura para el grupo. 0004 Lectura para otros. 0002 Escritura para otros. Los bits 0100, 0010 y 0001 (bits de ejecucin) no se utilizan. Adems, "write" (permiso de escritura) se interpreta efectivamente como "alter" (permiso de alteracin) para un conjunto de semforos. El mismo fichero de cabecera del sistema tambin define las siguientes constantes simblicas: IPC_CREAT Crea la entrada si la clave no existe. IPC_EXCL Falla si la clave existe. IPC_NOWAIT Devuelve error si la peticin debe esperar. IPC_PRIVATE Clave privada. IPC_RMID Elimina el recurso. IPC_SET Establece opciones del recurso. IPC_STAT Obtiene opciones del recurso. Ntese que IPC_PRIVATE es de tipo key_t, mientras que las otras constantes simblicas son campos sealizadores que pueden combinarse usando operaciones 'or' en una variable de tipo int. Colas de Mensajes Una cola de mensajes se identifica unvocamente usando un nmero entero positivo (llamado msqid) y tiene una estructura de datos asociada de tipo struct msquid_ds, definida en <sys/msg.h>. La estructura contiene los siguientes miembros: struct ipc_perm msg_perm; ushort msg_qnum; /* nmero de mensajes en cola */ ushort msg_qbytes; /* mximo nmero de bytes en cola */ ushort msg_lspid; /* pid ltima llamada a msgsnd */ ushort msg_lrpid; /* pid ltima llamada a msgrcv */ time_t msg_stime; /* hora ltima llamada a msgsnd */ time_t msg_rtime; /* hora ltima llamada a msgrcv */ time_t msg_ctime; /* hora del ltimo cambio */ msg_perm ipc_perm estructura que especifica los permisos de acceso a la cola de mensajes.

msg_qnum Nmero actual de mensajes en la cola de mensajes. msg_qbytes Mximo nmero de bytes permitidos en el texto del mensaje en la cola de mensajes. msg_lspid ID del proceso que ejecut la ltima llamada a msgsnd. msg_lrpid ID del proceso que ejecut la ltima llamada a msgrcv. msg_stime Hora de la ltima llamada a msgsnd. msg_rtime Hora de la ltima llamada a msgrcv. msg_ctime Hora de la ltima llamada que cambi un miembro de la estructura msqid_ds.

37 DE 48 CTEDRA S ISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II
Conjuntos de Semforos Un conjunto de semforos se identifica unvocamente usando un nmero entero positivo (llamado semid) y tiene asociada la siguiente estructura de datos de tipo struct semid_ds, definida en <sys/sem.h>. La estructura contiene los siguientes campos: struct ipc_perm sem_perm; time_t sem_otime; /* hora de la ltima operacin */ time_t sem_ctime; /* hora del ltimo cambio */ ushort sem_nsems; /* cantidad de semforos en el conjunto */ sem_perm ipc_perm estructura que especifica los permisos de acceso al conjunto de semforos. sem_otime Hora de la ltima llamada a semop. sem_ctime Hora de la ltima llamada a semctl que cambi un miembro de la estructura anterior o un miembro de algn semforo del conjunto. sem_nsems Cantidad de semforos en el conjunto. Cada semforo en el conjunto se accede usando un entero positivo en el rango 0 a sem_nsems-1. Un semforo es una estructura de datos de tipo struct sem que contiene los siguientes miembros: ushort semval; /* valor del semforo */ short sempid; /* pid para la ltima operacin */ ushort semncnt; /* cantidad de semval esperando a ser incrementados */ ushort semzcnt; /* cantidad de semforos esperando cuyo semval = 0 */ semval Valor del semforo: un entero no negativo. sempid ID del ltimo proceso que realiz una operacin de semforo sobre este semforo. semncnt Cantidad de procesos suspendidos esperando que semval aumente. semznt Cantidad de procesos suspendidos esperando que semval se haga cero. Segmentos de Memoria Compartida Un segmento de memoria compartida se identifica unvocamente mediante un nmero entero positivo (llamado shmid) y tiene una estructura de datos asociada de tipo struct shmid_ds, definida en <sys/shm.h>. La estructura contiene los siguiente miembros: struct ipc_perm shm_perm; int shm_segsz; /* Tamao del segmento */ ushort shm_cpid; /* pid del creador */ ushort shm_lpid; /* pid de la ltima operacin */ short shm_nattch; /* cantidad actual de conexiones */ time_t shm_atime; /* hora de la ltima conexion */ time_t shm_dtime; /* hora ltima desconexin */ time_t shm_ctime; /* hora del ltimo cambio */ shm_perm ipc_perm estructura que especifica los permisos de acceso al segmento de memoria compartida.

shm_segsz Tamao en bytes del segmento de memoria compartida. shm_cpid shm_lpid ID del proceso que creo el segmento de memoria compartida. ID del ltimo proceso que ejecut una llamada del sistema shmat o shmdt.
38 DE 48 CTEDRA S ISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II
shm_nattch Cantidad de conexiones activas actualmente para este segmento de memoria compartida. shm_atime Hora de la ltima llamada a shmat. shm_dtime Hora de la ltima llamada a shmdt. shm_ctime Hora de la ltima llamada a shmctl que cambi shmid_ds. VASE TAMBIN ftok(3), msgctl(2), msgget(2), msgrcv(2), msgsnd(2), semctl(2), semget(2), semop(2), shmat(2), shmctl(2), shmget(2), shmdt (2).

NOMBRE semctl - operaciones de control de semforos SINOPSIS #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED) /* la union semun se define al incluir <sys/sem.h> */ #else /* segn X/OPEN tenemos que definirla nosostros mismos */ union semun { int val; /* valor para SETVAL */ struct semid_ds *buf; /* buffer para IPC_STAT, IPC_SET */ unsigned short int *array; /* array para GETALL, SETALL */ struct seminfo *__buf; /* buffer para IPC_INFO */ }; #endif int semctl (int semid, int semnun, int cmd, union semun arg) DESCRIPCIN La funcin realiza la operacin de control especificada por cmd en el conjunto de semforos (o en el semforo semnum-avo del grupo) identificado por semid. El primer semforo del conjunto est indicado por el valor 0 para semnum. Valores vlidos para cmd son: IPC_STAT Copiar informacin de la estructura de datos del conjunto de semforos en la estructura apuntada por arg.buf. El argumento semnum es ignorado. El proceso que realiza la llamada debe tener privilegios de acceso de lectura en el conjunto de semforos.

39 DE 48 CTEDRA S ISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II
IPC_SET Escribir los valores de algunos miembros de la estructura semid_ds apuntada por arg.buf a la estructura de datos del conjunto de semforos, actualizando tambin su miembro sem_ctime. Los miembros de la estructura provista por el usuario struct semid_ds a los que apunta arg.buf son sem_perm.uid sem_perm.gid sem_perm.mode

/* solo los 9 bits ms bajos */

El ID de usuario efectivo del proceso que realiza la llamada debe ser o de super-usuario, o el del creador o propietario del conjunto de semforos. El argumento semnum es ignorado. IPC_RMID Borrar inmediatamente el conjunto de semforos y sus estructuras de datos, despertando todos los procesos en espera (devuelve un error, y errno puesto a EIDRM). El ID de usuario efectivo del proceso que realiza la llamada debe ser o de super-usuario, o el del creador o propietario del conjunto de semforos. El argumento semnum es ignorado. GETALL Devuelve semval para todos los semforos del conjunto, en arg.array. El argumento semnum es ignorado. El proceso que realiza la llamada ha de tener privilegios de lectura en el conjunto de semforos. GETNCNT La llamada al sistema devuelve el valor de semncnt para el semnum-avo semforo del conjunto (p.ej. el nmero de procesos esperando que aumente semval para el semnum-avo semforo del conjunto). El proceso que realiza la llamada ha de tener privilegios de lectura en el conjunto de semforos. GETPID La llamada al sistema devuelve el valor de sempid para el semnum-avo semforo del conjunto (p.ej. el pid del proceso que ejecut la ltima llamada semop para el semnum-avo semforo del conjunto). El proceso que realiza la llamada ha de tener privilegios de lectura en el conjunto de semforos. GETVAL La llamada al sistema devuelve el valor de semval para el semnum-avo semforo del conjunto. El proceso que realiza la llamada ha de tener privilegios de lectura en el conjunto de semforos. GETZCNT La llamada al sistema devuelve el valor de semzcnt para el semnum-avo semforo del conjunto (p.ej. el nmero de procesos que esperan que semval del semnum-avo semforo del conjunto se ponga a 0). El proceso que realiza la llamada ha de tener privilegios de lectura en el conjunto de semforos. SETALL Poner semval para todos los semforos del conjunto usando arg.array, actualizando tambin el miembro sem_ctime de la estructura semid_ds asociada al conjunto. Los registros de anulacin son limpiados, para los semforos cambiados, en todos los procesos. Los procesos que estn durmiendo en la cola de espera son despertados si algn semval se pone a 0 o se incrementa. El argumento semnum es ignorado. El proceso que realiza la llamada ha de tener privilegios de modificacin en el conjunto de semforos. SETVAL Poner el valor de semval a arg.val para el semnum-avo semforo del conjunto, actualizando tambin el miembro sem_ctime de la estructura semid_ds asociada al conjunto. El registro de anulacin es limpiado, para el semforo alterado, en todos los procesos. Los procesos que estn durmiendo en la cola de espera son despertados si semval se pone a 0 o se incrementa. El proceso que realiza la llamada ha de tener privilegios de escritura en el conjunto de semforos. VALOR DEVUELTO Si falla, la llamada al sistema devuelve -1, mientras errno indica el error. De otro modo, la llamada al sistema devuelve un valor no negativo, dependiendo de cmd como sigue: GETNCNT el valor de semncnt. GETPID el valor de sempid. GETVAL el valor de semval.
40 DE 48 CTEDRA S ISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II
GETZCNT el valor de semzcnt. ERRORES EACCESS El proceso que realiza la llamada no tiene los permisos necesarios para ejecutar cmd. EFAULT La direccin a la que apunta arg.buf o arg.array no es accesible. EIDRM El conjunto de semforos se borr. EINVAL Valor no vlido para cmd o semid. EPERM El argumento cmd tiene valor IPC_SET o IPC_RMID pero el user-ID del proceso que realiza la llamada no tiene suficientes privilegios para ejecutar el comando. ERANGE El argumento cmd tiene el valor SETALL o SETVAL y el valor al que ha de ser puesto semval (para algn semforo del conjunto) es menor que 0 o mayor que el valor SEMVMX de la implementacin. NOTAS Las llamadas de control IPC_INFO, SEM_STAT y SEM_INFO son utilizadas por el programa ipcs(8) para proveer informacin sobre recursos asignados. En el futuro pueden ser modificadas segn se necesite, o llevadas al interfaz del sis

NOMBRE semget - obtiene el identificador de un conjunto de semforos SINOPSIS # include <sys/types.h> # include <sys/ipc.h> # include <sys/sem.h> int semget ( key_t key, int nsems, int semflg ) DESCRIPCIN La funcin devuelve el identificador del conjunto de semforos asociado al valor del argumento key. Un nuevo conjunto de nsems semforos se crea si key tiene el valor IPC_PRIVATE, o si key no vale IPC_PRIVATE, no hay un conjunto de semforos asociado a key, y el bit IPC_CREAT vale 1 en semflg (p.ej. semflg & IPC_CREAT es distinto de cero). La presencia en semflg de los campos IPC_CREAT e IPC_EXCL tiene el mismo papel, con respecto a la existencia del conjunto de semforos, que la presencia de O_CREAT y O_EXCL en el argumento mode de la llamada del sistema open(2): p.ej., la funcin semget falla si semflg tiene a 1 tanto IPC_CREAT como IPC_EXCL y ya existe un conjunto de semforos para key. Acerca de la creacin, los 9 bits bajos del argumento semflg definen los permisos de acceso (para el propietario, grupo y otros) al conjunto de semforos en el mismo formato, y con el mismo significado, que para el parmetro de permisos de acceso en las llamadas al sistema open(2) o creat(2) (aunque los permisos de ejecucin no son usados por el sistema, y los de escritura, para un conjunto de semforos, efectivamente significa permisos de modificacin).

41 DE 48 CTEDRA S ISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II
Adems, durante la creacin, la llamada al sistema inicializa la estructura de datos semid_ds del conjunto semforos del sistema, como sigue: Se pone el ID de usuario efectivo del proceso que realiza la llamada en sem_perm.cuid y sem_perm.uid Se pone el ID de grupo efectivo del proceso que realiza la llamada en sem_perm.cgid y sem_perm.gid Los 9 bits ms bajos de sem_perm.mode se ponen como los 9 bits ms bajos de semflg. Se pone el valor de nsems en sem_nsems. sem_otime se pone a 0. Se pone la hora actual en sem_ctime. El argumento nsems puede ser 0 (un comodn o valor sin importancia) cuando la llamada del sistema no es de creacin. En otro caso nsems debe ser mayor que 0 y menor o igual que el nmero mximo de semforos por semid, (SEMMSL). Si el conjunto de semforos ya existe, los permisos de acceso son verificados, y se hace una comprobacin para ver si est marcado para ser destruido. VALOR REGRESADO Si hubo xito, el valor devuelto ser el identificador del conjunto de semforos (un entero positivo), de otro modo, se devuelve -1 con errno indicando el error. ERRORES EACCES Existe un conjunto de semforos para key, pero el proceso que realiza la llamada no tiene permisos de acceso al conjunto. EEXIST Existe un conjunto de semforos para key y semflg tiene a 1 tanto IPC_CREAT como IPC_EXCL. EIDRM El conjunto de semforos est marcado para ser borrado. ENOENT No existe ningn conjunto de semforos para key y semflg no tiene a 1 IPC_CREAT. ENOMEM Se ha de crear un conjunto de semforos, pero el sistema no tiene suficiente memoria para la nueva estructura de datos. ENOSPC Se ha de crear un conjunto de semforos, pero el lmite del sistema para el nmero mximo de conjuntos de semforos (SEMMNI), o el nmero de semforos mximo del sistema (SEMMNS), sera excedido. NOTAS IPC_PRIVATE no es un campo bandera (flag), sino que es de tipo key_t Si este valor especial es usado para key, la llamada del sistema ignora todo excepto los 9 bits ms bajos de semflg y crea un nuevo conjunto de semforos (si hay xito).
42 DE 48 CTEDRA S ISTEMAS OPERATIVOS II 2006

de

SISTEMAS OPERATIVOS II
Los siguientes son lmites de los recursos de los conjuntos de semforos que afectan a la llamada semget : SEMMNI Mximo total de conjuntos de semforos para el sistema: depende de la poltica. SEMMSL Mximo de semforos por semid: depende de la implementacin (500 normalmente). SEMMNS Mximo total de semforos para el sistema: depende de la poltica. Valores mayores que SEMMSL * SEMMNI lo hacen irrelevante. FALLOS El uso de IPC_PRIVATE no inhibe el acceso de los dems procesos al conjunto de semforos asignado. Al igual que pasa con los ficheros, no hay una manera intrnseca para que un proceso se a segure el acceso exclusivo a un conjunto de semforos. Tener a 1 tanto IPC_CREAT como IPC_EXCL en semflg solo asegura (si hay xito) la creacin de un nuevo conjunto de semforos, no implica acceso exclusivo a dicho conjunto. La estructura de datos asociada con cada semforo del conjunto no es inicializada por la llamada del sistema. Para inicializar estas estructuras de datos, se ha de ejecutar la subsiguiente llamada a semctl(2) para realizar un comando SETVAL o SETALL en el conjunto de semforos. CONFORME A SVr4, SVID. SVr4 documenta condiciones de error adicionales EINVAL, EFBIG, E2BIG, EAGAIN, ERANGE, EFAULT. VASE TAMBIN ftok(3), ipc(5), semctl(2), semop(2)

NOMBRE semop - operaciones con semforos SINTAXIS # include <sys/types.h> # include <sys/ipc.h> # include <sys/sem.h> int semop ( int semid, struct sembuf *sops, unsigned nsops ) DESCRIPCIN Esta funcin ejecuta operaciones en los miembros seleccionados del semforo indicado por semid. Cada uno de los nsops elementos en el array apuntado por sops especifica una operacin a ser realizada en un semforo por struct sembuf incluyendo los siguientes miembros: short sem_num; /* numero de semforo: 0 = primero */ short sem_op; /* operacin sobre el semforo */ short sem_flg; /* banderas (indicadores/parametros) de la operacin */

43 DE 48 CTEDRA S ISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II
Banderas reconocidas en sem_flg son IPC_NOWAIT y SEM_UNDO. deshecha cuando el proceso finalice. Si una operacin ejecuta SEM_UNDO, sera

La semntica de la llamada al sistema asegura que la operacin er ejecutada si y solo si todas ellas pueden ser ejecutadas. Cada operacin es ejecutada en el semforo numero sem_num donde el primer semforo del conjunto es el semforo 0 - y es uno entre los siguientes tres. Si sem_op es un entero positivo, la operacin aade este valor a semval. Sin embargo, si SEM_UNDO es invocado para esta operacin , el sistema actualiza el contador del proceso (para operaciones "undo") para este semforo. La operacin siempre se ejecuta, por lo que no puede haber ningn proceso durmiendo. El proceso que invoca debe tener los permisos modificados en el conjunto de semforos. Si sem_op es cero, el proceso debe tener permiso de lectura en el semforo. Si semval es cero, la operacin se ejecuta. Por otra parte, si IPC_NOWAIT es invocado en sem_flg, la llamada al sistema falla (deshaciendo todas las acciones anteriores ejecutadas) con la variable errno fijada a EAGAIN. En otro caso semzcnt es incremetada en uno y el proceso duerme hasta que algo de lo siguiente ocurra:

semval es 0, instante en el que el valor de semzcnt es decrementeado. El semforo es eliminado: la llamada al sistema falla con errno fijada a EIDRM. El proceso que lo invoca recibe una seal que debe ser atendida: el valor de semzcnt es decrementado y la llamada al sistema falla con errno fijada a EINTR. Si sem_op es menor que cero, el proceso debe tener los permisos de modificacin sobre el semforo. Si semval es mayor que o igual que el valor absoluto de sem_op, el valor absoluto de sem_op es restado a semval. Por otra parte, si SEM_UNDO es invocado para esta operacin, el sistema actualiza el contador "undo" del pro ceso para este semforo. Entonces la operacin se ejecuta. En otro caso, si IPC_NOWAIT es invocado en sem_flg, la llamada al sistema falla (deshaciendo todas las acciones anteriores ejecutadas) con errno fijado a EAGAIN. En otro caso semncnt es incrementado en uno y el proceso duerme hasta que ocurra: sea mayor o igual que el valor absoluto de sem_op, en cuyo instante el valor de semncnt es decrementado, el valor absoluto de sem_op es restado de semval y, si SEM_UNDO es invocado para esta operacin , el sistema actualiza el contador "undo" del proceso para este semforo. El semforo es eliminado del sistema: la llamada al sistema falla con errno fijado a EIDRM. El proceso invocador recibe una seal que tiene que capturar: el valor de semncnt es decrementado y la llamada al sistema falla con errno fijado a EINTR. En caso de que haya funcionado, el miembro sempid de la estructura sem para cada semforo especificado en el array apuntado por sops es fijado al identificador del proceso del proceso que la invoca. De otra forma sem_otime y sem_ctime son fijados a la hora actual. VALOR DEVUELTO Si todo ha sido correcto la llamada al sistema devuelve 0, en otro caso devuelve -1 con errno indicando el error. ERRORES E2BIG
44 DE 48 CTEDRA S ISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II
El argumento nsops es mayor que SEMOPM, el numero mximo de operaciones permitidas por llamada del sistema. EACCES El proceso invocador no tiene permisos de acceso al semforo como se requiere por una de las operaciones especificadas. EAGAIN Una operacin no puede ser ejecutada y IPC_NOWAIT ha sido invocada en su sem_flg. EFAULT La direccin apuntada por sops no es accesible. EFBIG Para algunas operaciones el valor de sem_num es menor que 0 o mayor o igual que el numero de semforos en el conjunto. EIDRM El conjunto de semforos ha sido eliminado. EINTR Durmiento en una cola de espera, el proceso recibio una seal que debe ser capturada. EINVAL Este conjunto de semforos no existe, o semid es menor que cero, o nsops tiene un valor no-positivo. ENOMEM El sem_flg de alguna operacin invoco SEM_UNDO y el sistema no tiene suficiente memoria para alojar la estructura "undo". ERANGE Para alguna operacin semop+semval es mayor que SEMVMX, el valor mximo dependiente de la implementacin para semval. ANUNCIA La estructura sem_undo de un proceso no es heredada por sus hijos en la ejecucin de fork(2) Son, en cambio, heredadas por el proceso sustituto resultante de la ejecucin de execve(2) Los siguientes valores son limites en el conjunto de recursos de los semforos que afecta a semop: SEMOPM Numero mximo de operaciones permitidas para una llamada semop, dependiente de la implementacin. SEMVMX Valor mximo permitido para semval: dependiente de la implementacin (32767).

La implementacin no contiene lmites intrnsecos para ajustar el valor mximo de la salida (SEMAEM), el numero mximo de estructuras "undo" que el sistema permite (SEMMNU) y mximo numero de entradas "undo" por proceso para los parametros del sistema. FALLOS El sistema mantiene una estructura sem_undo por p roceso para cada semforo modificado por el proceso con parmetro "undo". Estas estructuras estn vacas a la terminacin de un proceso. Una causa de insatisfaccin con el mecanismo "undo" es que no es compatible con la nocin de tener un conjunto atmico de operaciones en un vector
45 DE 48 CTEDRA S ISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II
de semforos. La llamada "undo" para un vector y cada semforo en este deben ser acumuladas en varias llamadas semopt Debe pasar un proceso al estado dormido cuando ha finalizado, o debe deshacer todas las operaciones realizadas con el parmetro ? IPC_NOWAIT Actualmente estas operaciones "undo" que se invocan son ejecutadas inmediatamente, y aquellas querequieren una espera son ignoradas en silencio. Luego el uso correcto del "undo" esta garantizado solo con semforos de tipo pri vado. COMPATIBLE CON SVr4, SVID. SVr4 documenta las condiciones de error adicionales EINVAL, EFBIG, ENOSPC. VASE TAMBIN ipc(5), semctl(2), semget(2) NOMBRE errno - nmero del ltimo error SINOPSIS #include <errno.h> extern int errno; DESCRIPCIN Algunas llamadas al sistema (y algunas funciones de biblioteca) dan un valor al entero errno para indicar qu ha ido mal. Su valor slo es significativo cuando la llamada devolvi un error (usualmente -1) y cuando una funcin de biblioteca que la acabe bien tenga permitido cambiar errno. Algunas veces, cuando una funcin tambin puede devolver -1 como valor vlido, se debe poner errno a cero antes de la llamada, para poder detectar posibles errores. errno se define en el estndar ISO de C como un lvalor (valor de lado izquierdo) modificable de tipo int y no se debe declarar de forma explcita; errno puede ser una macro. errno es "local en hilo"; asignarle un valor en un hilo no afecta al valor que tenga en ningn otro hilo. Los nmeros de error vlidos son todos no cero; ninguna funcin de biblioteca asigna nunca un valor cero a errno. Todos los nombres de error especificados por POSIX.1 deben tener valores distintos. POSIX.1 (edicin de 1996) lista los siguientes nombres de error simblicos. De stos, EDOM y ERANGE existen en el estndar ISO de C. La enmienda 1 del ISO C define el nmero de error adicional EILSEQ para codificar los errores en mltiples bytes o caracteres extendidos. E2BIG Lista de argumentos demasiado larga EACCES Permiso denegado EAGAIN Recurso temporalmente no disponible EBADF Descriptor de fichero incorrecto EBADMSG Mensaje incorrecto EBUSY Recurso ocupado ECANCELED Operacin cancelada

46 DE 48 CTEDRA S ISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II
ECHILD No hay procesos hijos EDEADLK Interbloqueo de recurso evitado EDOM Error de dominio EEXIST El fichero existe EFAULT Direccin incorrecta EFBIG Fichero demasiado grande EINPROGRESS Operacin en progreso EINTR Llamada a funcin interrumpida EINVAL Argumento invlido EIO Error de Entrada/Salida

EISDIR Es un directorio EMFILE Demasiados ficheros abiertos EMLINK Demasiados enlaces EMSGSIZE Longitud de buffer de mensaje inapropiada ENAMETOOLONG Nombre de fichero demasiado largo ENFILE Demasiados ficheros abiertos en el sistema ENODEV No existe tal dispositivo ENOENT No existe ese fichero o directorio ENOEXEC Error en el formato del ejecutable ENOLCK No hay bloqueos disponibles ENOMEM No hay bastante espacio ENOSPC No queda espacio en el dispositivo ENOSYS Funcin no implementada ENOTDIR No es un directorio ENOTEMPTY El directorio no est vaco ENOTSUP Operacin no soportada ENOTTY Operacin de control de E/S inapropiada
47 DE 48 CTEDRA S ISTEMAS OPERATIVOS II 2006

SISTEMAS OPERATIVOS II
ENXIO No existe tal dispositivo o direccin EPERM Operacin no permitida EPIPE Interconexin rota ERANGE Resultado demasiado grande EROFS Sistema de ficheros de slo lectura ESPIPE Posicionamiento invlido ESRCH No existe tal proceso ETIMEDOUT La operacin ha excedido su plazo de tiempo EXDEV Enlace inapropiado Otras implementaciones de Unix devuelven muchos otros tipos de error. System V devuelve ETXTBSY (fichero de cdigo ocupado) si se intenta ejecutar una llamada exec() sobre un fichero que actualmente est abierto para escritura. Linux tambin devuelve este error si se intenta tener un fichero tanto asociado en memoria con VM_DENYWRITE como abierto para escritura.

NOMBRE strerror - devuelve una cadena de caracteres describiendo un cdigo de error SINOPSIS #include <string.h> char *strerror(int errnum); DESCRIPCIN La funcin strerror() devuelve una cadena de caracteres que describe el cdigo de error pasado en el argumento errnum. La cadena slo puede ser usada hasta la siguiente llamada a strerror(). VALOR DEVUELTO La funcin strerror() devuelve la cadena apropiada que describe el error, o un mensaje de error desconocido si el cdigo de error es invlido. CONFORME A SVID 3, POSIX, BSD 4.3, ISO 9899

48 DE 48 CTEDRA S ISTEMAS OPERATIVOS II 2006

También podría gustarte