Operaciones sobre procesos

De Departamento de Informatica
Revisión a fecha de 02:57 20 sep 2012; Abruna (Discusión | contribuciones)
(dif) ← Revisión anterior | Revisión actual (dif) | Revisión siguiente → (dif)
Saltar a: navegación, buscar

Los sistemas operativos son responsables de la "gestión de procesos y memoria", por lo que están encargados de realizar una serie de actividades, tales como la planificación o itineración de procesos, la operación sobre procesos y la comunicación entre procesos. Para operar sobre un proceso, los sistemas operativos actuales suministran ciertas funciones, que pueden ser ejecutadas ya sea desde el mismo proceso o desde el intérprete de comandos, si es un usuario el que solicita algún servicio de dicho sistema.

Entre las operaciones sobre procesos que con mayor frecuencia ofrecen los sistemas operativos se encuentran la creación, terminación o destrucción, suspensión y reanudación de procesos. Actualmente, en la mayoría de los S.O., los procesos pueden ejecutarse de forma concurrente, pudiéndose crear y eliminar de forma dinámica, por lo que es necesario que estos sistemas brinden un mecanismo para la creación y terminación de procesos.

Contenido

Creación de procesos

Durante la ejecución de un proceso, éste puede crear otros procesos. Si lo hace, el proceso creador es llamado proceso padre, y el creado, proceso hijo. Estos último pueden, a su vez, crear otros procesos, construyendo así un árbol de procesos.

Hay 4 eventos comunes que conducen a la creación de procesos:

  • En un ambiente batch, un proceso es creado en respuesta al sometimiento a ejecución de un trabajo (job). El S.O. tomará el próximo trabajo a ser ejecutado y creará el respectivo proceso.
  • En un ambiente interactivo, un proceso es creado cuando un nuevo usuario entra al sistema (log on). El S.O crea un proceso shell que espera las órdenes del usuario.
  • El S.O. puede crear un proceso para que realice una función en respuesta a una petición de un programa usuario, sin que el usuario tenga que esperar. Por ejemplo, si un usuario quiere que se imprima un archivo, el S.O. puede crear un proceso que maneje esta impresión, mientras que el proceso que realizó la petición puede continuar independientemente del tiempo requerido para completar la impresión.
  • Para procesos de modularidad o para explotar paralelismo, donde un programa usuario ya existente puede crear un conjunto de procesos hijos.

Además, crear un proceso implica varias operaciones, entre ellas:

  • Buscarle un identificador: la mayoría de los sistemas operativos, incluyendo los UNIX y Windows, identifican los procesos mediante un identificador unívoco que normalmente es un número entero, es decir, cada proceso (padre e hijo) es identificado por un id o PID (process identifier) distinto para cada uno.
  • Determinar la prioridad inicial del proceso.
  • Crear el PCB: el S.O. busca un hueco libre en la lista de PCB, y cuando lo encuentra crea el PCB del proceso.
  • Asignar recursos iniciales al proceso: por ejemplo, establecer su contexto de memoria (espacio de direcciones) y de CPU (registros), los archivos a usar y los dispositivos de E/S.
  • Insertarlo en la cola de procesos.

Relación entre procesos padres e hijos

Ejemplo de jerarquía de procesos en UNIX

Hay varias formas y criterios por lo que los hijos se relacionan con sus padres, estos son:

Jerarquía

Puede ser de dos tipos:

  1. Estructura jerárquica: cada proceso que se crea es hijo del proceso creador, y hereda el entorno de ejecución de su padre, estableciéndose un árbol de procesos como se mencionó anteriormente, donde cada hijo tiene sólo un padre, pero un padre puede tener más de un hijo. La estructura jerárquica se llevará a cabo por medio de la información adecuada insertada en el PCB del proceso padre.
  2. Estructura no jerárquica: consiste en que cada proceso creado por otro se ejecute independientemente de su creados, con un entorno totalmente diferente.

Recursos

Los recursos físicos y lógicos asignados a los procesos pueden venir de parte del sistema operativo o bien se limitan recibiendo una serie de recursos del padre (ficheros, dispositivos, memoria compartida,...), lo cual ayuda para no sobrecargar el sistema creando procesos hijos. Por lo tanto la relación puede ser:

  1. Padre e hijo comparten todos sus recursos
  2. El padre le comparte un subconjunto de sus recursos a sus hijos.
  3. Padre e hijo no comparten recursos.

Ejecución

El proceso padre puede entregarle, además de sus recursos a sus procesos hijos, parámetros iniciales para ayudarlo a completar tareas. Por lo cual existen dos escenarios en la ejecución:

  1. El proceso padre se ejecuta de forma simultánea o concurrente con su proceso hijo, o bien
  2. Espera que sus hijos (o parte de ellos) se terminen para poder continuar.

