Download Capitulo 2. Procesos

Document related concepts

Proceso (informática) wikipedia , lookup

Bomba fork wikipedia , lookup

Bifurcación (sistema operativo) wikipedia , lookup

Núcleo (informática) wikipedia , lookup

Hilo de ejecución wikipedia , lookup

Transcript
Sistemas Operativos
PROCESOS
Un proceso es un programa que se encuentra en ejecución. Un proceso no sólo es una copia del programa, sino que el núcleo le añade: un segmento de texto, un segmento de datos y un segmento de pila. Desde un punto de vista funcional, un proceso en UNIX es la entidad que se crea tras la llamda fork. Todos los procesos, excepto el proceso cero, son creados de esta forma. El proceso que llama a fork se conoce como el proceso padre y el proceso creado es el proceso hijo. El núcleo identifica cada proceso mediante un PID ( process identification), que es un número asociado a cada proceso, y que no cambia durante su tiempo de vida.
Partes claves de los sistemas operativos
•
•
•
•
•
Los procesos
La gestión de memoria
La seguridad y la protección de la información
La planificación y la gestión de recursos
La estructura del sistema
Los errores frecuentes en los procesos son:
•
•
•
•
Sincronización incorrecta: Es frecuente el caso en el que una rutina debe ser suspendida a la espera de un suceso en cualquier lugar del sistema. Por ejemplo, un programa inicia una lectura de E/S y debe esperar hasta que los datos están disponibles en un buffer antes de continuar. En tales casos se requiere alguna señal proveniente de alguna otra rutina.
Fallos de exclusión mutua: Es habitual el caso en que más de un usuario o programa intenta a la vez hacer uso de un recurso compartido. Por ejemplo, en un sistema de reservas de líneas aéreas. Si no se controlan estos accesos, puede producirse un error. Debe existir algún tipo de mecanismo de exclusión mutua que permita que sólo una rutina a la vez pueda realizar una transacción sobre una determinada parte de los datos.
Funcionamiento no determinista del programa: Los resultados de un programa en particular deben depender normalmente sólo de la entrada del programa y no de las actividades de otros programas en un sistema compartido. Pero cuando los programas comparten memoria y sus ejecuciones son intercaladas por el procesador, entonces pueden interferir con otros, sobre escribiendo zonas comunes de memoria de forma incierta. Así pues, el orden en que se organiza la ejecución de varios programas puede influir en los resultados de un programa en particular.
Interbloqueos: Es posible que dos o más programas estén suspendidos a la espera uno del otro.
1
Sistemas Operativos
El S.O. tiene cinco responsabilidades principales en la gestión de almacenamiento:
•
•
•
•
•
Aislamiento del proceso: El sistema operativo debe procurar que cada proceso independiente no interfiera con los datos y la memoria de ningún otro.
Asignación y gestión automática: A los programas se les debe asignar memoria dinámicamente en la jerarquía de memoria, según la vayan necesitando. Este proceso debe ser transparente para el programador. Soporte para la programación modular: Los programadores deben ser capaces de definir módulos de programa y de crear, destruir y alterar el tamaño de los módulos dinámicamente.
Protección y control de acceso: El s.o. debe permitir que las secciones de memoria estén accesibles de varias maneras para los diversos usuarios.
Almacenamiento a largo plazo: Muchos usuarios y aplicaciones necesitan medios para almacenar información por largos periodos de tiempo.
Normalmente, los s.o. satisfacen estos requisitos mediante la memoria virtual y los servicios del sistema de archivos. La memoria virtual es un servicio que permite a los programas direccionar la memoria desde un punto de vista lógico, sin depender del tamaño de la memoria principal física disponible.
El crecimiento de la utilización de los sistemas de tiempo compartido y, las redes de computadoras ha traído consigo un aumento en las preocupaciones de seguridad y protección de información. Se han identificado cuatro clases de políticas generales de protección, en orden creciente de dificultada:
•
•
•
No compartición: Los procesos están completamente aislados uno del otro y cada proceso tiene control exclusivo sobre los recursos que le fueron asignados estática o dinámicamente. Con esta política, los procesos suelen compartir los programas o archivos de datos haciendo copias y pasándolas a su propia memoria virtual.
Compartiendo los originales de los programas o archivos de datos: Una única copia física de un programa puede aparecer en varios espacios de memoria virtual como archivos de sólo lectura. Subsistemas confinados o sin memoria: En este caso, los procesos se agrupan en subsistemas para cumplir una política de protección en particular. Por ejemplo, un proceso “cliente” llama a un proceso “servidor” para llevar a cabo cierta tarea con los datos. El servidor se protegerá de que el cliente descubra el algoritmo con el cual se lleva a cabo su trabajo y el cliente se protegerá de que el servidor retenga alguna información sobre el trabajo que está llevando a cabo.
2
Sistemas Operativos
•
•
•
•
Diseminación controlada de la información: A los usuarios y a las aplicaciones se les dan credenciales de seguridad de un cierto nivel, mientras que a los datos y a otros recursos (p.e. los dispositivos de E/S) se les dota de clasificaciones de seguridad. La política de seguridad hace cumplir las restricciones relativas a qué usuarios tiene acceso a qué clasificaciones.
Control de acceso: Tiene que ver con la regulación del acceso del usuario al sistema completo, a los subsistemas y a los datos, así como a regular el acceso de los procesos a los recursos y objetos del sistema.
Control del flujo de información: Regula el flujo de datos dentro del sistema y su distribución a los usuarios.
Certificación: Es relativa a la demostración de que el acceso y los mecanismos de control del flujo se llevan a cabo de acuerdo a las especificaciones y a que estas cumplen las políticas de protección y seguridad deseadas.
Una tarea clave del s.o. es administrar los recursos que tiene disponibles y planificar su utilización por parte de los diferentes procesos activos. Cualquier política de planificación y gestión de recursos cuenta con los tres factores siguientes:
•
•
•
Equidad: Sería conveniente que a todos los procesos que compitan por el uso de un recurso se les otorgue un acceso igualitario y equitativo, especialmente si estos procesos pertenecen a la misma clase.
Sensibilidades diferenciales: El sistema operativo debe intentar tomar decisiones de asignación y planificación que satisfagan la totalidad de los requisitos. El s.o. debe contemplar estas decisiones dinámicamente. Por ejemplo, si un proceso está esperando por el uso de un dispositivo de E/S, el s.o. puede querer planificar la ejecución de dicho proceso tan pronto como sea posible y así tener disponible al dispositivo para las demandas de otros procesos.
Eficiencia: El s.o. debe intentar maximizar la productividad, minimizar el tiempo de respuesta y, en el caso de tiempo compartido, alojar a tantos usuarios como sea posible.
La tarea de planificación y gestión de recursos es básicamente un problema de investigación operativa, así que se pueden aplicar los resultados matemáticos de esta disciplina. Hablemos ahora de la parte clave de un s.o. la estrucura del sistema. El tamaño de un s.o. completo y la dificultad de las tareas que lleva a cabo plantean tres problemas desafortunados pero demasiado habituales:
• Los s.o. cuando se entregan ya están cronológicamente retrasados. Esto conduce a nuevos s.o. y actualizaciones de los anteriores.
• Los sistemas tienen fallos latentes que se manifiestan en el terreno y que deben ser detectados y corregidos.
3
Sistemas Operativos
•
Su rendimiento no es a menudo el que se esperaba.
4
Sistemas Operativos
Jerarquía del Diseño de un Sistema Operativo
Nivel
13
12
11
10
9
8
7
6
5
4
3
2
1
•
Nombre
Shell
Objetos
Entorno de programación del usuario.
Procesos de usuario.
Ejemplos de operaciones
Sentencias de un lenguaje de shell
Procesos de Salir, eliminar, suspender, usuario
reanudar.
Directorios
Directorios.
Crear, destruir, conectar, desconectar, buscar, listar
Dispositivos
Dispositivos externos tales Crear, destruir, abrir, cerrar, leer, como impresoras, escribir
pantallas y teclados.
Sistema de Archivos.
Crear, destruir, abrir, cerrar, leer, archivos
escribir
Comunicacione Tubos (pipes).
Crear, destruir, abrir, cerrar, leer, s
escribir
Memoria Segmentos, páginas.
Leer, escribir, traer (fech)
virtual
Almacenamient Bloques de datos, canales Leer, escribir, asignar, liberar
o secundario de dispositivos.
local
Procesos Procesos primitivos, Suspender, reanudar, esperar, primitivos.
semáforos, colas de señalizar.
procesos listos.
Interrupciones Programas de tratamiento Invocar, enmascarar, de interrupciones.
desenmascarar, reintentar.
Procedimientos Procedimientos, pila de Marcar la pila, llamar, retornar.
.
llamadas, visualización.
Conjunto de Evaluación de la pila, Cargar, almacenar, sumar, restar, instrucciones
intérprete de bifurcar.
microprogramas, vectores de datos y escalares.
Circuitos Registros, puertas, buses, Borrar, transferir, activar, electrónicos
etc.
completar.
Descripción y control de procesos.
Todos los sistemas de multiprogramación (desde Windows NT hasta MVS) están construidos en torno al concepto de procesos.
5
Sistemas Operativos
El modelo más sencillo que puede construirse tiene en cuenta que, en un momento dado, un proceso puede estar ejecutándose en el procesador o no. Así pues, un proceso puede estar en uno de dos estados: Ejecución o No ejecución.
Entrar
No ejecución
•
Ejecución
Salir
Diagrama de transición de estados.
Aún en este modelo tan simple se puede apreciar algunos de los elementos del diseño del sistema operativo, cada proceso debe representarse de forma que el sistema operativo pueda seguirle la pista. Esto es, debe haber información relativa a cada proceso, incluyendo su estado actual y su posición en memoria. Aquellos procesos que no están ejecutándose tiene que guardarse en algún tipo de cola, para que esperen su turno de ejecución. Cola
Entrar
Expedir
Procesador
Salir
Interrumpir
•
Diagrama de colas.
Creación y terminación de procesos.
La vida de un proceso está limitada por su creación y su terminación.
Creación de procesos.
6
Sistemas Operativos
Cuando se añade un proceso a los que ya está administrando el s.o., hay que construir las estructuras de datos que se utilizan para administrar el proceso y asignar el espacio de direcciones que va a utilizar el proceso.
Existen cuatro sucesos comunes que llevan a la creación de un proceso:
•
•
•
•
En un entorno de trabajo por lotes , un proceso se crea como respuesta a la remisión de un trabajo.
En un entorno interactivo, se crea un proceso cuando un nuevo usuario intenta conectarse.
Proceso generado por un proceso existente. Creado por el S.O. para dar un servicio. Cuando un proceso genera otro, el proceso generador se conoce como proceso padre y el proceso generado es el proceso hijo. Normalmente, estos procesos “emparentados” necesitarán comunicarse y cooperar entre sí.
Terminación de procesos.
En cualquier sistema, debe haber alguna forma de que un proceso pueda indicar que ha terminado.
Razones para terminación de un proceso
Terminación normal
El proceso ejecuta una llamada a un servicio del SO que indica que ha terminado de ejecutarse.
Tiempo límite excedido
El proceso se ha ejecutado por más del límita especificado.
No hay memoria disponible.
El proceso necesita más memoria de la que el sistema le puede proporcionar.
Violación de límites.
El proceso trata de acceder a una posición de memoria a la que no le está permitido.
Error de protección.
El proceso intenta utilizar un recurso o un archivo que no le está permitido utilizar, o trata de utilizarlo de forma incorrecta, como escribir en un archivo que es sólo de lectura.
Error aritmético.
El proceso intenta hacer un cálculo prohibido, o trata de almacenar un número mayor del que el hardware acepta.
Tiempo máximo de espera El proceso ha esperado más allá del tiempo máximo rebasado.
especificado para que se produzca cierto suceso.
Fallo de E/S
Se produce un error en la entrada o la salida, tal como no encontrar un archivo, un fallo de lectura o escritura después de un número máximo de intentos.
Instrucción privilegiada.
El proceso intenta usar una instrucción reservada para el SO.
Intervención del operador o del SO. Por alguna razón el operador o el sistema operativo terminan con el proceso.
7
Sistemas Operativos
Terminación del padre.
Solicitud del padre.
Cuando un proceso padre finaliza, el SO. Puede diseñarse para terminar automáticamente con todos sus descendientes.
Un proceso padre tiene normalmente la autorización de terminar con cualquiera de sus descendientes.
/*** Aquí falta las funciones getuid, getpid, getppid **********/
Estado de un proceso (modelo de cinco estados)
Si todos los procesos estuvieran siempre listos para ejecutar, entonces la disciplina de cola propuesta anteriormente sería eficaz, sin embargo, aún en el simple ejemplo que se ha descrito, esta implementación no es adecuada: algunos procesos en el estado de No Ejecución están listos para ejecutar, mientras que otros están bloqueados, esperando a que termine una operación de E/S. Así pues, utilizando una cola sencilla, el distribuidos podría no seleccionar exactamente el proceso que está en el extremo más antiguo de la cola. Más bien, el distribuidos tendría que recorrer la lista buscando el proceso que no esté “no bloqueado” y que lleve más tiempo en la cola.
Una forma más natural de afrontar esta situación es dividir el estado de No Ejecución en dos estados: Listo y Bloqueado. De esta forma contamos ahora con cinco estados:
Ejecución. Proceso que está actualmente en ejecución.
Listo. Proceso que está preparado para ejecutar, en cuanto se le dé la oportunidad.
Bloqueado. Proceso que no puede ejecutarse hasta que se produzca cierto suceso, como la terminación de una operación de E/S.
Nuevo. Proceso que se acaba de crear, pero que aún no ha sido admitido por el sistema operativo en el grupo de procesos ejecutables.
Terminado. Proceso que ha sido excluido del grupo de procesos ejecutables, bien porque se detuvo o porque fue abandonado por alguna razón.
8
Sistemas Operativos
Figura 2­1. Diagrama de estado para un sistema operativo sencillo.
Un proceso puede moverse voluntariamente al estado bloqueado haciendo una llamada a una función como sleep. Tarea: Investigar los parámetros del comando ps
Creación de procesos y el fork de UNIX
UNIX crea los procesos a través de una llamada fork al sistema, copiado la imagen en memoria que tiene el proceso padre. El nuevo proceso recibe una copia del espacio de direcciones del padre. Los procesos continúan su ejecución en la instrucción que está después del fork.
La creación de dos procesos totalmente idénticos no es algo muy útil. El valor devuelto por fork es la característica distintiva importante que permite que el padre y el hijo ejecuten código distinto. El fork devuelve 0 al hijo y el ID del hijo, al padre.
Ejemplo: en el siguiente fragmento de código tanto el padre como el hijo ejecutan la instrucción de asignación x =1 después del regreso de fork.
#include <sys/types.h>
#include <unistd.h>
x = 0;
fork();
9
Sistemas Operativos
x = 1;
Ejemplo: Después de la llamada fork en el siguiente fragmento de código, los procesos padre e hijo imprimen sus ID de proceso.
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
pid_t hijo;
void main (void)
{
if ( (hijo = fork ( )) = = 0)
{
fprintf (stderr, “soy el hijo, ID= %ld\n”, (long)getpid());
/* el código del hijo va aquí */
} else if (hijo > 0)
{ fprintf (stderr, “soy el padre, ID = %ld\n”, (long)getppid());
/* el código del padre va aquí */
}
}
10
Sistemas Operativos
Ejemplo: El siguiente fragmento de código crea una cadena de n procesos.
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int i, n;
pid_t hijo;
void main (void)
{
for (I = 1; I < n; I++)
{
if (hijo = fork()) break; /* mientras no sea diferente de cero , ie, no exista error */
fprintf (stderr, “Este es el proceso %ld con padre %ld \n”, (long)getpid(), (long)getppid());
}
}
Ejemplo: El siguiente fragmento de código crea un abanico de procesos.
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int I, n;
pid_t hijo;
void main (void)
{
for (I = 1; I < n; I++)
{
if (hijo = fork() <=0) break; /* después que crea un proceso termina */
fprintf (stderr, “Este es el proceso %ld con padre %ld \n”, (long)getpid(), (long)getppid());
}
}
Fork crea procesos nuevos haciendo una copia de la imagen del padre en la memoria. El hijo hereda la mayor parte de los atributos del padre, incluyendo el ambiente y los privilegios. El hijo también hereda algunos de los recursos del padre, tales como los archivos y dispositivos abiertos.
11
Sistemas Operativos
No todos los atributos o recursos del padre son heredados por el hijo. Este último tiene un ID de proceso nuevo y, claro que es diferente del ID del padre. Los tiempos del hijo para el usos del CPU son iniciados a 0. El hijo no obtiene los bloqueos que el padre mantiene. Si el padre ha puesto una alarma, el hijo no recibe notificación alguna del momento en que ésta expira. El hijo comienza sin señales pendientes, aunque el padre las tenga en el momento en que se ejecuta el fork.
Aunque el hijo hereda la prioridad del padre y los atributos de la administración de procesos, tiene que competir con otros procesos, como entidad aparte, por el tiempo del procesador.
Llamada wait al sistema
¿Qué sucede con el proceso padre después de que éste crea un hijo? Tanto el padre como el hijo continúan la ejecución desde el punto donde se hace la llamada a fork. Si el padre desa esperar hasta que el hijo termine, entonces debe ejecutar una llamada a wait o a waitpid.
La llamada al sistema wait detiene el proceso que llama hasta que un hijo de éste termine o se detenga, o hasta que el proceso que la invocó reciba una señal. Wait regresa de inmediato si el proceso no tiene hijos o si el hijo termina o se detiene y aún no se ha solicitado la espera. int wait (int *stat_loc)
Si wait regresa debido a la terminación de un hijo, el valor devuelto es positivo e igual al ID de proceso de dicho hijo.
De lo contrario, wait devuelve –1 y pone un valor en errno.
Errno = ECHILD Errno = EINTR
indica que no existen procesos hijos a los cuales hay que esperar.
la llamada fue interrumpida por una señal.
stat_loc es un apuntador a una variable entera.
POSIX (Portable Operating System Environment for Computer Environments, IEEE) especifica los macros WIFEXITED, WEXITSTUS, WIFSIGNALED, WTERMSIG, WIFSTOPPED y WSTOPSIG para analizar el estado devuelto por el hijjo y que permanence guardado en *stat_loc.
El hijo regresa su estado llamando a exit, _exit o return.
Ejemplo: Programa que muestra el empleo de wait.
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
12
Sistemas Operativos
main()
{
pid_t hijo;
int estado;
if ( (hijo=fork()) == ­1)
{
perror ("fallo el fork");
exit (1);
}
else if (hijo == 0)
fprintf (stderr, "soy el hijo con pid = %ld \n", (long) getpid());
else if (wait(&estado) !=hijo)
fprintf (stderr, "una señal debio interrumpir la espera \n"); else
fprintf (stderr, "soy el padre con pid = %ld e hijo con pid = %ld\n",
(long)getpid(),(long)hijo);
exit(0);
} Descripción de procesos
El S.O. es el controlador de los sucesos que se producen en un sistema informático. Es el S.O. el que planifica y expide a los procesos para su ejecución en el procesador, el que asigna los recursos a los procesos y el que responde a las solicitudes de servicios básicos realizadas por los programas de usuario. Este concepto queda ilustrado en la figura 2­2.
Figura 2­2. Procesos y recursos.
Estructuras de control del sistema operativo
13
Sistemas Operativos
Si el S.O. va a administrar los procesos y los recursos, entonces tiene que disponer de información sobre el estado actual de cada proceso y de cada recurso. El método universal para obtener esta información es sencillo: el sistema operativo construye y mantiene tablas de información sobre cada entidad que esté administrando.
Figura 2­3. Estructura general de las tablas de control del sistema operativo.
Debemos tener claro que las tablas mostradas en la figura 2­3, deben estar enlazadas o disponer de referencias cruzadas de alguna manera. La memoria, la E/S y los archivos son administrados en nombre de los procesos, por lo que debe haber alguna referencia directa o indirecta a estos recursos en la tablas de procesos. Los archivos que son referidos en las tablas de archivos son accesibles a través de un dispositivo de E/S y, algunas veces, estarán en memoria principal o en memoria virtual.
Operaciones sobre procesos.
Los sistemas que administran procesos deben ser capaces de realizar ciertas operaciones sobre procesos y con ellos. Tales operaciones incluyen:
Crear un proceso
Destruir un proceso
Suspender un proceso
Reanudar un proceso
Cambiar la prioridad de un proceso
Bloquear un proceso
Despertar un proceso
Despachar un proceso
Permitir que un proceso se comunique con otro (comunicación entre procesos)
14
Sistemas Operativos
Crear un proceso implica operaciones tales como:
Dar un nombre al proceso
Insertarlo en la lista de procesos conocidos del sistema (o tabla de procesos)
Determinar la prioridad inicial del proceso
Crear el bloque de control de proceso
Asignar los recursos iniciales al proceso.
Llamada exec al sistema
La llamada for al sistema crea una copia del proceso que la llama. Muchas aplicaciones requieren que el proceso hijo ejecute un código diferente del de su padre. La familia exec de llamadas al sistema proporciona una característica que permite traslapar al proceso que llama con un módulo ejecutable nuevo. La manera tradicional de utilizar la combinación fork­exec es dejar que el hijo ejecute el exec para el nuevo programa mientras el padre continúa con la ejecución del código original.
Existen seis variaciones de la llamada exec al sistema, las cuales se distinguen por la forma en que son pasados los argumentos de la línea de comando y el ambiente, y por si es necesario proporcionar la ruta de acceso y el nombre del archivo ejecutable.
execl (execl, execlp y execle). Pasan los argumentos de la línea de comando como una lista y son útiles si se conoce el número de argumentos de la línea de comando en el momento de la compilación.
#include <unistd.h>
int execl (const char *path, const char *arg0, … , const char *argn, char * /*NULL*/);
int execle (const char *path, const char *arg0, … , const char *argn, char * /*NULL*/, const char *envp[]);
int execlp (const char *file, const char *arg0, … , const char *argn, char * /*NULL*/);
execv (execv, execvp y execve). Pasan los argumentos de la línea de comando en un arreglo de argumentos.
#include <unistd.h>
int execv (const char *path, const char *argv[]);
int execvp (const char *file, const char *argv[]);
15
Sistemas Operativos
int execve (const char *’path, const char *argv[], const char *envp[]);
Ejemplo: programa que crea un proceso para ejecutar ls –l.
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
main( )
{
pid_t hijo;
int estado;
if (( hijo = fork( )) = = ­1)
{
perror (“Error al ejecutar fork”);
exit (1);
}
else if (hijo = = 0)
{
if (execl (“/usr/bin/ls”, “ls”, “­l”, NULL) < 0)
{
perror (“Falla en la ejecución de ls”);
exit (1);
}
}
else if (hijo ! = wait (&estado))
perror (“Se presento una señal antes de la terminación del hijo”);
exit (0);
}
NOTA: la función perror muestra un mensaje con el error estándar seguido por el error de la última llamada al sistema o la biblioteca que lo produjo.
#include <stdio.h>
void perror (const char *s);
16
Sistemas Operativos
El DIAGRAMA de estado para los procesos de UNIX es bastante complejo.
El proceso se está ejecutando en modo usuario.
El proceso se está ejecutando en modo kernel.
El proceso no se está ejecutando, pero está listo para ejecutarse tan pronto como el kernel lo ordene.
El proceso está durmiendo cargado en memoria.
El proceso está listo para ejecutarse, pero el swapper (proceso 0) debe cargar el proceso en memoria antes de que el kernel pueda ordenar que pase a ejecutarse.
El proceso está durmiendo y el swappper ha descargado el proceso hacia una memoria secundaria (área de swap del disco) para crear espacio en la memoria principal donde poder cargar otros procesos.
El proceso está volviendo del modo kernel al modo usuario, pero el kernel se apropia del proceso y hace un cambio de contexto, pasando otro proceso a ejecutarse en modo usuario.
El proceso acaba de ser creado y está en un estado de transición; el proceso existe, pero ni está preparado para ejecutarse (estado 3), ni durmiendo (estado 4). Este estado es el inicial para todos los procesos, excepto el proceso 0.
El proceso ejecuta la llamada exit y pasa al estado zombi. El proceso ya no existe, pero deja para su proceso padre un registro que contiene el código de salida y algunos datos estadísticos tales como los tiempos de ejecución. El estado zombi es el estado final de un proceso.
17
Sistemas Operativos
18