Está en la página 1de 8

SISTEMAS OPERATIVOS

SERVICIOS PARA LA GESTIN DE PROCESOS

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);

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>

MIGUEL PAGUAY

extern char **environ; int main(int argc, char **argv { 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: HO ME: 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, lafuncin 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);

} Creacin de procesos:

MIGUEL PAGUAY

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 piladel 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 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 qu esta en la misma zona de memoria. El tiempo de ejecucin del proceso hijo es igual a cero. Toda la alarma pendiente se desactiva en el proceso hijo. El conjunto de seales pendientes se pone en cero.

MIGUEL PAGUAY

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 eimagen 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. Esto hace que el hijo tenga acceso a los archivos abiertos por el proceso padre. El padre y el hijo comparten el puntero de posicin de los archivos abiertos en el padre. Ejemplo: Programa que crea un proceso

#include <sys/types.h> #include <stdio.h> #include <unistd.h> #include <sys/wait.h> int main(){ pid_t pid; pid = fork(); if(pi d== 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());

MIGUEL PAGUAY

// 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()); }

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.intpthread_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)

MIGUEL PAGUAY

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.

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); exit(0); }

/* Ejemplo

MIGUEL PAGUAY

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 <uni std.h> #define MAX_THREADS 10void *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 pr ocesos 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{

MIGUEL PAGUAY

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); pth read_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); while(1){ printf("Escribir numero entero : \ n"); scanf("%d", &num); /* espera */ pthread_create(&thid, &attr, &imprimir, &num); } }

MIGUEL PAGUAY