Espacio Direccionable

Con respecto al padre, el hijo puede ser:

  1. Una réplica, clon o duplicado de su padre: se copia el espacio del creador para el creado, compartiendo el mismo código, datos, etc., o
  2. Un nuevo programa: el proceso creado inicia un programa diferente al del creador, es decir, tiene su propio programa cargado.

Funciones para la creación de procesos

Existen varias llamadas al sistema utilizadas para la creación de procesos. En el caso de los sistemas UNIX, entre las más conocidas se encuentran:

Representación gráfica de la función fork(), donde se crea un proceso hijo al que se le carga un nuevo programa con exec().
  • fork( ): llamada a sistema para la creación de procesos, donde el hijo es una copia exacta del padre, salvo por el PID y la memoria que ocupan (las variables son independientes. Ésta permite que el proceso hijo copie el espacio de direcciones de su padre, por lo que tienen las mismas variables y ficheros abiertos. Esta llamada al sistema retorna 0 si el proceso es un hijo, al padre le retorna un entero positivo (que representa el PID del hijo) o un entero negativo que indica un error en la creación del proceso.
  • exec( ): produce la sustitución del programa invocados por el nuevo programa invocado, cambia el espacio de memoria del proceso por un nuevo programa. Sustituye todos los elementos del proceso: código del programa, datos, etc.). La combinación de las llamadas fork y exec es el mecanismo que ofrece UNIX para crear un nuevo proceso (fork) que ejecute un programa determinado (exec).
  • wait( ): sirve para que el padre se ponga en espera hasta que su o sus procesos hijos finalicen sus tareas, permitiendo la sincronización del padre con el hijo.
  • clone(): llamada similar a fork(), pero mucho más genérica y flexible, ya que permite definir qué van a compartir los procesos padre e hijo.

Para el caso de los sistemas Windows, la creación de procesos se hace a través de la función CreateProcess(), que es similar a fork() en el sentido de que un padre crea un nuevo proceso hijo, con la diferencia que con fork() el proceso hijo hereda el espacio de direcciones de su padre y con CreateProcess() se necesita cargar un programa específico en el espacio de las direcciones del proceso hijo durante su creación.

Terminación de procesos

Un proceso acaba cuando termina de ejecutar su último enunciado y le pide al S.O. que lo elimine. Destruir o terminar un proceso implica eliminarlo del sistema: se le borra de las tablas o listas de procesos, sus recursos reutilizables se devuelven al sistema y su PCB se borra, es decir, el espacio de memoria ocupado por su PCB se devuelve al espacio de memoria disponible. Como es de esperar, el término de un proceso es más difícil cuando éste ha creado otros procesos. En algunos sistemas un proceso hijo se destruye automáticamente cuando su padre ha terminado, creando terminaciones en cascada, que son iniciadas normalmente por el sistema operativo. En otros sistemas, los procesos creados son independientes de sus padres, por lo que la destrucción de éste no afecta sobre sus hijos.

En un sistema UNIX, un proceso se termina con la llamada al sistema exit( ) (ExitProcess() en Windows), proveniente del proceso mismo o de su padre, que permite que se liberen todos los recursos asignados previamente. En el momento en que se hace esta llamada, el proceso puede devolver un valor de estado a su proceso padre (un entero normalmente) a través de la llamada al sistema wait(). El S.O. libera la asignación de todos los recursos del proceso, incluyendo las memorias física, virtual, los archivos abiertos y los búfer de E/S.

Al llamar a la función exit() un proceso padre puede esperar a la terminación de sus procesos hijos usando la llamada al sistema wait(), que devuelve el identificador de un proceso hijo completado, con el fin de que el padre sepa cuál de sus hijos ha terminado. Sin embargo, si el proceso padre ha terminado, a todos sus procesos hijos se les asigna un proceso init como nuevo padre, evitando la eliminación en cascada.

Algunas de las razones por la que se termina un proceso son:

  • Un proceso hijo sobrepasa el límite de recursos que le fueron asignados.
  • Las tareas de un proceso ya no son necesarias.
  • El padre finaliza, por lo que su hijo también.
  • La ocurrencia de un error irrecuperable o no controlado.
  • Excede el tiempo límite.
  • Errores aritméticos.
  • Fallas de E/S.
  • Instrucciones inválidas.

Suspensión y reanudación de procesos

Un proceso suspendido o bloqueado no puede proseguir sino hasta ser reanudado por otro proceso. Generalmente, es el S.O. el que se encarga de eliminar temporalmente ciertos procesos con el fin de reducir la carga del sistema durante una situación crítica. Normalmente, los procesos son suspendidos durante periodos pequeños para disminuir la exigencia al sistema, pero también hay casos en que ocurren suspensiones más largas, en las que es posible liberar los recursos del proceso para poder utilizarlos durante ésta. Según la naturaleza del recurso, se toma la decisión de liberarlo o no: la memoria principal debe ser liberada de inmediato cuando se suspenda un proceso; una unidad de cinta puede ser retenida brevemente por un proceso suspendido, pero debe ser liberada si el proceso se suspende por un periodo largo o indefinido. Reanudar (o activar) un proceso implica reiniciarlo a partir del punto en el que se suspendió.

