Está en la página 1de 10

Laboratorio de Sistemas Operativos

Pgina: 1

UNIVERSIDAD CATLICA DE SANTA MARA


PROGRAMA PROFESIONAL DE INGENIERA DE SISTEMAS

SESIN 05:

Programacin de Procesos en C
para Linux
I
OBJETIVOS

Conocer y aplicar los conceptos sobre Procesos en LINUX


Llamadas POSIX para gestin de Procesos en LINUX
Creacin y ejecucin de Procesos
Compilacin y ejecucin de programas en LINUX
Realizar ejercicios.

II
TEMAS A TRATAR
Identificadores (PID, PPID, UID, EUID, GID y EGID)
Llamadas al sistema
Cmo crear un proceso
La llamadas al sistema fork()
La llamadas al sistema exec()
Finalizacin de procesos
La llamada al sistema exit, wait y waitpid
Obtencin de Identificadores (getpid(), getppid())
GCC (Compilacin)
./ (Ejecucin)

III
MARCO TEORICO
Identificadores PID, PPID, UID, EUID, GID y EGID
Process ID (PID)

M.Sc. Karim Guevara Puente de la Vega, Ing. Eveling Castro

Sesin 05

Laboratorio de Sistemas Operativos

Pgina: 2

Al crearse un nuevo proceso se le asigna un identificador de proceso nico. Este nmero


debe utilizarse por el administrador para referirse a un proceso dado al ejecutar un
comando.
Los PID son asignados por el sistema a cada nuevo proceso en orden creciente
comenzando desde cero. Si antes de un reboot del sistema se llega al nmero mximo, se
vuelve a comenzar desde cero, salteando los procesos que an estn activos.
Parent Process ID (PPID)
La creacin de nuevos procesos en Unix se realiza por la va de duplicar un proceso
existente invocando al comando fork(). Al proceso original se le llama "padre" y al nuevo
proceso "hijo". El PPID de un proceso es el PID de su proceso padre.
UID y EUID
Los procesos tienen un EUID (Effective User ID), y un UID normalmente ambos
coinciden. El UID es el identificador de usuario real que coincide con el identificador del
usuario que arranc el proceso. El EUID es el identificador de usuario efectivo y se llama
as porque es el identificador que se tiene en cuenta a la hora de considerar los permisos.
El UID es uno de los atributos de un proceso que indica por decirlo de alguna manera
quien es el propietario actual de ese proceso y en funcin de ello podr hacer ciertas
cosas. Por ejemplo si un usuario normal intentara eliminar un proceso del cual no es
propietario el sistema no lo permitir mostrando un mensaje de error en el que advierta
que usted no es el propietario de ese proceso y por tanto no est autorizado a hacer esa
operacin. Por el contrario el usuario root puede hacer lo que quiera con cualquier
proceso ya que el sistema no comprueba jams si root tiene permisos o no para hacer
algo. root siempre tiene permisos para todo. Esto es cierto a nivel de llamadas del sistema
pero nada impide implementar un comando que haga comprobaciones de permisos
incluso con root. Algunos comandos en Linux tienen opciones que permiten hacer estas
cosas y solicitar confirmacin en caso de detectar una operacin peligrosa o poco
frecuente.
El UID tambin es un atributo presente en otros elementos del sistema. Por ejemplo los
ficheros y directorios del sistema tienen este atributo. De esta forma cuando un proceso
intenta efectuar una operacin sobre un fichero. El kernel comprobar si el EUID del
proceso coincide con el UID del fichero. Por ejemplo si se establece que determinado
fichero solo puede ser leido por su propietario, el kernel denegar todo intento de lectura
a un proceso que no tenga un EUID igual al UID del fichero salvo que se trate del root
La forma ms habitual de hacer que el EUID de un proceso sea el de un usuario diferente
del que lanza a correr el programa es activando el flag setuid en el archivo del programa.
Un ejemplo de esto son los comandos que permiten a un usuario modificar su password,
en que se debe modificar el archivo passwd o equivalente del sistema sobre el cual el
usuario obviamente no tiene permiso de escritura. Habitualmente ese comando es un
archivo de root con setuid y el proceso corre con EUID de root.
GID y EGID
Es totalmente anlogo a los identificadores de usuario pero para grupos de usuarios. El
GID se hereda del proceso padre. El EGID puede utilizarse igual que el EUID para
controlar el acceso del proceso a archivos.

