36

En la actualidad es muy común que necesitemos que nuestro ordenador realice muchas labores al mismo tiempo. Para ello existen sistemas llamados multitarea o multiproceso, los cuales nos pueden ayudar a realizar ese tipo de cosas.  Hablemos un poco al respecto.

SISTEMA OPERATIVO MULTITAREA

Es aquel sistema que le permite al usuario realizar varios procesos al mismo tiempo. Permite prestar un buen servicio para atender varios usuarios y optimizar los recursos del sistema.

Facilita la programación.

Aprovecha los tiempos muertos del procesador cuando otros procesos requieren de entrada/salida.

Utiliza al máximo la CPU.

SISTEMA OPERATIVO MULTIPROCESO

Un sistema operativo multiproceso o multitarea es aquel que permite ejecutar varios procesos de forma concurrente, la razón es porque actualmente nuestras CPUs sólo pueden ejecutar un proceso cada vez. La única forma de que se ejecuten de forma simultánea varios procesos es tener varias CPUs (ya sea en una máquina o en varias, en un sistema distribuido).

EJEMPLO:

Supongamos que estamos en una máquina con un sistema operativo multiproceso (como UNIX; Windows NT, OS/2, NeXTStep …), y supongamos que queremos ejecutar el programa Ejecutame que ha sido compilado de forma estática.

Cuando introducimos en el indicador de comandos del shell (o lo lanzamos con un doble click del ratón) el nombre de un fichero ejecutable binario lo que ocurre es que un proceso del sistema (cargador) lo prepara para que posteriormente sea ejecutado. La función que realiza el cargador es:

Crea el BCP. Se le asigna un identificador (pid) y una prioridad base (como máximo la misma que para el usuario, y se le van asignando todos los recursos a excepción de la CPU.

Se le inserta en la tabla de procesos del sistema.

Se carga en memoria virtual. Cuando ya tiene todos los recursos asignados (menos la CPU) se pone el campo de estado del proceso del BCP en preparado y se le ingresa en la cola de procesos listos de la CPU. Al proceso del sistema que controla la cola de la CPU se llama planificador, que es el encargado de elegir que proceso será el siguiente a ocupar la CPU. La elección se realiza mediante prioridades.

El problema reside en que, si un proceso tiene una prioridad muy baja, puede darse el caso que nunca se ejecute. Para evitar esto se emplea un sistema de prioridades dinámicas, es decir, se irán aumentando las prioridades a medida que esperen en la cola. Los pasos del planificador serán los siguientes:

Asignar nuevas prioridades a los procesos en la cola de la CPU.

Elegir aquel proceso con prioridad más alta.

Poner el campo de estado del proceso elegido en ejecución.

Llamar a la rutina de cambio de contexto, que lo que hará será cargar el proceso en la CPU. Es decir, volcará el estado hardware en los registros de la CPU, el último registro a actualizar será el PC (contador de programa), para que la próxima instrucción a ejecutar sea la siguiente donde se quedó el proceso.

DESVENTAJA

En un sistema operativo tradicional (UNIX, OS/2) al emplear la llamada al sistema de creación de un nuevo proceso (fork en UNIX), lo que el sistema realiza es una copia exacta del padre en el hijo. Se crean 2 procesos iguales y a la hora de programar tendremos el mismo código para ambos procesos, por lo cual tendremos que saber que proceso se ejecuta en ese momento.

int espera;

if(fork()==0) printf(“Hola papa!!!!\n”);

wait(&espera);

El padre espera hasta que el hijo le salude. El problema reside en que, si el padre es un proceso grande, al crear el hijo tendrá que volcar todo su contenido en el hijo, y si éste no realiza una labor grande estaríamos perdiendo eficiencia.

Al ser padre e hijo dos procesos independientes, su comunicación y compartición de datos será complicada y poco eficiente. Normalmente se crea un proceso hijo para que realice una subtarea, sobre todo para aprovechar tiempo cuando se espera una E/S. Supongamos que realizamos un programa que adquiere ficheros vía red y va sumando la cantidad de datos obtenida, mientras los vamos editando. Necesitaremos:

Proceso que nos traiga los ficheros de la red.

Proceso que lance un editor cada vez que se traiga un fichero entero.

Proceso para que realice la suma de los ficheros.

Los problemas que surgen son:

Necesidad de semáforos para sincronizar los procesos:

Suma<- Traigo fichero -> Edito

Además necesitaremos una zona de memoria compartida de tamaño indeterminado (es decir varias zonas) para que el proceso que está en la red nos diga la cantidad de datos que son traídos.

Y, por supuesto, tenemos tres procesos iguales y con una complicada gestión.

Con este ejemplo se ven los problemas principales de los sistemas operativos multiproceso. Aunque aún falta un problema importante:

Cuando dos procesos (padre e hijo) se ejecutan de forma seguida en la CPU, al ser procesos iguales solo cambian algunos datos del BCP, por lo cual con una nueva gestión podríamos salvar algunas operaciones innecesarias.

Para solucionar estos problemas se han creado una serie de procesos ligeros llamados threads. Y es precisamente de ellos de quienes hablaremos en nuestra siguiente sesión.