La suspensión y reanudación de procesos son importantes y han sido puestas en práctica en diferentes sistemas. Estas operaciones pueden ser de gran necesidad en casos como:

  • Si un sistema está funcionando mal, y es probable que falle, se puede suspender los procesos activos para reanudarlos cuando se haya corregido el problema.
  • Un usuario que desconfíe de los resultados parciales de un proceso puede suspenderlo (en lugar de abortarlo) hasta que verifique si el proceso funciona correctamente o no.
  • Algunos procesos se pueden suspender como respuesta a las fluctuaciones a corto plazo de la carga del sistema, y reanudarse cuando las cargas vuelvan a niveles normales.

Ejemplo

Código

Ejemplo Creacion de Procesos en UNIX

    #include <sys/types.h>
    #include <sys/wait.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    int main (int argc, char ∗argv[]){
         int num;
         pid_t pid;
         for(num = 0; num < 3; num++) 
         {
              pid= fork(); //Crea el proceso hijo
              printf("Soy el proceso de PID %d y mi padre tiene%d de PID.\n",getpid(), getppid());
              if(pid != 0) //ve si el proceso hijo termino de ejecutarse
              break; 
              srandom(getpid());
              sleep(random() %3);
         }
         if(pid!= 0)
         printf ("Fin del proceso de PID %d.\n", wait (NULL));
         return 0;
    }

Ejemplo Eliminacion de Procesos en UNIX

    #include <sys/types.h>
    #include <stdio.h>
    main() 
    {
         int pid;
         if(fork()==0){            /* hijo */
              fprintf(stdout, "hijo %d\n", getpid());
              sleep(3);
              exit(0);                   /* termina el proceso*/
              }else{                        /* padre */
              fprintf(stdout, "padre %d\n", getpid());
              pid = wait(NULL);            /* espera que finalice cualquier hijo */
              fprintf(stdout, "fin del hijo %d\n", pid);
              }
         exit(0);
    }

Tipo certamen

Certamen 1, segundo semestre 2009, profesor Javier Cañas:

¿Cuántos procesos crea el siguiente programa?


    #include <stdio.h>
    #include <unistd.h>
    
    int main()
    {
         fork();   /*F1*/
         fork();   /*F2*/
         fork();   /*F3*/
         fork();   /*F4*/
         return 0; 
    }


Respuesta: 15.....

Solución método 1

Fork1.jpg


  • El padre (P1) crea 4 procesos (fork F1, F2, F3 y F4).
    • El primer hijo (P2) crea 3 procesos (fork F2, F3 y F4).
      • Su primer hijo (P6) crea 2 procesos (fork F3 y F4).
        • Su hijo (P12) crea 1 proceso (fork F4).
          • Su hijo (P16) no crea proceso alguno.
        • Su otro hijo(P13) no crea proceso alguno.
      • Su segundo hijo (P7) crea 1 proceso (fork F4).
        • Su hijo (P14) no crea proceso alguno.
      • Su tercer hijo (P8) no crea proceso alguno.
    • El segundo hijo (P3) crea 2 procesos (fork F3 y F4).
      • Su hijo (P9) crea 1 proceso (fork F4).
        • Su hijo (P15) no crea proceso alguno.
      • Su otro hijo (P10) no crea proceso alguno.
    • Su tercer hijo (P4) crea 1 proceso (fork F4).
      • Su hijo (P11) no crea proceso alguno.
    • Su cuarto hijo (P5) no crea proceso alguno.

Por lo tanto, se han creado 15 procesos.

En general, se crean 2n − 1 procesos nuevos, donde n es el número de llamadas fork( ) que están presentes.

Solución método 2

Fork2.jpg

Otra forma, es entendiendo cómo funciona la función fork(): cuando un proceso hace la llamada, éste se "divide" en dos sub procesos: en "él mismo" y en un hijo idéntico a él (como se ve en la representación gráfica más arriba). Así, con cada llamada fork() el proceso se separa en el mismo padre (nodos blancos) y un hijo (nodos negros). Todos los procesos en negro son los que se han creado con la llamada al sistema, y, al contarlos, se ve que son 15.

Este método sirve para ver también el nivel de profundidad n (veces que se ha aplicado el fork) en el que estamos, ya que cada piso del árbol, representa una nueva llamada.

Referencias

Herramientas personales
Espacios de nombres
Variantes
Acciones
Navegación
Herramientas