Está en la página 1de 15

Universidad de El Salvador

Facultad Multidisciplinaria de Occidente

Departamento de Ingeniera y Arquitectura


-------------------------------------------------------------------------------Sistemas Operativos_
24 Septiembre -2015_

_Gua de Trabajo No 6_

Servicios POSIX para la Gestin de Procesos


fork(), exec(), wait()

Objetivo_
_Estudiar los conceptos bsicos de los servicios POSIX para la gestin de procesos
empleada por los Sistemas Operativos GNU/Linux
Indicaciones_ Habiendo ledo sus apuntes, material visto en clases y la lectura de Servicios
POSIX para la gestin de procesos, resuelva o plantee una solucin a una serie de
interrogantes y problemas que a continuacin se le presentan, donde se destacan los puntos
bsicos de la gestin de procesos en el Sistema Operativo GNU/Linux.

Material de Apoyo_
_Definicin de Proceso
Un programa es una secuencia de instrucciones escrita en un lenguaje de programacin. Un
proceso es una instancia de ejecucin de un programa. Un programa es un concepto esttico,
mientras que un proceso es un concepto dinmico. En un entorno multiusuario, es posible que
varios usuarios ejecuten el mismo programa, obteniendo un proceso distinto por cada
ejecucin.
_Estados de un Proceso en el Kernel Linux
En un entorno multitarea coexisten varios procesos que se ejecutan de manera entrelazada (un
nico procesador). Sin embargo, algunos procesos se encuentran esperando eventos, por
ejemplo esperando a que el usuario pulse una tecla, dicha espera se debe realizar de manera
que se perjudique lo menos posible al resto de procesos, con los que se comparte la CPU.
Si se realiza espera activa, cada vez que el sistema operativo le asigne la CPU a dicho
proceso, ste mirar el teclado a ver si se ha pulsado una tecla, y esto lo repetir hasta
que dicho evento se produzca. Durante todo ese tiempo, el proceso est consumiendo
innecesariamente CPU. Para evitar la espera activa, los procesos se suspenden a espera de
eventos, de manera que dichos procesos no entren en el reparto de la CPU. A continuacin se
enumeran los distintos estados en los que se puede encontrar un proceso:
_Preparados (R): Conjunto de procesos que pueden ejecutarse en este momento, es decir,
disponen de todos los recursos necesarios para poder ejecutarse, salvo la CPU. El
sistema operativo les ir asignando la CPU a cada uno de ellos.
_Ejecutando (O): El proceso ocupa actualmente la CPU: Slo uno de los procesos
preparados se estar ejecutando en cada momento (monoprocesador).
_Suspendidos (S): A dichos procesos les falta, adems de la CPU, algn recurso para
poder ejecutarse, entendindose por recurso un dispositivo, un dato, etc. Los procesos
suspendidos estn esperando a que ocurra algn evento para poder acceder al recurso
que necesitan. Estos procesos no entran en el reparto de la CPU, evitando as la
espera activa. Cuando se produce el evento esperado, dicho proceso pasar a estar
preparado.

_Sistemas Operativos_

_24-09-2015_

_Parados (T): Son procesos que tampoco entran en el reparto de la CPU, pero que no
estn suspendidos a la espera de eventos, sino que han sido parados en su ejecucin.
Para salir de dicho estado hay que mandarles continuar, volviendo as a estar
preparados.
_Zombies (Z): Cuando un proceso finaliza, se lo comunica a su proceso padre (el
proceso que lo cre). Si dicho proceso no captura el aviso de su proceso hijo, ste
queda en un estado zombies. En dicho estado, el proceso no consume CPU pero sigue
ocupando recursos en la tabla de procesos (donde se guarda informacin de cada uno de
los procesos existentes en el sistema). Un proceso permanece zombi hasta que su
proceso padre captura su aviso.