M.Sc. Karim Guevara Puente de la Vega, Ing. Eveling Castro

Sesin 05

Laboratorio de Sistemas Operativos

Pgina: 3

En la mayora de los versiones actuales de Unix el proceso puede estar en varios grupos y
se chequea contra toda la lista de grupos para definir si el proceso puede acceder o no a
un recurso.

Las llamadas al sistema para la gestin de procesos


Como se crea un nuevo proceso
El sistema operativo UNIX/Linux dispone de un conjunto de llamadas al sistema que
definen una poderosa interfaz para la programacin de aplicaciones (API) que involucren
mltiples procesos; abriendo las puertas a la programacin concurrente. Esta interfaz
suministra herramientas al desarrollador de software, tanto para la creacin,
sincronizacin y comunicacin de nuevos procesos, como la capacidad de ejecutar
nuevos programas.
Entre los aspectos ms destacados de la gestin de procesos en UNIX/Linux se encuentra
la forma en que se crean y cmo se ejecutan nuevos programas. El kernel es el encargado
de realizar la mayora de funciones bsicas que gestiona entre otras cosas los procesos.
La gestin de estos procesos se hacen por medio de un limitado nmero de funciones que
se denominan llamadas al sistema. Estas llamadas al sistema estn implementadas en
lenguaje C. Aunque ms adelante se mostrarn las correspondientes llamadas al sistema,
aqu mostraremos una visin inicial conjunta, que permita entender mejor la forma en
que estas llamadas se utilizan.
Cuando el kernel crea un nuevo proceso, procesos hijo, hace una copia (clonacin) del
proceso que realiza la llamada al sistema fork (proceso padre). As, salvo el PID y el
PPID, los dos procesos sern inicialmente idnticos. El proceso hijo obtiene una copia de
los recursos del padre (hereda su entorno).

Cuando un proceso termina (muere), el sistema operativo lo elimina recuperando sus


recursos para que puedan ser usados por otros procesos.
La llamada al sistema fork()

M.Sc. Karim Guevara Puente de la Vega, Ing. Eveling Castro

Sesin 05

Laboratorio de Sistemas Operativos

Pgina: 4

La forma en que un proceso arranca a otro es mediante una llamada al sistema con la
funcin fork(). Lo normal es que el proceso hijo ejecute luego una llamada al sistema
exec(). fork() duplica un proceso generando dos procesos casi idnticos. En realidad solo
se diferenciaran en los valores PID y PPID. Un proceso puede pasar al proceso hijo una
serie de variables pero un hijo no puede pasar nada a su padre a travs de variables.
Adems fork() retorna un valor numrico que ser -1 en caso de fallo, pero si tiene xito
se habr producido la duplicacin de procesos y retornar un valor distinto para el
proceso hijo que para el proceso padre. Al proceso hijo le retornar el valor 0 y al
proceso padre le retornar el PID del proceso hijo. Despus de hacer fork() se pueden
hacer varias cosas pero lo primero que se utiliza despus del fork es una pregunta sobre
el valor retornado por fork() para as saber si ese proceso es el padre o el hijo ya que cada
uno de ellos normalmente deber hacer cosas distintas.
int PID = fork()

crea un nuevo proceso (hijo del que hace la llamada a fork). padre e hijo continan la
ejecucin en la instruccin inmediatamente posterior al fork.
Con:
PID = 0 en el hijo,
PID > 0 en el padre (y contiene el pid del hijo)
PID < 0 si error

La llamada al sistema exec()


