|
|
Tema 6. Gestión de Procesos e Hilos. |
1. EJECUCIÓN DE PROGRAMAS MEDIANTE EXECExisten una serie de funciones para ejecutar programas, las cuales cargan un programa en la zona de la memoria del proceso que ejecuta la llamada, es decir un programa viejo es sustituido por otro nuevo y nunca volveremos a el para proseguir su ejecución ya que es el programa nuevo el que pasa a ejecutarse. La declaración de exec es la siguiente: Int execl (char *path, char *arg0,... char *argn, (char *)0);Int execv (char *path, char *argv[ ]); Int execle(char *path, char *arg0,... char *argn, (char *)0, char *envp[ ]); Int execve(char *path, char *argv[ ], char *envp[ ]); Int execlp(char *file, char *argv[ ], char *argn, (char *)0); Int execvp(char *file, char *argv[ ]); Path: ruta del fichero ordinario ejecutable. File: nombre del fichero ejecutable. Arg0 y argn: son punteros a cadenas de caracteres que constituyen una lista de argumentos que se le pasa al nuevo programa. Argv: array de punteros a cadenas de caracteres. Envp: array de punteros a cadenas de caracteres que constituye el entorno en el que se ejecutara el nuevo programa. Si exec no se ejecuta bien nos devolverá -1 y en errno estará el código del tipo de error que se ha producido. La estructura de un fichero ejecutable consta de:
2. CREACIÓN DE PROCESOS (FORK)El proceso que invoca a fork se le llama proceso padre mientras que al proceso creado se le llama proceso hijo. La declaración es la siguiente: #include <sys/types.h>pid_t fork (); La llamada a fork hace que el proceso actual se duplique. A la salida de fork, los dos procesos tienen una copia idéntica del contexto de nivel de usuario excepto el valor de pid, que para el proceso padre toma el valor del PID del proceso hijo, mientras que para el proceso hijo toma el valor 0. El único proceso que no se crea con la llamada a fork es el proceso 0 creado por el núcleo del sistema. Si fork falla nos devolverá -1. Cuando realizamos una llamada a fork, el núcleo del sistema realiza las siguientes operaciones: Buscara una entrada libre en la tabla de procesos y la reserva para el proceso hijo. Asigna un PID al proceso hijo, el cual es invariable y único durante toda la vida del proceso y además constituirá la clave para poder controlarlo desde otros procesos. Realiza una copia del contexto del nivel de usuario del proceso padre para el proceso hijo. También se copiaran las tablas de control de ficheros locales del proceso padre al proceso hijo. Vuelve al proceso padre el PID del proceso hijo y el proceso hijo le devuelve el valor 0. 3. TERMINACIÓN DE PROCESOS(EXIT Y WAIT)La declaración de exit es la siguiente: #include <stdlib.h>void exit (int status); Esta llamada termina la ejecución de un proceso y le devuelve el valor de status al sistema. Para consultarlo podemos utilizar la variable entorno?. Si efectuamos el retorno sin devolver ningún valor en concreto, el resultado devuelto al sistema estará indefinido. Las consecuencias de exit son:
La declaración de wait es la siguiente: #include <sys/types.h>#include <sys/wait.h> pid_t wait (int *stat_loc); Esta llamada suspende la ejecución del proceso que la invoca hasta que alguno de los procesos hijos termina. Puede ocurrir que algún proceso hijo termine de forma anormal, exigiendo unas macros que muestran la terminación del proceso:
Si durante la llamada a wait se produce algún error nos devolverá -1. 4. INFORMACIÓN SOBRE PROCESOSIDENTIFICADORES DE PROCESOTodos los procesos tienen dos números, el identificador de proceso que es el PID y el identificador del proceso padre que es el PPID que a diferencia del PID este puede variar. Esto ocurre cuando el proceso padre muere y el PPID pasa al proceso hijo poniéndose el valor a 1. Para saber los valores de los procesos utilizaremos: #include <types.h>pid_t getpid (); pid_t getppid (); Para determinar a que grupo pertenece un proceso utilizaremos: #include <sys/types.h> pid_t getpgrp(); Para cambiar el identificador de grupo de procesos utilizaremos: #include <sys/types.h> pid_t setpgrp (); IDENTIFICADORES DE USUARIO Y DE GRUPOEl núcleo asocia a cada proceso dos identificadores de usuario, UID(identificador real) y EUID(identificador del usuario efectivo) y dos identificadores para el grupo, GID(identificador del grupo real) y EGID(identificador del grupo efectivo). El UID identifica al usuario que es responsable de la ejecución del proceso y el GID al grupo al cual pertenece el usuario. El EUID se usa para determinar el propietario de los ficheros recién creados, comprobar la mascara de permisos de acceso a ficheros y los permisos para enviar señales a otros procesos. El UID y EUID coinciden, pero si un proceso ejecuta un programa que pertenece a otro usuario y que tiene activo el bit S_ISUID el proceso cambia su EUID que toma el valor del UID del nuevo usuario. Con respecto al identificador de grupo efectivo pasa exactamente lo mismo. Bajate esta documentación en un archivo Acrobat Reader |