_Identificacin de Procesos
Cada proceso se identifica mediante su PID (identificador de proceso), que es un nmero
entero (mayor que cero) que el sistema va asignando a cada proceso cuando ste se crea.
El sistema operativo Unix y Linux proporciona un comando que nos da informacin relativa a
cada uno de los procesos que existen en el sistema. Para obtener todos los procesos
correspondientes a un usuario
usuario: ps -aux | grep usuario. Se recomienda ver el manual (man ps).
USER: El propietario del proceso.
PID: El identificador del proceso.
%CPU: Porcentaje de CPU consumida.
%MEM: Porcentaje de memoria consumida.
SIZE: Tamao total del proceso (Kb).
RSS: Kilobytes del programa en memoria. (El resto estar en disco (swap)).
TTY: Identificador del terminal desde donde se lanz el proceso.
STAT: Estado del proceso.
START: Hora en la que empez o la que se lanz el proceso.
TIME: Tiempo de CPU consumido.
COMMAND: Nombre del proceso.
Otros comandos interesantes:

top, htop

(ver man para una mayor descripcin)

_Servicios POSIX para la identificacin de procesos


POSIX identifica cada proceso por medio de un entero nico denominado identificador de
proceso de tipo pid_t. Los servicios relativos a la identificacin de los procesos son los
siguientes:

_Sistemas Operativos_

_24-09-2015_

_Obtener el identificador de proceso


Este servicio devuelve el identificador del proceso que realiza la llamada. Su
prototipo en lenguaje C es:
pid_t getpid(void);
_Obtener el identificador del proceso padre
Devuelve el identificador del proceso padre. Su prototipo en lenguaje C es:
pid_t getppid(void);
Adems, cada proceso lleva asociado un usuario que se denomina propietario. Cada usuario en
el sistema tiene un identificador nico denominado identificador de usuario, de tipo uid_t.
El proceso tiene tambin un identificador de usuario efectivo, que determina los privilegios
que un proceso tiene cuando se encuentra ejecutando. El sistema incluye tambin grupos de
usuarios, cada usuario debe ser miembro al menos de un grupo.
_Obtener el identificador de usuario real
Este servicio devuelve el identificador de usuario real del proceso que realiza la
llamada:
uid_t getuid(void);
_Obtener el identificador de usuario efectivo
Devuelve el identificador de usuario efectivo:
uid_t geteuid(void);
_Obtener el identificador de grupo real
Devuelve el identificador de grupo real, su prototipo es el siguiente:
gid_t getgid(void);
_Obtener el identificador de grupo efectivo
Devuelve el identificador de grupo efectivo, su prototipo es:
gid_t getegid(void);

_El entorno de un proceso


El 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.
Cada aplicacin interpreta la lista de variables de entorno de forma especfica. POSIX
establece el significado de determinadas variables de entorno. Las ms comunes son:
HOME: directorio de trabajo inicial del usuario.
LOGNAME: nombre del usuario asociado a un proceso.
PATH: prefijo de directorios para encontrar ejecutables.
TERM: tipo de terminal.
TZ: informacin de la zona horaria.

_Sistemas Operativos_

_24-09-2015_

_Obtener el valor de una variable de entorno


El servicio getenv permite buscar una determinada variable de entorno dentro de la
lista de variables de entorno de un proceso. La sintaxis de esta funcin es:
char *getenv(const char *name)
Esta funcin devuelve un puntero al valor asociado a la variable de entorno de nombre
name. Si la variable de entorno no se encuentra definida, la funcin devuelve NULL.
_Creacin de Procesos: fork()
Los procesos pueden tener una estructura jerrquica, de manera que un proceso (proceso
padre) puede crear un nuevo proceso (proceso hijo) y as sucesivamente. Para la realizacin
de aplicaciones con varios procesos, este servicio lo proporciona la funcin fork().
Synopsis
#include <sys/types.h>
#include <unistd.h>
int fork(void);
Descripcin
fork() crea un nuevo proceso exactamente igual (mismo cdigo) al proceso que invoca
la funcin. Ambos procesos continan su ejecucin tras la llamada a fork().
Valores retornados
En caso de error retorna -1 y no se crea el proceso hijo. En otro caso, retorna
valores diferentes al proceso padre (el que lo invoc) y al proceso hijo (el proceso
creado):
- Proceso Padre: Retorna el PID del proceso hijo.
- Proceso Hijo: Retorna 0.