Un proceso puede evolucionar y cambiar totalmente desde que arranca hasta que muere.
Lo nico que no cambia en un proceso desde que nace hasta que se muere es su
identificador de proceso PID. Una de las cosas que puede hacer un proceso es cambiar
por completo su cdigo. Por ejemplo un proceso encargado de procesar la entrada y
salida de un trminal (getty) puede transformarse en un proceso de autentificacin de
usuario y password (login) y este a su vez puede transformarse en un interprete de
comandos (bash). Si la llamada exec() falla retornar un 1, cuando esta llamada tiene
xito no se produce jams un retorno. En realidad no tendra sentido retornar a ningn
lado. Cuando un proceso termina simplemente deja de existir. La llamada exec()
mantiene el mismo PID y PPID pero transforma totalmente el cdigo de un proceso en
otro que cargar desde un archivo ejecutable.
exec se ejecuta en el espacio del proceso llamador, posibilidades:
int
int
int
int

execl(char *path, char *arg0, char *arg1,..., char *argn, null);


execv(char *path, char *argv[]);
execlp(char *file, char *arg0, char *arg1,..., char *argn, null);
execvp(char *file, char *argv[]);

El sistema operativo UNIX ofrece una llamada al sistema llamada exec para lanzar a
ejecucin un programa, almacenado en forma de fichero. Aunque en el fondo slo existe
una llamada, las bibliotecas estndares del C disponen de varias funciones, todas
comenzando por exec que se diferencian en la manera en que se pasan parmetros al
programa.
La versin tpica cuando se conoce a priori el nmero de argumentos que se van a
entregar al programa se denomina execl. Su sintaxis es

M.Sc. Karim Guevara Puente de la Vega, Ing. Eveling Castro

Sesin 05

Laboratorio de Sistemas Operativos

Pgina: 5

int execl ( char* fichero, char* arg0, char* arg1, ... , 0 );

Es decir, el nombre del fichero y luego todos los argumentos consecutivamente,


terminando con un puntero nulo o cero.
Por ejemplo, si quisiramos ejecutar el siguiente comando:
/bin/ls -l /usr/include

Escribiramos
execl ( "/bin/ls", "ls", "-l", "/usr/include", 0 );

Observe que el primer argumento coincide con el nombre del programa. En caso de
desconocer con anticipacin el nmero de argumentos, habr que emplear la funcin
execv, que tiene este prototipo:
execv ( char* fichero, char* argv [] );

El parmetro argv es una tira de cadenas que representan los argumentos del programa
lanzado, siendo la ltima cadena un nulo (o cero). El ejemplo anterior se resolvera as:
char* parametros [] = { "ls", "-l", "/usr/include", 0 }; ...
execv ( "/bin/ls", parametros );

En los anteriores ejemplos se ha escrito el nombre completo del fichero para ejecutar
("/bin/ls" en vez de "ls"). Esto es porque tanto execl como execv ignoran la variable
PATH, que contiene las rutas de bsqueda. Para tener en cuenta esta variable pueden
usarse las versiones execlp o execvp. Por ejemplo:
execvp ( "ls", parametros );

ejecutara el programa "/bin/ls", si es que la ruta "/bin" est definida en la variable


PATH.
Todas las llamadas exec, retornan un valor no nulo si el programa no se ha podido
ejecutar. En caso de que s se pueda ejecutar el programa, se transfiere el control a ste y
la llamada exec nunca retorna. En cierta forma el programa que invoca un exec
desaparece del mapa.

Finalizacin de procesos
exit
void exit (int status)

exit finaliza al proceso que lo llam, con un cdigo de estado igual al byte inferior del
parmetro status. Todos los descriptores de archivo abiertos son cerrados y sus buffers
sincronizados, si hay procesos hijo cuando el padre ejecutar un exit, el PPID de los hijos
se cambia a 1 (proceso init). Es la nica llamada al sistema que nunca retorna.

M.Sc. Karim Guevara Puente de la Vega, Ing. Eveling Castro

Sesin 05

Laboratorio de Sistemas Operativos

Pgina: 6

El valor del parmetro status se utiliza para comunicar al proceso padre la forma en que
el proceso hijo termina. Por convenio, este valor suele ser 0 si el proceso termina
correctamente y cualquier otro valor en caso de terminacin anormal. El proceso padre
puede obtener este valor a travs de la llamada al sistema wait.
wait y waitpid
Espera a que pare o termine un proceso hijo, permitiendo obtener sus estados de salida.
Una seal no bloqueada o no ignorada puede reactivar el proceso padre.
pid_t wait (int *statusp)