La siguiente figura muestra que la clonacin del proceso padre se realiza copiando la imagen
de memoria y el BCP. Observe que el proceso hijo es una copia del proceso padre en el
instante en que ste solicita el 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 hace es salvar los
registros en el BCP
del padre, al copiarse
el BCP se copian los
valores salvados de
los registros, por lo
que el hijo tiene los
mismos valores que el
padre.

_Sistemas Operativos_

_24-09-2015_

Esto significa, en especial, 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.
Repetimos que el hijo empieza a ejecutar, al igual que el padre, en la sentencia que est
despus del fork.
En realidad, el proceso hijo no es totalmente idntico al padre, puesto que algunos de los
valores del BCP han de ser distintos. Las diferencias ms importantes son las siguientes:
_El proceso hijo tiene su propio identificador de proceso, distinto al del padre.
_El proceso hijo tiene una nueva descripcin de la memoria. Aunque el hijo tenga los
mismos segmentos con el mismo contenido, no tienen por qu estar en la misma zona de
memoria (esto es especialmente cierto en el caso de sistemas sin memoria virtual).
_El tiempo de ejecucin del proceso hijo se iguala a cero.
_Todas las alarmas pendientes se desactivan en el proceso hijo.
_El conjunto de seales pendientes se pone a vaco.
_El valor que retorna el sistema operativo como resultado del fork es distinto en el
hijo y el padre.
Ejemplo:
En el ejemplo que se muestra a continuacin, se crea un proceso hijo que imprime en pantalla
el PID de su proceso padre, mientras que el proceso padre imprime en pantalla su propio PID
y el del proceso hijo que ha creado. Para ello, se utilizan servicio getpid() y getppid().
El proceso padre, antes de finalizar se suspende hasta que el hijo muere, para evitar que
ste se quede zombi. Para ello, utiliza servicio wait() [consulte el manual del programador
de linux para mayor informacin del servicio wait ($ man 2 wait)], que recibe en la variable
status el estado de que el proceso hijo finaliz.
/*
* File:
main.c
* Author: logan
*
* Created on 20 de septiembre de 2015, 08:41 PM
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
int main() {
pid_t pid;
int status = 0, pid_hijo_terminado = 0;
if ((pid = fork()) == -1) {
printf("Error al crear proceso hijo!!!\n");
exit(1);
}
if (pid == 0) {
/* Proceso Hijo */
printf("El PID de mi proceso padre es %d:\n ", getppid());
exit(1);
} else {
/* Proceso Padre */
printf("Mi PID es el %d y he creado un proceso hijo y su pid es %d\n", getpid(), pid);
pid_hijo_terminado = wait(&status);
printf("\nEl proceso hijo [pid] = %d, finalizo con el estado %d\n", pid_hijo_terminado, status);
}
return (0);
}

_Ejecucin de un Programa
El servicio exec de POSIX tiene por objetivo cambiar el programa que est ejecutando un
proceso. Se puede considerar que el servicio tiene dos fases. En la primera se vaca el
proceso de casi todo su contenido, mientras que en la segunda se carga en nuevo programa. La
siguiente figura muestra estas dos fases.

_Sistemas Operativos_

_24-09-2015_

En la fase de vaciado del proceso se conservan algunas informaciones, como:


_Entorno del proceso. Que el sistema operativo incluye en la nueva pila del proceso.
_Algunas informaciones del BCP como: identificador de proceso, identificador del
proceso padre, identificador de usuario y descriptores de archivos abiertos.
En la fase de carga hay que realizar las siguientes operaciones:
_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 pasan al
programa.
_Rellenar el BCP con los valores iniciales de los registros y la descripcin de los
nuevos segmentos de memoria.
Recuerde que el servicio fork crea un nuevo proceso que ejecuta el mismo programa que el
proceso padre y que el servicio exec no crea un nuevo proceso, sino que permite que un
proceso pase a ejecutar un programa distinto.
En POSIX existe una familia de funciones exec, cuyos prototipos se muestran a continuacin:
Manual del Programador Linux: (Seccin 3)
NOMBRE