Si hay varios procesos hijos, wait espera hasta que uno de ellos termina. No es posible
especificar por qu hijo se espera. wait retorna el PID del hijo que termina (o -1 si no se
crearon hijos o si ya no hay hijos por los que esperar) y almacena el cdigo del estado de
finalizacin del proceso hijo (parmetro status en su llamada al sistema exit) en la
direccin apuntada por el parmetro statusp.
Un proceso puede terminar en n momento en el que su padre no le est esperando. Como
el kernel debe asegurar que el padre pueda esperar por cada proceso, los procesos hijos
por los que el padre no espera, se convierten en procesos zombies (se descartan sus
segmentos, pero siguen ocupando una entrada en la tabla de procesos del kernel). Cuando
el padre realiza una llamada wait, el proceso hijo es eliminado de la tabla de procesos.
No es obligatorio que todo proceso padre espera a sus hijos.
Un proceso puede termina por:
Causa de terminacin
Llamada al sistema exit
Recibe una seal
Cada del sistema
(p.e.: prdida de la alimentacin del equipo)

Contenido de *statusp
Byte ms a la derecha = 0
Byte de la izquierda = parmetro status de exit
En los 7 bits de ms a la derecha se almacena el nmero
de seal que termin con el proceso. Si el 8vo bit ms a la
derecha est en 1, el proceso fue detenido por el kernel y
se gener un volcado del proceso en un archivo core.
Todos los procesos desaparecen bruscamente. No hay
nada que devolver

Proceso zombie:
Proceso parado que queda en la tabla de procesos hasta que termine su padre. Este hecho
se produce cuando el proceso padre no recoge el cdigo de salida del proceso hijo.
Proceso hurfano:
Proceso en ejecucin cuyo padre ha finalizado. El nuevo identificador de proceso padre
(PPID) coincide con el identificador del proceso init (1).

Obtencin de Identificadores (getpid(), getppid())


getpid(void) Devuelven el ID del proceso

M.Sc. Karim Guevara Puente de la Vega, Ing. Eveling Castro

Sesin 05

Laboratorio de Sistemas Operativos

Pgina: 7

getppid(void) devuelve el ID del padre (del proceso), en general, se ejecutan en silencio


sin necesidad de interaccin.

GCC
Cada vez que usted desea compilar un programa con extensin .c (dentro de las
principales) lo puede hacer con el comando gcc por ejemplo:
gcc programas.c o programas.exe

el primer parmetro implica el programa a compilarse y el segundo el archivo objeto de


salida el cual posteriormente se podr ejecutar.

./
Con esta instruccin usted puede ejecutar el programa cuyo ejecutable cre
anteriormente. Por ejemplo:
./ programas.exe

Por ahora solo necesitamos saber esa informacin para empezar a crear nuestros
programas y ejecutarlos en C.

IV
ACTIVIDADES
1. Realice los ejemplos que se encuentren en el Marco Terico
2. Para los siguientes ejercicios utilizaremos el lenguaje de programacin C y el
compilador gcc.
3. En cualquier editor digite el siguiente programa y evale el resultado
// Nos d el PPID y el PID
#include <unistd.h>
#include <stdio.h>
#include <stlib.h>
int main(void)
{
printf("Proseso hijo PID= %d\n", getpid());
printf("Proceso padre PPID= %d\n", getppid());
exit(0);
}

4. Escriba el siguiente programa y verifique de acuerdo a la siguiente tabla:

M.Sc. Karim Guevara Puente de la Vega, Ing. Eveling Castro

Sesin 05

Laboratorio de Sistemas Operativos

Pgina: 8

// Muestra los UID y los GUID


#include <unistd.h>
#include <stdio.h>
#include <stlib.h>
int main(void)
{
printf("ID
printf("ID
printf("ID
printf("ID
exit(0);
}

de
de
de
de

usuario real: %d\n", getuid());


usuario efectivo: %d\n", geteuid());
grupo real: %d\n", getgid());
grupo efectivo: %d\n", getegid());

5. Ejecutar el siguiente programa.


#include <unistd.h>
#include <stdio.h>
#include <stlib.h>
int main(void)
{
pid_t rf;
rf = fork();
switch (rf)
{
case -1:
printf (No he podido crear el proceso hijo \n);
break;
case 0:
printf (Soy el hijo, mi PID es %d y mi PPID es %d
\n, getpid(), getppid());
sleep (20);
break;
default:
printf (Soy el padre, mi PID es %d y el PID de mi
hijo es %d \n, getpid(), rf);
sleep (30);
break;
}
printf (Final de ejecucin de %d \n, getpid());
exit (0);
}

6. Ejecute el programa anterior en segundo plano.


7. Verifique su ejecucin con la orden ps. Observe los valores PID y PPID. Describa lo
que sucede
8. Digite el siguiente programa:
#include <stdio.h>
int main(void) {
int pid;
printf("Hasta aqu hay un nico proceso...\n");
printf("Primera llamada a fork...\n");
/* Creamos un nuevo proceso. */
pid = fork();
if (pid == 0) {
printf("HIJO1: Hola, yo soy el primer hijo...\n");

M.Sc. Karim Guevara Puente de la Vega, Ing. Eveling Castro

Sesin 05

Laboratorio de Sistemas Operativos

Pgina: 9

printf("HIJO1: Voy a pararme durante 60 seg. y luego


terminar...\n");
sleep(60);
}
else if (pid > 0) {
printf("PADRE: Hola, soy el padre. El pid de mi hijo es:
%d\n",pid);
/* Creamos un nuevo proceso. */
pid = fork();
if (pid == 0) {
printf("HIJO2: Hola, soy el segundo hijo...\n");
printf("HIJO2: El segundo hijo va a ejecutar la orden
'ls'...\n");
execlp("ls","ls",NULL);
printf("HIJO2: Si ve este mensaje, el execlp no
funcion...\n");
}
else if (pid > 0) {
printf("PADRE: Hola otra vez. Pid de mi segundo hijo:
%d\n",pid);
printf("PADRE: Voy a esperar a que terminen mis
hijos...\n");
printf("PADRE: Ha terminado mi hijo %d\n",wait(NULL));
printf("PADRE: Ha terminado mi hijo %d\n",wait(NULL));
}
else
printf("Ha habido algn error al llamar por 2 vez al
fork\n");
}
else
printf("Ha habido algn error al llamar a fork\n");
}

9. Digite el siguiente programa y describa su funcionalidad:


#include <stdio.h>
#include <unistd.h>
main() {
printf("Ejemplo de proceso huerfano.\n");
printf("Inicio del proceso padre. PID = %d\n", getpid());
if (fork() == 0) {
printf("Inicio proceso hijo. PID = %d, PPID = %d\n", getpid(),
getppid());
sleep(1);
printf("Proceso queda huerfano. PID = %d, PPID = %d\n", getpid(),
getppid());
}
else
printf("Continuacin del padre. PID = %d \n", getpid());
printf("Fin del proceso %d \n");
exit (0);
}

V
EJERCICIOS
Realice la escritura, compilacin y ejecucin de los siguientes programas
01. A los programas de los incisos 3 y 6 colocarles la llamada exec() donde crea
conveniente para finalizar correctamente los procesos.
M.Sc. Karim Guevara Puente de la Vega, Ing. Eveling Castro

Sesin 05

Laboratorio de Sistemas Operativos

Pgina: 10

02. Elabore un programa propio sobre creacin de procesos.


03. Escriba un programa en el cual se creen procesos y uno de ellos se encuentre en
estado zombie.
04. Deduzca que procesos intervienen en la ejecucin de la orden man y la jerarqua
entre ellos. Para esto, ejecute dicha orden e interrumpa su ejecucin con Ctrl + Z y
compruebe los procesos existentes con la orden ps y la opcin l.

VI
BIBLIOGRAFIA Y REFERENCIAS

Blanco, V., Linux Instalacin, Administracin y uso del Sistema, Ed. Ra-Ma,
Mxico, 2001.

http://users.exa.unicen.edu.ar/~hcurti/linux/index.html

M.Sc. Karim Guevara Puente de la Vega, Ing. Eveling Castro

Sesin 05

También podría gustarte