execl, execlp, execle, execv, execvp - ejecutan un fichero

SINOPSIS
#include <unistd.h>
extern char **environ;
int
int
int
int
int

execl(const char *path, const char *arg, ...);


execlp(const char *file, const char *arg, ...);
execle(const char *path, const char *arg , ..., char * const envp[]);
execv(const char *path, char *const argv[]);
execvp(const char *file, char *const argv[]);

DESCRIPCIN
La familia de funciones exec reemplaza la imagen del proceso en curso con una nueva.
Las funciones descritas en esta pgina del Manual son interfaces para la primitiva
execve(2). (Consulte la pgina del Manual de execve para informacin detallada acerca
del reemplazo del proceso en curso.)

_Sistemas Operativos_

_24-09-2015_

Si la llamada se ejecuta con xito, sta no devolver ningn valor puesto que la imagen del
proceso habr sido reemplazada, en caso contrario devuelve -1.
La funcin main del nuevo programa llamado tendr la forma:
int main(int argc, char **argv)
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.
El argumento path apunta al nombre del archivo ejecutable donde reside la nueva imagen del
proceso. El argumento file se utiliza para construir el nombre del archivo ejecutable. Si el
argumento file contiene el carcter /, entonces el argumento file constituye el nombre del
archivo ejecutable. En caso contrario, el prefijo del nombre para el archivo se construye
por medio de la bsqueda en los directorios pasados en la variable de entorno PATH.
El argumento argv contiene los argumentos pasados al programa y debera acabar con un
puntero NULL. El argumento envp apunta al entorno que se pasar al nuevo proceso y se
obtiene de la variable externa environ.
Ejemplo: A continuacin se muestra un ejemplo de utilizacin de la llamada execlp. Este
programa crea un proceso hijo, que ejecuta el comando ls -l, para listar el contenido del
directorio actual de trabajo.
/*
* File:
fexecvp.c
* Author: logan
*
* Created on 23 de septiembre de 2015, 06:37 PM
*/
#include
#include
#include
#include

<stdio.h>
<stdlib.h>
<unistd.h>
<sys/types.h>

int main() {
pid_t pid;

pid = fork();
switch(pid) {
case -1:
exit(-1);
case 0:
execlp("ls", "ls", "-l", NULL);
perror("exec");
break;
default:
printf("Proceso Padre\n");
}
return (EXIT_SUCCESS);

_Terminacin de Procesos
Un proceso puede terminar su ejecucin de forma normal o anormal. Un proceso puede terminar
su ejecucin de forma normal usando cualquiera de las tres formas siguientes:
_Ejecutando una sentencia return en la funcin main.
_Ejecutando la llamada exit.
_Ejecutando la llamada _exit.
Cuando un programa ejecuta dentro de la funcin main la sentencia return(valor), sta es
similar a exit(valor). El prototipo de la funcin exit es:
void exit(int status);
_Sistemas Operativos_

_24-09-2015_

Estos servicios tienen por funcin finalizar la ejecucin de un proceso. Ambos reciben como
parmetro un valor que sirve para que el proceso d una indicacin de cmo ha terminado.
La finalizacin de un proceso tiene las siguientes consecuencias:
_Se cierran todos los descriptores de archivos.
_La terminacin del proceso no finaliza de forma directa la ejecucin de sus procesos
hijos.
_Si el proceso padre del proceso que realiza la llamada se encuentra ejecutando una
llamada wait o waitpid, se notifica la terminacin del proceso.
_Si el proceso padre no se encuentra ejecutando una llamada wait o waitpid, el cdigo
de finalizacin (status) se salva hasta que el proceso padre ejecute la llamada wait o
waitpid.
_El sistema operativo libera todos los recursos utilizados por el proceso.
Un proceso tambin puede terminar su ejecucin de forma anormal, llamando a la funcin
abort, por la recepcin de una seal que provoca su finalizacin. La seal puede ser causada
por un evento externo (ej: se pulsa CTRL-C), por una seal enviada por otro proceso, o por
un error de ejecucin, como, por ejemplo, la ejecucin de una instruccin ilegal, un acceso
ilegal a una posicin de memoria, etc.
En realidad, exit es una funcin de biblioteca que llama al servicio _exit despus de
preparar la terminacin ordenada del proceso.
Para tener un mejor panorama y explicacin de las funciones de biblioteca aqu planteadas
puede consultar el manual del sistema [man] en las secciones 2 y 3.
MAN(1)
MAN(1)
NOMBRE

tiles de Pginas de Manual

man - una interfaz de los manuales de referencia electrnicos

SINOPSIS
man [-c|-w|-tZT dispositivo] [-adhu7V] [-m sistema[,...]] [-L locale] [-p cadena] [-M
ruta] [-P paginador] [-r prompt] [-S lista] [-e extension]
[[seccin] pagina ...] ...
man -l [-7] [-tZT dispositivo] [-p cadena] [-P paginador] [-r prompt] fichero ...
man -k [-M ruta] palabra_clave ...
man -f [-M ruta] pagina ...
DESCRIPCIN
man es el paginador del manual del sistema. Las pginas usadas como argumentos al ejecutar man
suelen ser normalmente nombres de programas,
tiles
o funciones. La
pgina
de
manual
associada con cada uno de esos argumentos es buscada y presentada. Si la llamada da tambin la
seccin, man buscar slo en dicha seccin del manual. Normalmente, la bsqueda se lleva a cabo
en todas las secciones de manual
disponibles
segn
un
orden predeterminado, y slo se
presenta la primera pgina encontrada, incluso si esa pgina se encuentra en varias secciones.
La siguiente tabla muestra los nmeros de seccin del manual y los tipos de pginas que
contienen.
1
2
3
4
5
6
7
8
9
n
l
p
o

Programas ejecutables y guiones del intrprete de rdenes


Llamadas del sistema (funciones servidas por el ncleo)
Llamadas de la biblioteca (funciones contenidas en las bibliotecas del sistema)
Ficheros especiales (se encuentran generalmente en /dev)
Formato de ficheros y convenios p.ej. I/etc/passwd
Juegos
Paquetes de macros y convenios p.ej. man(7), groff(7).
rdenes de administracin del sistema (generalmente solo son para root)
Rutinas del ncleo [No es estndar]
nuevo [obsoleto]
local [obsoleto]
pblico [obsoleto]
viejo [obsoleto]

Una pgina de manual tiene varias partes.

_Sistemas Operativos_

_24-09-2015_

Practica 1_ Creacin de Procesos con fork()


El siguiente cdigo, muestra las acciones internas del servicio fork():
------------------------------------------------------------------------------------------------/*
* File:
pfork.c
* Author: logan
*
* Created on 22 de septiembre de 2015, 07:13 PM
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
int main() {
pid_t pid;
pid = fork();
switch(pid) {
case -1:
printf("ERROR.- No se pudo crear el proceso hijo\n");
break;
case 0:
printf("Soy el P-Hijo, mi PID es %d y mi PPID es %d\n", getpid(), getppid());
sleep(20);
break;
default:
printf("Soy el P-Padre, mi PID es %d y el PID de mi hijo es %d\n", getpid(), pid);
sleep(30);
}
printf("Final de ejecucin de %d \n", getpid());
return (EXIT_SUCCESS);
}
-------------------------------------------------------------------------------------------------

Realice las siguientes tareas:


_Compile el programa anterior mediante el mandato gcc
$ gcc Wall -o forkprog forkprog.c
_Ejecute el programa en segundo plano (o background). Para ello, se debe aadir al
nombre del programa el carcter '& '.
$ forkprog &
_Verifique su ejecucin con comando ps, este le permitir comprobar su funcionamiento.
Dicha comando ha de ser ejecutado antes de que finalice la ejecucin del proceso.
$ ps -l
_Observe los valores del PID y PPID de cada proceso e identifique que atributos son
heredados entre padre e hijo y cuales no.
Responda a las siguientes preguntas:
_Anote el valor mostrado por el interprete de comandos inmediatamente despus de
lanzar al proceso en segundo plano e indique qu representa dicho valor.
_Cuales son los PID de los procesos padre e hijo?
_Qu tamao de memoria ocupan los procesos padre e hijo?
_Qu realiza la funcin sleep?, Qu proceso termina antes su ejecucin?
_Qu ocurre cuando la llamada al sistema fork devuelve un valor negativo?
_Sistemas Operativos_

_24-09-2015_

_Cul es la primera instruccin que ejecuta el proceso hijo?


_Modifique el cdigo del programa para asegurar que el proceso padre imprime su
mensaje de presentacin (Soy el P-Padre...) antes que el hijo imprima el suyo.
_Modifique
cont_fork e
veces en el
1. Anote el

el cdigo fuente del programa declarando una variable entera llamada


inicializndola con un valor de 10. Dicha variable deber incrementarse 10
padre y de 10 en 10. Mientras que el hijo la incrementar 10 veces de 1 en
valor final de la variable cont_fork para el padre y para el hijo.

Practica 2_ Ejecucin de Programas con exec


La llamada exec produce la sustitucin del programa invocador por el nuevo programa
invocado. Mientras fork crea nuevos procesos, exec sustituye la imagen de memoria del
proceso por otra nueva. La combinacin de las llamas fork y exec es el mecanismo que ofrece
UNIX para crear un nuevo proceso (fork) que ejecute un programa determinado (exec).
De las posibles llamadas tipo exec se usar en esta prctica la llamada execv:
int execv(const char *path, char *const argv[]);
El seguimiento de ejecucin del proceso, mediante el comando ps del sistema usado antes y
despus de la llamada execv, permite comprobar cmo se efecta la sustitucin de la imagen
de memoria. El nuevo programa activado mantiene el mismo PID, identificador de proceso, as
como otras propiedades asociadas al proceso, sin embargo, el tamao de memoria de la imagen
del proceso cambia dado que el programa en ejecucin es diferente.
Para esta practica se utilizarn dos programas (p1 y p2), cuyos nombres seran p1.c y p2.c y
se muestran a continuacin:
------------------------------------------------------------------------------------------------/*
* File:
p1.c
* Author: logan
*
* Created on 23 de septiembre de 2015, 07:43 PM
*/
#include
#include
#include
#include

<stdio.h>
<unistd.h>
<string.h>
<stdlib.h>

int main(int argc, char *argv[]) {


int i;
printf("\nEjecutando el programa invocador (p1).- Sus argumentos son: \n");
for (i = 0; i < argc; i++)
printf("argv[%d]: %s\n", i, argv[i]);
sleep(10);
strcpy(argv[0], "p2");
if (execv("./p2", argv) < 0) {
printf("Error en la invocacion de p2.- \n");
exit(1);
}
return (EXIT_SUCCESS);
}
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

_Sistemas Operativos_

_24-09-2015_

/*
* File:
p2.c
* Author: logan
*
* Created on 23 de septiembre de 2015, 07:54 PM
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char** argv) {

int i;
char a[2000000];
printf("Ejecutando el programa invocado.- (p2).- Sus argumentos son: \n");
for (i = 0; i < argc; i++)
printf("argv[%d]: %s\n", i, argv[i]);
sleep(10);
return (EXIT_SUCCESS);

-------------------------------------------------------------------------------------------------

Realice las siguientes tareas:


_Compile
$
_Ejecute
ps.
$

los programas p1.c y p2.c mediante el comando gcc.


gcc Wall -o prog1 prog1.c
$ gcc Wall -o prog2 prog2.c
el programa en background para poder verificar su ejecucin con el comando
prog1 arg1 arg2 ... argN &

$ ps -l

Nota: Para observar cunta memoria ocupa cada programa, realice un ps l una vez el
proceso ha escrito en pantalla el mensaje correspondiente (hay 10 segundos de plazo antes de
realizar el execv en
p1 y antes de terminar en p2).
Responda a las siguientes preguntas:
_Escriba el contenido de los elementos del vector argv que recibe p1 y los que recibe
p2.
_Qu PID tiene el proceso que ejecuta p1.c? Y el de p2.c?
_Qu tamao de memoria utiliza el proceso, segn se ejecuta p1 o p2?

Practica 3_ Visibilidad de Recursos entre Procesos


Dos procesos vinculados por una llamada fork (padre e hijo) poseen zonas de datos propias,
de uso privado (no compartidas). Obviamente, al tratarse de procesos diferentes, cada uno
posee un espacio de direccionamiento independiente e inviolable. La ejecucin del siguiente
programa, en el cual se asigna distinto valor a una misma variable segn se trate de la
ejecucin del proceso padre o del hijo, permitir comprobar tal caracterstica de la llamada
fork.

-------------------------------------------------------------------------------------------------

_Sistemas Operativos_

_24-09-2015_

/*
* File:
pfork2.c
* Author: logan
*
* Created on 20 de septiembre de 2015, 08:12 PM
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
int i, j;
pid_t pid;
pid = fork();
switch (pid) {
case -1:
printf("\nERROR.- No se ha podido crear el proceso hijo.-");
break;
case 0:
i = 0;
printf("\nSoy el Proceso Hijo, mi PID es %d y mi variable i
(valor inicial: %d) es par", getpid(), i);
for (j = 0; j < 5; j++) {
i++;
i++;
printf("\nSoy el Proceso Hijo, mi variable i es: %d", i);
}
break;
default:
i = 1;
printf("\nSoy el Proceso Padre, mi PID es %d y mi variable i
(valor inicial: %d) es impar", getpid(), i);
for (j = 0; j < 5; j++) {
i++;
i++;
printf("\nSoy el Proceso Padre, mi variable i es: %d", i);
};
}
printf("\nFinal de ejecucion de %d \n", getpid());
return (EXIT_SUCCESS);
}
-------------------------------------------------------------------------------------------------

En el programa anterior, el proceso padre visualiza los sucesivos valores impares que toma
su variable i privada, mientras el proceso hijo visualiza los sucesivos valores pares que
toma su variable i privada y diferente a la del proceso padre.
Compile el el programa, haciendo uso del comando gcc.
Responda a las siguientes preguntas:
_Las variables enteras i y j del proceso padre son las mismas que las del proceso
hijo?
_Qu cambios deberan realizarse en el cdigo para que ambos procesos partieran de
igual valor de la variable entera i, y adems un proceso realice su cuenta de uno en
uno y el otro proceso de dos en dos? Editar el programa, compilarlo y comprobar su
ejecucin.

_Sistemas Operativos_

_24-09-2015_

Practica 4_ Espera del Proceso Padre al Proceso Hijo


En el siguiente programa, emplea la llamada al sistema wait. Esta llamada provoca que el
proceso invocador quede en suspenso hasta que concluya algn proceso hijo que haya sido
activado por l mismo.
------------------------------------------------------------------------------------------------/*
* File:
pwait1.c
* Author: logan
*
* Created on 23 de septiembre de 2015, 08:27 PM
*/
#include <stdio.h>
#include <stdlib.h>

int main() {
pid_t pid;
pid = fork();
switch (pid) {
case -1:
printf("\nERROR.- No se ha podido crear el proceso hijo.-");
break;
case 0:
printf("\nSoy el Proceso Hijo, mi PID es %d y mi PPID es %d\n", getpid(), getppid());
sleep(10);
break;
default:
printf("\nSoy el Proceso Padre, mi PID es %d y el PID de mi Hijo es: %d\n", getpid(), pid);

wait(0);

}
printf("\nFinal de ejecucion de %d \n", getpid());
return (EXIT_SUCCESS);

Compile y ejecute el programa anterior con el comando gcc.


Modifique el cdigo del programa anterior para que el proceso padre imprima el mensaje de
finalizacin de su ejecucin 10 segundos ms tarde que el proceso hijo.
Modifique el programa para que haga una ejecucin sin espera, es decir no se emplea la
llamada al sistema wait. Verifique cual es el PPID del proceso hijo, una vez el padre ha
finalizado.- Por qu?

Practica 5_ Jerarqua de Procesos 1


A continuacin se le presenta un programa escrito es C; dibuje la jerarqua de procesos que
resulta tras su ejecucin.

------------------------------------------------------------------------------------------------_Sistemas Operativos_

_24-09-2015_

/*
* File:
jfork1.c
* Author: logan
*
* Created on 23 de septiembre de 2015, 10:24 AM
*/
#include
#include
#include
#include
#include

<stdio.h>
<stdlib.h>
<unistd.h>
<sys/types.h>
<sys/wait.h>

int main(int argc, char** argv) {


int num;
pid_t pid;
for (num = 0; num < 3; num++) {
pid = fork();
printf("Soy el proceso de PID %d y mi Proceso Padre tiene el %d como PID.-\n",
getpid(), getppid());
if (pid != 0)
break;
srandom(getpid());
sleep(random() % 3);
}
if (pid != 0)
printf("Fin del proceso de PID %d.\n", wait(NULL));
return (EXIT_SUCCESS);
}
-------------------------------------------------------------------------------------------------

Compile el programa utilizando del comando gcc y ejectelo.


Responda a las siguientes preguntas:
_Por qu al ejecutar el programa aparecen mensajes repetidos?
_Preste especial atencin al orden de terminacin de los procesos.- Qu observa? y Por
que?

Practica 6_ Jerarqua de Procesos 2


Dibuje la estructura de la jerarqua de procesos que se obtiene al ejecutar el siguiente
fragmento de cdigo en C:
------------------------------------------------------------------------------------------------for (num = 0; num < 2; num++) {
pid = fork();
if (pid == 0)
break;
}
pid = fork();
pid = fork();
printf("Soy el proceso %d y mi padre es %d\n", getpid(), getppid());

_Sistemas Operativos_

_24-09-2015_

Practica 7_ Jerarqua de Procesos 3


Considere el siguiente fragmento de cdigo en lenguaje C:
------------------------------------------------------------------------------------------------for (num = 1; num <= n; num++) {
pid = fork();
if ((num == n) && (pid == 0))
execlp("ls", "ls", "-l", NULL);
}
-------------------------------------------------------------------------------------------------

_Dibuje la jerarqua de procesos que resulta cuando se ejecuta el cdigo y el valor de


n = 3.
_Indique en qu procesos se ha cambiado la imagen del proceso cuando se utiliza la
funcin execlp.

Practica 8_ Jerarqua de Procesos 4


Escriba un programa en lenguaje C, que genere la jerarqua de procesos como se muestra en la
siguiente figura. Los valores de profundidad y anchura de la jerarqua son dados como
parmetros en la linea de comandos por el usuario en cada ejecucin.

Profundidad 5

Anchura 3

Modifique el programa anterior para que la


expansin de la anchura de la jerarqua se produzca
solamente en aquellos niveles de profundidad par
(y distinta de cero).

Practica 9_ Procesos Hijos


Escriba un programa que reciba a travs de la lnea de comandos del sistema operativo el
nmero de procesos hijos que debe crear. Cada proceso hijo deber dormir un nmero aleatorio
de segundos comprendidos entre 0 y 30. El proceso padre debe esperar la terminacin de cada
hijo y, segn vayan stos terminando, presentar en pantalla el PID de cada uno de ellos y
el nmero de segundos que ha estado durmiendo cada proceso hijo. El nmero de segundos que
duerme cada hijo se debe generar internamente en el proceso hijo; es decir, el padre no
tiene conocimiento de este dato hasta que el hijo no termina su ejecucin y se lo comunica.

_Sistemas Operativos_

_24-09-2015_

También podría gustarte