Sistemas Operativos Unidad Temas 1 Introducción a los sistemas operativos. Subtemas 1.1 Definición y concepto. 1.2 Funciones y características. 1.3 Evolución histórica. 1.4 Clasificación. 1.5 Estructura (niveles o estratos de diseño). 1.6 Núcleo. 1.6.1 Interrupciones (FLIH). 1.6.2 Despachador(Scheduler). 1.6.3 Primitivas de comunicación(IPC). 2 Administración de procesos y del procesador. 2.1 2.2 2.3 2.4 Concepto de proceso. Estados y transiciones de los procesos Procesos ligeros (Hilos o hebras). Concurrencia y secuenciabilidad. 2.4.1 Exclusión mutua de secciones criticas. 2.4.2 Sincronización de procesos en S.C. 2.4.2.1 Mecanismo de semáforos. 2.4.2.2 Mecanismo de monitores. 2.4.3 Interbloqueo (DeadLock). 2.4.3.1 Prevención. 2.4.3.2 Detección. 2.4.3.3 Recuperación. 2.5 Niveles, objetivos y criterios de planificación. 2.6 Técnicas de administración del planificador. 2.6.1 FIFO 2.6.2 SJF 2.6.3 RR 2.6.4 Queves multi-level. 2.6.5 Multi-level feedback queves. 3 Administración de memoria. 3.1 Política y filosofía. 3.2 Memoria real. 3.2.1 Administración de almacenamiento. 3.2.2 Jerarquía. 3.2.3 Estrategia de administración de memoria. 3.2.4 Asignación contigua v.s. no contigua. 3.2.5 Multiprogramación de partición fija, partición variable, con intercambio de almacenamiento. 3.3 Organización de memoria virtual. 3.3.1 Evaluación de las organizaciones de almacenamiento. 3.3.2 Paginación. 3.3.3 Segmentación. 3.3.4 Sistemas de paginación segmentación. 3.4 Administración de memoria virtual. 3.4.1 Estrategias de administración. 3.4.2 Técnicas de reemplazo de páginas. 3.4.3 Paginación por demanda. 3.4.4 Paginación anticipada. 3.4.5 Liberación de página. 3.4.6 Tamaño de página. 4 Administración de entrada/salida. 4.1 Dispositivos y manejadores de dispositivos (device drivers). 4.2 Mecanismos y funciones de los manejadores de dispositivos (device drivers). 4.3 Estructuras de datos para manejo de dispositivos. 4.4 Operaciones de Entrada /salida. 5 Sistema de archivos. 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 Concepto. Noción de archivo real y virtual. Componentes de un sistema de archivos. Organización lógica y física. Mecanismos de acceso a los archivos. Manejo de espacio en memoria secundaria. Modelo jerárquico. Mecanismos de recuperación en caso de falla. 6 Protección y seguridad. 6.1 6.2 6.3 6.4 6.5 6.6 6.7 6.8 Concepto y objetivos de protección. Funciones del sistema de protección. Implantación de matrices de acceso. Protección basada en el lenguaje. Concepto de seguridad. Clasificaciones de la seguridad. Validación y amenazas al sistema. Cifrado. Unidad 1 Introducción a los sistemas operativos. 1.7 Definición y concepto. Un sistema operativo es el programa que oculta la verdad del hardware al programador y presenta una vista simple y agradable de los archivos nominados que pueden leerse y escribirse. Es sistema operativo resguarda al programador del hardware del disco y presenta una interfaz simple orientada al archivo, también disimula mucho del trabajo concerniente a interrupciones, relojes o cronómetros, manejo de memoria y otras características de bajo nivel. Desde su creación, las computadoras digitales han utilizado un sistema de codificación de instrucciones en sistema de numeración binaria, es decir con los 0S. Esto se debe a que los circuitos integrados funcionan con este principio, es decir, hay corriente o no hay corriente. En el origen de la historia de las computadoras ( hace unos cuarenta años), los sistemas operativos no existían y la introducción de un programa para ser ejecutado se convertía en un increíble esfuerzo que solo podía ser llevado a cabo por muy pocos expertos. Esto hacia que las computadoras fueran muy complicadas de usar y que se requiriera tener altos conocimientos técnicos para operarlas. Era tan complejo su manejo, que en algunos casos el resultado llegaba a ser desastroso. Además, el tiempo requerido para introducir un programa en aquellas grandes máquinas de lento proceso superaba por mucho el de ejecución y resultaba poco provechosa la utilización de computadoras para resolución de problemas prácticos. Se buscaron medios más elaborados para manipular la computadora, pero que a su vez simplificaran la labor del operador o el usuario. Es entonces cuando surge la idea de crear un medio para que el usuario pueda operar la computadora con un entorno, lenguaje y operación bien definido para hacer un verdadero uso y explotación de esta. Surgen los sistemas operativos. Un sistema operativo es el encargado de brindar al usuario una forma amigable y sencilla de operar, interpretar, codificar y emitir las ordenes al procesador central para que este realice las tareas necesarias y especificas para completar una orden. El sistema operativo, es el instrumento indispensable para hacer de la computadora un objeto útil. Bajo este nombre se agrupan todos aquellos programas que permiten a los usuarios la utilización de este enredo de cables y circuitos, que de otra manera serian difíciles de controlar. Un sistema operativo se define como un conjunto de procedimientos manuales y automáticos, que permiten a un grupo de usuarios compartir una instalación de computadora eficazmente. Existen diversas definiciones de lo que es un Sistema Operativo, pero no hay una definición exacta, es decir una que sea estándar; a continuación se presentan algunas: 1.- Se pueden imaginar un Sistema Operativo como los programas, instalados en el software o firmware, que hacen utilizable el hardware. El hardware proporciona la "capacidad bruta de cómputo"; los sistemas operativos ponen dicha capacidad de cómputo al alcance de los usuarios y administran cuidadosamente el hardware para lograr un buen rendimiento. 2.- Los Sistemas Operativos son ante todo administradores de recursos; el principal recurso que administran es el hardware del computador ;además de los procesadores, los medios de almacenamiento, los dispositivos de entrada/salida, los dispositivos de comunicación y los datos. 3.- Un Sistema Operativo es un programa que actúa como intermediario entre el usuario y el hardware del computador y su propósito es proporcionar el entorno en el cual el usuario pueda ejecutar programas. Entonces, el objetivo principal de un Sistema Operativo es, lograr que el sistema de computación se use de manera cómoda, y el objetivo secundario es que el hardware del computador se emplee de manera eficiente. 4.- Un Sistema Operativo es un conjunto de programas que controla la ejecución de programas de aplicación y actúa como una interfaz entre el usuario y el hardware de una computadora, esto es, un Sistema Operativo explota y administra los recursos de hardware de la computadora con el objeto de proporcionar un conjunto de servicios a los usuarios del sistema. En resumen, se podría decir que los Sistemas Operativos son un conjunto de programas que crean la interfaz del hardware con el usuario, y que tiene dos funciones primordiales, que son: o o Gestionar el hardware.- Se refiere al hecho de administrar de una forma más eficiente los recursos de la máquina. Facilitar el trabajo al usuario.-Permite una comunicación con los dispositivos de la máquina. El Sistema Operativo se encuentra almacenado en la memoria secundaria. Primero se carga y ejecuta un pedazo de código que se encuentra en el procesador, el cual carga el BIOS, y este a su vez carga el Sistema Operativo que carga todos los programas de aplicación y software variado. 1.2 Funciones y características. La función del sistema operativo es la de presentar al usuario con el equivalente de una máquina ampliada o máquina virtual que sea más fácil de programar que el hardware implícito. Interpreta los comandos que permiten al usuario comunicarse con el ordenador. Coordina y manipula el hardware de la computadora, como la memoria, las impresoras, las unidades de disco, el teclado o el mouse. Organiza los archivos en diversos dispositivos de almacenamiento, como discos flexibles, discos duros, discos compactos o cintas magnéticas. Gestiona los errores de hardware y la pérdida de datos. Servir de base para la creación del software logrando que equipos de marcas distintas funcionen de manera análoga, salvando las diferencias existentes entre ambos. Configura el entorno para el uso del software y los periféricos; dependiendo del tipo de máquina que se emplea, debe establecerse en forma lógica la disposición y características del equipo. Como por ejemplo, una microcomputadora tiene físicamente dos unidades de disco, puede simular el uso de otras unidades de disco, que pueden ser virtuales utilizando parte de la memoria principal para tal fin. En caso de estar conectado a una red, el sistema operativo se convierte en la plataforma de trabajo de los usuarios y es este quien controla los elementos o recursos que comparten. De igual forma, provee de protección a la información que almacena. Funciones de los sistemas operativos. 1.- Aceptar todos los trabajos y conservarlos hasta su finalización. 2.- Interpretación de comandos: Interpreta los comandos que permiten al usuario comunicarse con el ordenador. 3.- Control de recursos: Coordina y manipula el hardware de la computadora, como la memoria, las impresoras, las unidades de disco, el teclado o el Mouse. 4.- Manejo de dispositivos de E/S: Organiza los archivos en diversos dispositivos de almacenamiento, como discos flexibles, discos duros, discos compactos o cintas magnéticas. 5.- Manejo de errores: Gestiona los errores de hardware y la pérdida de datos. 6.- Secuencia de tareas: El sistema operativo debe administrar la manera en que se reparten los procesos. Definir el orden. (Quien va primero y quien después). 7.- Protección: Evitar que las acciones de un usuario afecten el trabajo que esta realizando otro usuario. 8.- Multiacceso: Un usuario se puede conectar a otra máquina sin tener que estar cerca de ella. 9.- Contabilidad de recursos: establece el costo que se le cobra a un usuario por utilizar determinados recursos. Características de los sistemas operativos. En general, se puede decir que un Sistema Operativo tiene las siguientes características: Conveniencia. Un Sistema Operativo hace más conveniente el uso de una computadora. Eficiencia. Un Sistema Operativo permite que los recursos de la computadora se usen de la manera más eficiente posible. Habilidad para evolucionar. Un Sistema Operativo deberá construirse de manera que permita el desarrollo, prueba o introducción efectiva de nuevas funciones del sistema sin interferir con el servicio. Encargado de administrar el hardware. El Sistema Operativo se encarga de manejar de una mejor manera los recursos de la computadora en cuanto a hardware se refiere, esto es, asignar a cada proceso una parte del procesador para poder compartir los recursos. Relacionar dispositivos (gestionar a través del kernel). El Sistema Operativo se debe encargar de comunicar a los dispositivos periféricos, cuando el usuario así lo requiera. Organizar datos para acceso rápido y seguro. Manejar las comunicaciones en red. El Sistema Operativo permite al usuario manejar con alta facilidad todo lo referente a la instalación y uso de las redes de computadoras. Procesamiento por bytes de flujo a través del bus de datos. Facilitar las entradas y salidas. Un Sistema Operativo debe hacerle fácil al usuario el acceso y manejo de los dispositivos de Entrada/Salida de la computadora. El software de aplicación son programas que se utilizan para diseñar, tal como el procesador de palabras, lenguajes de programación, hojas de cálculo, etc. El software de base sirve para interactuar el usuario con la máquina, son un conjunto de programas que facilitan el ambiente plataforma, y permite el diseño del mismo. El Software de base está compuesto por : o o o o Cargadores. Compiladores. Ensambladores. Macros. 1.3 Evolución histórica. Los Sistemas Operativos, al igual que el Hardware de los computadores, han sufrido una serie de cambios revolucionarios llamados generaciones. En el caso del Hardware, las generaciones han sido marcadas por grandes avances en los componentes utilizados, pasando de válvulas ( primera generación ) a transistores ( segunda generación ), a circuitos integrados ( tercera generación), a circuitos integrados de gran y muy gran escala (cuarta generación). Cada generación Sucesiva de hardware ha ido acompañada de reducciones substanciales en los costos, tamaño, emisión de calor y consumo de energía, y por incrementos notables en velocidad y capacidad. Generacion Cero (década de 1940) Los primeros sistemas computacionales no poseían sistemas operativos. Los usuarios tenían completo acceso al lenguaje de la maquina. Todas las instrucciones eran codificadas a mano. Primera Generacion (década de 1950) Los sistemas operativos de los años cincuenta fueron diseñados para hacer mas fluida la transición entre trabajos. Antes de que los sistemas fueran diseñados, se perdía un tiempo considerable entre la terminación de un trabajo y el inicio del siguiente. Este fue el comienzo de los sistemas de procesamiento por lotes, donde los trabajos se reunían por grupos o lotes. Cuando el trabajo estaba en ejecución, este tenia control total de la maquina. Al terminar cada trabajo, el control era devuelto al sistema operativo, el cual limpiaba y leía e iniciaba el trabajo siguiente. Al inicio de los 50's esto había mejorado un poco con la introducción de tarjetas perforadas (las cuales servían para introducir los programas de lenguajes de máquina), puesto que ya no había necesidad de utilizar los tableros enchufables. Además el laboratorio de investigación General Motors implementó el primer sistema operativo para la IBM 701. Los sistemas de los 50's generalmente ejecutaban una sola tarea, y la transición entre tareas se suavizaba para lograr la máxima utilización del sistema. Esto se conoce como sistemas de procesamiento por lotes de un sólo flujo, ya que los programas y los datos eran sometidos en grupos o lotes. La introducción del transistor a mediados de los 50's cambió la imagen radicalmente. Se crearon máquinas suficientemente confiables las cuales se instalaban en lugares especialmente acondicionados, aunque sólo las grandes universidades y las grandes corporaciones o bien las oficinas del gobierno se podían dar el lujo de tenerlas. Para poder correr un trabajo (programa), tenían que escribirlo en papel (en Fortran o en lenguaje ensamblador) y después se perforaría en tarjetas. Enseguida se llevaría la pila de tarjetas al cuarto de introducción al sistema y la entregaría a uno de los operadores. Cuando la computadora terminara el trabajo, un operador se dirigiría a la impresora y desprendería la salida y la llevaría al cuarto de salida, para que la recogiera el programador. Segunda Generacion (a mitad de la década de 1960) La característica de los sistemas operativos fue el desarrollo de los sistemas compartidos con multiprogramación, y los principios del multiprocesamiento. En los sistemas de multiprogramación, varios programas de usuario se encuentran al mismo tiempo en el almacenamiento principal, y el procesador se cambia rápidamente de un trabajo a otro. En los sistemas de multiprocesamiento se utilizan varios procesadores en un solo sistema computacional, con la finalidad de incrementar el poder de procesamiento de la maquina. La independencia de dispositivos aparece después. Un usuario que desea escribir datos en una cinta en sistemas de la primera generación tenia que hacer referencia especifica a una unidad de cinta particular. En la segunda generación, el programa del usuario especificaba tan solo que un archivo iba a ser escrito en una unidad de cinta con cierto numero de pistas y cierta densidad. Se desarrollo sistemas compartidos, en la que los usuarios podían acoplarse directamente con el computador a través de terminales. Surgieron sistemas de tiempo real, en que los computadores fueron utilizados en el control de procesos industriales. Los sistemas de tiempo real se caracterizan por proveer una respuesta inmediata. Tercera Generacion (mitad de década 1960 a mitad década de 1970) Se inicia en 1964, con la introducción de la familia de computadores Sistema/360 de IBM. Los computadores de esta generación fueron diseñados como sistemas para usos generales . Casi siempre eran sistemas grandes, voluminosos, con el propósito de serlo todo para toda la gente. Eran sistemas de modos múltiples, algunos de ellos soportaban simultáneamente procesos por lotes, tiempo compartido, procesamiento de tiempo real y multiprocesamiento. Eran grandes y costosos, nunca antes se había construido algo similar, y muchos de los esfuerzos de desarrollo terminaron muy por arriba del presupuesto y mucho después de lo que el planificador marcaba como fecha de terminación. Estos sistemas introdujeron mayor complejidad a los ambientes computacionales; una complejidad a la cual, en un principio, no estaban acostumbrados los usuarios. Cuarta Generacion (mitad de década de 1970 en adelante) Los sistemas de la cuarta generación constituyen el estado actual de la tecnología. Muchos diseñadores y usuarios se sienten aun incómodos, después de sus experiencias con los sistemas operativos de la tercera generación. Con la ampliación del uso de redes de computadores y del procesamiento en línea los usuarios obtienen acceso a computadores alejados geográficamente a través de varios tipos de terminales. Los sistemas de seguridad se ha incrementado mucho ahora que la información pasa a través de varios tipos vulnerables de líneas de comunicación. La clave de cifrado esta recibiendo mucha atención; han sido necesario codificar los datos personales o de gran intimidad para que; aun si los datos son expuestos, no sean de utilidad a nadie mas que a los receptores adecuados. El porcentaje de la población que tiene acceso a un computador en la década de los ochenta es mucho mayor que nunca y aumenta rápidamente. El concepto de maquinas virtuales es utilizado. El usuario ya no se encuentra interesado en los detalles físicos de; sistema de computación que esta siendo accedida. En su lugar, el usuario ve un panorama llamado maquina virtual creado por el sistema operativo. Los sistemas de bases de datos han adquirido gran importancia. Nuestro mundo es una sociedad orientada hacia la información, y el trabajo de las bases de datos es hacer que esta información sea conveniente accesible de una manera controlada para aquellos que tienen derechos de acceso. Historia de los Sistemas Operativos. Para tratar de comprender los requisitos de un Sistema Operativo y el significado de las principales características de un Sistema Operativo contemporáneo, es útil considerar como han ido evolucionando éstos con el tiempo. Existen diferentes enfoques o versiones de como han ido evolucionando los Sistemas Operativos La primera de estas versiones podría ser esta: En los 40's, se introducen los programas bit a bit, por medio de interruptores mecánicos y después se introdujo el leng. máquina que trabajaba por tarjetas perforadas. Con las primeras computadoras, desde finales de los años 40 hasta la mitad de los años 50, el programador interactuaba de manera directa con el hardware de la computadora, no existía realmente un Sistema Operativo; las primeras computadoras utilizaban bulbos, la entrada de datos y los programas se realizaban a través del lenguaje máquina (bits) o a través de interruptores. Durante los años 50's y 60's.- A principio de los 50's, la compañía General's Motors implanto el primer sistema operativo para su IBM 170. Empiezan a surgir las tarjetas perforadas las cuales permiten que los usuarios (que en ese tiempo eran programadores, diseñadores, capturistas, etc.), se encarguen de modificar sus programas. Establecían o apartaban tiempo, metían o introducían sus programas, corregían y depuraban sus programas en su tiempo. A esto se le llamaba trabajo en serie. Todo esto se traducía en pérdida de tiempo y tiempos de programas excesivos. En los años 60's y 70's se genera el circuito integrado, se organizan los trabajos y se generan los procesos Batch (por lotes), lo cual consiste en determinar los trabajos comunes y realizarlos todos juntos de una sola vez. En esta época surgen las unidades de cinta y el cargador de programas, el cual se considera como el primer tipo de Sistema Operativo. En los 80's, inició el auge de la INTERNET en los Estados Unidos de América. A finales de los años 80's comienza el gran auge y evolución de los Sistemas Operativos. Se descubre el concepto de multiprogramación que consiste en tener cargados en memoria a varios trabajos al mismo tiempo, tema principal de los Sistemas Operativos actuales. Los 90's y el futuro, entramos a la era de la computación distribuida y del multiprocesamiento a través de múltiples redes de computadoras, aprovechando el ciclo del procesador. Se tendrá una configuración dinámica con un reconocimiento inmediato de dispositivos y software que se añada o elimine de las redes a través de procesos de registro y localizadores. La conectividad se facilita gracias a estándares y protocolos de sistemas abiertos por organizaciones como la Org. Intern. de normas, fundación de software abierto, todo estará mas controlado por los protocolos de comunicación OSI y por la red de servicios digital ISDN. Se ha desarrollado otra versión, la cual se ha hecho en base a etapas o generaciones: 1a. Etapa (1945-1955) : Bulbos y conexiones. Después de los infructuosos esfuerzos de Babbage, hubo poco progreso en la construcción de las computadoras digitales, hasta la Segunda Guerra Mundial. A mitad de la década de los 40's, Howard Aiken (Harvard), John Von Newman (Instituto de Estudios Avanzados, Princeton), J. Prespe R. Eckert y Williams Mauchley (Universidad de Pennsylvania), así como Conrad Zuse (Alemania), entre otros lograron construir máquinas de cálculo mediante bulbos. Estas máquinas eran enormes y llenaban cuartos completos con decenas de miles de bulbos, pero eran mucho más lentas que la computadora casera más económica en nuestros días. Toda la programación se llevaba a cabo en lenguaje de máquina absoluto y con frecuencia se utilizaban conexiones para controlar las funciones básicas de la máquina. Los lenguajes de programación eran desconocidos (incluso el lenguaje ensamblador). No se oía de los Sistemas Operativos el modo usual de operación consistía en que el programador reservaba cierto período en una hoja de reservación pegada a la pared, iba al cuarto de la máquina, insertaba su conexión a la computadora y pasaba unas horas esperando que ninguno de los 20,000 o más bulbos se quemara durante la ejecución. La inmensa mayoría de los problemas eran cálculos numéricos directos, por ejemplo, el cálculo de valores para tablas de senos y cosenos. A principio de la década de los 50's la rutina mejoro un poco con la introducción de las tarjetas perforadas. Fue entonces posible escribir los programas y leerlas en vez de insertar conexiones, por lo demás el proceso era el mismo. 2a. Etapa. (1955-1965) : Transistores y Sistemas de Procesamiento por lotes. La introducción del transistor a mediados de los años 50's modificó en forma radical el panorama. Las computadoras se volvieron confiables de forma que podían fabricarse y venderse a clientes, con la esperanza de que ellas continuaran funcionando lo suficiente como para realizar un trabajo en forma. Dado el alto costo del equipo, no debe sorprender el hecho de que las personas buscaron en forma por demás rápidas vías para reducir el tiempo invertido. La solución que, por lo general se adoptó, fue la del sistema de procesamiento por lotes. 3ra Etapa (1965-1980 ) : Circuitos integrados y multiprogramación. La 360 de IBM fue la primera línea principal de computadoras que utilizó los circuitos integrados, lo que proporcionó una gran ventaja en el precio y desempeño con respecto a las máquinas de la segunda generación, construidas a partir de transistores individuales. Se trabajo con un sistema operativo enorme y extraordinariamente complejo. A pesar de su enorme tamaño y sus problemas el sistema operativo de la línea IBM 360 y los sistemas operativos similares de esta generación producidos por otros fabricantes de computadoras realmente pudieron satisfacer, en forma razonable a la mayoría de sus clientes. También popularizaron varias técnicas fundamentales, ausentes de los sistemas operativos de la segunda generación, de las cuales la más importante era la de multiprogramación. Otra característica era la capacidad de leer trabajos de las tarjetas al disco, tan pronto como llegara al cuarto de cómputo. Así, siempre que concluyera un trabajo el sistema operativo podía cargar un nuevo trabajo del disco en la partición que quedara desocupada y ejecutarlo. 4ta Etapa (1980-Actualidad) : Computadoras personales. Un interesante desarrollo que comenzó a llevarse a cabo a mediados de la década de los ochenta ha sido el crecimiento de las redes de computadoras personales, con sistemas operativos de red y sistemas operativos distribuidos. En los sistema operativo de red, los usuarios están conscientes de la existencia de varias computadoras y pueden conectarse con máquinas remotas y copiar archivos de una máquina a otra. Cada máquina ejecuta su propio sistema operativo local y tiene su propio usuario. Por el contrario, un sistema operativo distribuido es aquel que aparece ante sus usuarios como un sistema tradicional de un solo procesador, aun cuando esté compuesto por varios procesadores. En un sistema distribuido verdadero, los usuarios no deben ser conscientes del lugar donde su programa se ejecute o de lugar donde se encuentren sus archivos; eso debe ser manejado en forma automática y eficaz por el sistema operativo. 1.4 Clasificación. Sistema Operativo Multitareas. Es el modo de funcionamiento disponible en algunos sistemas operativos, mediante el cual una computadora procesa varias tareas al mismo tiempo. Existen varios tipos de multitareas. La conmutación de contextos (context Switching) es un tipo muy simple de multitarea en el que dos o más aplicaciones se cargan al mismo tiempo, pero en el que solo se esta procesando la aplicación que se encuentra en primer plano (la que ve el usuario). Para activar otra tarea que se encuentre en segundo plano, el usuario debe traer al primer plano la ventana o pantalla que contenga esa aplicación. En la multitarea cooperativa, la que se utiliza en el sistema operativo Macintosh, las tareas en segundo plano reciben tiempo de procesado durante los tiempos muertos de la tarea que se encuentra en primer plano (por ejemplo, cuando esta aplicación esta esperando información del usuario), y siempre que esta aplicación lo permita. En los sistemas multitarea de tiempo compartido, como OS/2, cada tarea recibe la atención del microprocesador durante una fracción de segundo. Para mantener el sistema en orden, cada tarea recibe un nivel de prioridad o se procesa en orden secuencial. Dado que el sentido temporal del usuario es mucho más lento que la velocidad de procesamiento del ordenador, las operaciones de multitarea en tiempo compartido parecen ser simultáneas. Sistema Operativo Monotareas. Los sistemas operativos monotareas son más primitivos y es todo lo contrario al visto anteriormente, es decir, solo pueden manejar un proceso en cada momento o que solo puede ejecutar las tareas de una en una. Por ejemplo cuando la computadora esta imprimiendo un documento, no puede iniciar otro proceso ni responder a nuevas instrucciones hasta que se termine la impresión. Sistema Operativo Monousuario. Los sistemas monousuarios son aquellos que nada más puede atender a un solo usuario, gracias a las limitaciones creadas por el hardware, los programas o el tipo de aplicación que se este ejecutando. Estos tipos de sistemas son muy simples, porque todos los dispositivos de entrada, salida y control dependen de la tarea que se esta utilizando, esto quiere decir, que las instrucciones que se dan, son procesadas de inmediato; ya que existe un solo usuario. Y están orientados principalmente por los microcomputadores. Sistema Operativo Multiusuario. Es todo lo contrario a monousuario; y en esta categoría se encuentran todos los sistemas que cumplen simultáneamente las necesidades de dos o más usuarios, que comparten mismos recursos. Este tipo de sistemas se emplean especialmente en redes. En otras palabras consiste en el fraccionamiento del tiempo (timesharing). Secuencia por Lotes. La secuencia por lotes o procesamiento por lotes en microcomputadoras, es la ejecución de una lista de comandos del sistema operativo uno tras otro sin intervención del usuario. En los ordenadores más grandes el proceso de recogida de programas y de conjuntos de datos de los usuarios, la ejecución de uno o unos pocos cada vez y la entrega de los recursos a los usuarios. Procesamiento por lotes también puede referirse al proceso de almacenar transacciones durante un cierto lapso antes de su envío a un archivo maestro, por lo general una operación separada que se efectúa durante la noche. Los sistemas operativos por lotes (batch), en los que los programas eran tratados por grupos (lote) en ves de individualmente. La función de estos sistemas operativos consistía en cargar en memoria un programa de la cinta y ejecutarlo. Al final este, se realizaba el salto a una dirección de memoria desde donde reasumía el control del sistema operativo que cargaba el siguiente programa y lo ejecutaba. De esta manera el tiempo entre un trabajo y el otro disminuía considerablemente. Tiempo Real. Un sistema operativo en tiempo real procesa las instrucciones recibidas al instante, y una vez que han sido procesadas muestra el resultado. Este tipo tiene relación con los sistemas operativos monousuarios, ya que existe un solo operador y no necesita compartir el procesador entre varias solicitudes. Su característica principal es dar respuestas rápidas; por ejemplo en un caso de peligro se necesitarían respuestas inmediatas para evitar una catástrofe. Tiempo Compartido. El tiempo compartido en ordenadores o computadoras consiste en el uso de un sistema por más de una persona al mismo tiempo. El tiempo compartido ejecuta programas separados de forma concurrente, intercambiando porciones de tiempo asignadas a cada programa (usuario). En este aspecto, es similar a la capacidad de multitareas que es común en la mayoría de los microordenadores o las microcomputadoras. Sin embargo el tiempo compartido se asocia generalmente con el acceso de varios usuarios a computadoras más grandes y a organizaciones de servicios, mientras que la multitarea relacionada con las microcomputadoras implica la realización de múltiples tareas por un solo usuario. CLASIFICACIÓN DE LOS SISTEMAS OPERATIVOS Los sistemas operativos se clasifican en: Sistemas operativos por lotes. Sistemas operativos multiprogramación o de multitarea. Sistemas operativos multiusuario. Sistemas operativos de tiempo compartido. Sistemas operativos de tiempo real. Sistemas operativos distribuidos. Sistemas operativos de red. Sistemas operativos paralelos. Sistemas operativos por lotes. Los sistemas operativos por lotes requieren que la información esté reunida en bloque o "lote" (el programa, los datos, y las instrucciones). Los trabajos son procesados en el orden de admisión, según el modelo de "primero en llegar primero en ser atendido". En estos sistemas la memoria se divide en dos zonas. Una de ellas es ocupada por el sistema operativo, y la otra se usa para cargar programas transitorios para su ejecución. Cuando termina la ejecución de un programa se carga un nuevo programa en la misma zona de memoria. Algunos ejemplos de Sistemas Operativos por lotes exitosos son el SCOPE, del DC6600, el cual está orientado a procesamiento científico pesado, y el EXEC II para el UNIVAC 1107, orientado a procesamiento académico. Algunas otras características con que cuentan los Sistemas Operativos por lotes son: Requiere que el programa, datos y órdenes al sistema sean remitidos todos juntos en forma de lote. Permiten poca o ninguna interacción usuario/programa en ejecución. Mayor potencial de utilización de recursos que procesamiento serial simple en sistemas multiusuarios. No conveniente para desarrollo de programas por bajo tiempo de retorno y depuración fuera de línea. Conveniente para programas de largos tiempos de ejecución (Ej., análisis estadísticos, nóminas de personal, etc.). Se encuentra en muchos computadores personales combinados con procesamiento serial. Planificación del procesador sencilla, típicamente procesados en orden de llegada. Planificación de memoria sencilla, generalmente se divide en dos: parte residente del S.O. y programas transitorios. No requieren gestión crítica de dispositivos en el tiempo. Suelen proporcionar gestión sencilla de manejo de archivos: se requiere poca protección y ningún control de concurrencia para el acceso. Figura. Trabajos más comunes que realiza el Sistema Operativo por lotes. Sistemas operativos multiprogramación o de multitareas. Los sistemas de multiprogramación son capaces de soportar dos o más procesos concurrentes múltiples, permiten que residan al mismo tiempo en la memoria primaria las instrucciones y los datos procedentes de dos o más procesos. Estos sistemas implican la operación de multiproceso, para el manejo de la información. Se caracterizan principalmente por un gran número de programas activos simultáneamente que compiten por los recursos del sistema, como el procesador, la memoria, y los "dispositivos de E/S". Estos sistemas monitorean el estado de todos los programas activos y recursos del sistema. Sistemas Operativos como UNIX, Windows 95, Windows 98, Windows NT, MAC-OS, OS/2, soportan la multitarea. Las características de un Sistema Operativo de multiprogramación o multitarea son las siguientes: Mejora productividad del sistema y utilización de recursos. Multiplexa recursos entre varios programas. Generalmente soportan múltiples usuarios (multiusuarios). Proporcionan facilidades para mantener el entorno de usuarios individuales. Requieren validación de usuario para seguridad y protección. Proporcionan contabilidad del uso de los recursos por parte de los usuarios. Multitarea sin soporte multiusuario se encuentra en algunos computadores personales o en sistemas de tiempo real. Sistemas multiprocesadores son sistemas multitareas por definición ya que soportan la ejecución simultánea de múltiples tareas sobre diferentes procesadores. En general, los sistemas de multiprogramación se caracterizan por tener múltiples programas activos compitiendo por los recursos del sistema: procesador, memoria, dispositivos periféricos. Sistemas operativos multiusuario. Los sistemas operativos multiusuario permiten acceder simultáneamente a un sistema de computadoras a través de dos o más terminales. Este tipo de sistema operativo es fundamental en el manejo de redes de computadoras actualmente. Sistemas operativos de tiempo compartido Los sistemas operativos de tiempo compartido tratan de proporcionar un reparto equitativo de los recursos comunes para dar la impresión a los usuarios de que poseen una computadora independiente. En estos sistemas el administrador de memoria proporciona aislamiento y protección de los programas, ya que generalmente no tienen necesidad de comunicarse entre ellos. El control de E/S se encarga de proporcionar o retirar la asignación a los dispositivos de forma que se preserve la integridad del sistema y se proporcione servicio a todos los usuarios. El administrador de archivos proporciona protección y control en el acceso de la información, dada la posibilidad de concurrencia y conflictos al tratar de acceder a los archivos. Ejemplos de Sistemas Operativos de tiempo compartido son Multics, OS/360 y DEC-10. Características de los Sistemas Operativos de tiempo compartido: Populares representantes de sistemas multiprogramados multiusuario, Ej.: sistemas de diseño asistido por computador, procesamiento de texto, etc. Dan la ilusión de que cada usuario tiene una máquina para sí. Mayoría utilizan algoritmo de reparto circular. Programas se ejecutan con prioridad rotatoria que se incrementa con la espera y disminuye después de concedido el servicio. Evitan monopolización del sistema asignando tiempos de procesador (time slot). Gestión de memoria proporciona protección a programas residentes. Gestión de archivo debe proporcionar protección y control de acceso debido a que pueden existir múltiples usuarios accesando a un mismo archivo. Sistemas operativos de tiempo real Los Sistemas Operativos de tiempo real son aquellos en los cuales no tiene importancia el usuario, sino los procesos. Por lo general, están subutilizados sus recursos con la finalidad de prestar atención a los procesos en el momento que lo requieran. Se utilizan en entornos donde son procesados un gran número de sucesos o eventos. Muchos Sistemas Operativos de tiempo real son construidos para aplicaciones muy específicas como control de tráfico aéreo, bolsas de valores, control de refinerías, control de laminadores. También en el ramo automovilístico y de la electrónica de consumo, las aplicaciones de tiempo real están creciendo muy rápidamente. Otros campos de aplicación de los Sistemas Operativos de tiempo real son los siguientes: Control de trenes. Telecomunicaciones. Sistemas de fabricación integrada. Producción y distribución de energía eléctrica. Control de edificios. Sistemas multimedia. Algunos ejemplos de Sistemas Operativos de tiempo real son: VxWorks, Solaris, Lyns OS y Spectra. Los Sistemas Operativos de tiempo real, cuentan con las siguientes características: Se dan en entornos en donde deben ser aceptados y procesados gran cantidad de sucesos, la mayoría externos al sistema computacional, en breve tiempo o dentro de ciertos plazos. Se utilizan en control industrial, conmutación telefónica, control de vuelo, simulaciones en tiempo real., aplicaciones militares, etc. Objetivo es proporcionar rápidos tiempos de respuesta. Procesa ráfagas de miles de interrupciones por segundo sin perder un solo suceso. Proceso se activa tras ocurrencia de suceso, mediante interrupción. Proceso de mayor prioridad expropia recursos. Por tanto generalmente se utiliza planificación expropiativa basada en prioridades. Gestión de memoria menos exigente que tiempo compartido, usualmente procesos son residentes permanentes en memoria. Población de procesos estática en gran medida. Poco movimiento de programas entre almacenamiento secundario y memoria. Gestión de archivos se orienta más a velocidad de acceso que a utilización eficiente del recurso. Sistemas Operativos distribuidos. Permiten distribuir trabajos, tareas o procesos, entre un conjunto de procesadores. Puede ser que este conjunto de procesadores esté en un equipo o en diferentes, en este caso es transparente para el usuario. Existen dos esquemas básicos de éstos. Un sistema fuertemente acoplado es a es aquel que comparte la memoria y un reloj global, cuyos tiempos de acceso son similares para todos los procesadores. En un sistema débilmente acoplado los procesadores no comparten ni memoria ni reloj, ya que cada uno cuenta con su memoria local. Los sistemas distribuidos deben de ser muy confiables, ya que si un componente del sistema se compone otro componente debe de ser capaz de reemplazarlo. Entre los diferentes Sistemas Operativos distribuidos que existen tenemos los siguientes: Sprite, Solaris-MC, Mach, Chorus, Spring, Amoeba, Taos, etc. Características de los Sistemas Operativos distribuidos: Colección de sistemas autónomos capaces de comunicación y cooperación mediante interconexiones hardware y software. Gobierna operación de un S.C. y proporciona abstracción de máquina virtual a los usuarios. Objetivo clave es la transparencia. Generalmente proporcionan medios para la compartición global de recursos. Servicios añadidos: denominación global, sistemas de archivos distribuidos, facilidades para distribución de cálculos (a través de comunicación de procesos internodos, llamadas a procedimientos remotos, etc.). Sistemas Operativos de red. Son aquellos sistemas que mantienen a dos o más computadoras unidas a través de algún medio de comunicación (físico o no), con el objetivo primordial de poder compartir los diferentes recursos y la información del sistema. El primer Sistema Operativo de red estaba enfocado a equipos con un procesador Motorola 68000, pasando posteriormente a procesadores Intel como Novell Netware. Los Sistemas Operativos de red más ampliamente usados son: Novell Netware, Personal Netware, LAN Manager, Windows NT Server, UNIX, LANtastic. Figura. Se muestra un Sistema Operativo en red. Sistemas Operativos paralelos. En estos tipos de Sistemas Operativos se pretende que cuando existan dos o más procesos que compitan por algún recurso se puedan realizar o ejecutar al mismo tiempo. En UNIX existe también la posibilidad de ejecutar programas sin tener que atenderlos en forma interactiva, simulando paralelismo (es decir, atender de manera concurrente varios procesos de un mismo usuario). Así, en lugar de esperar a que el proceso termine de ejecutarse (como lo haría normalmente), regresa a atender al usuario inmediatamente después de haber creado el proceso. Ejemplos de estos tipos de Sistemas Operativos están: Alpha, PVM, la serie AIX, que es utilizado en los sistemas RS/6000 de IBM. Con el paso del tiempo, los Sistemas Operativos fueron clasificándose de diferentes maneras, dependiendo del uso o de la aplicación que se les daba. A continuación se mostrarán diversos tipos de Sistemas Operativos que existen en la actualidad, con algunas de sus características: Sistemas Operativos por lotes. Los Sistemas Operativos por lotes, procesan una gran cantidad de trabajos con poca o ninguna interacción entre los usuarios y los programas en ejecución. Se reúnen todos los trabajos comunes para realizarlos al mismo tiempo, evitando la espera de dos o más trabajos como sucede en el procesamiento en serie. Estos sistemas son de los más tradicionales y antiguos, y fueron introducidos alrededor de 1956 para aumentar la capacidad de procesamiento de los programas. Cuando estos sistemas son bien planeados, pueden tener un tiempo de ejecución muy alto, porque el procesador es mejor utilizado y los Sistemas Operativos pueden ser simples, debido a la secuenciabilidad de la ejecución de los trabajos. Algunos ejemplos de Sistemas Operativos por lotes exitosos son el SCOPE, del DC6600, el cual está orientado a procesamiento científico pesado, y el EXEC II para el UNIVAC 1107, orientado a procesamiento académico. Algunas otras características con que cuentan los Sistemas Operativos por lotes son: Requiere que el programa, datos y órdenes al sistema sean remitidos todos juntos en forma de lote. Permiten poca o ninguna interacción usuario/programa en ejecución. Mayor potencial de utilización de recursos que procesamiento serial simple en sistemas multiusuarios. No conveniente para desarrollo de programas por bajo tiempo de retorno y depuración fuera de línea. Conveniente para programas de largos tiempos de ejecución (ej, análisis estadísticos, nóminas de personal, etc.) Se encuentra en muchos computadores personales combinados con procesamiento serial. Planificación del procesador sencilla, típicamente procesados en orden de llegada. Planificación de memoria sencilla, generalmente se divide en dos: parte residente del S.O. y programas transitorios. No requieren gestión crítica de dispositivos en el tiempo. Suelen proporcionar gestión sencilla de manejo de archivos: se requiere poca protección y ningún control de concurrencia para el acceso. Figura. Trabajos más comunes que realiza el Sistema Operativo por lotes. Sistemas Operativos de tiempo real. Los Sistemas Operativos de tiempo real son aquelos en los cuales no tiene importancia el usuario, sino los procesos. Por lo general, están subutilizados sus recursos con la finalidad de prestar atención a los procesos en el momento que lo requieran. se utilizan en entornos donde son procesados un gran número de sucesos o eventos. Muchos Sistemas Operativos de tiempo real son construidos para aplicaciones muy específicas como control de tráfico aéreo, bolsas de valores, control de refinerías, control de laminadores. También en el ramo automovilístico y de la electrónica de consumo, las aplicaciones de tiempo real están creciendo muy rápidamente. Otros campos de aplicación de los Sistemas Operativos de tiempo real son los siguientes: Control de trenes. Telecomunicaciones. Sistemas de fabricación integrada. Producción y distribución de energía eléctrica. Control de edificios. Sistemas multimedia. Algunos ejemplos de Sistemas Operativos de tiempo real son: VxWorks, Solaris, Lyns OS y Spectra. Los Sistemas Operativos de tiempo real, cuentan con las siguientes características: Se dan en entornos en donde deben ser aceptados y procesados gran cantidad de sucesos, la mayoría externos al sisterma computacional, en breve tiempo o dentro de ciertos plazos. Se utlizan en control industrial, conmutación telefónica, control de vuelo, simulaciones en tiempo real., aplicaciones militares, etc. Objetivo es proporcionar rápidos tiempos de respuesta. Procesa ráfagas de miles de interrupciones por segundo sin perder un solo suceso. Proceso se activa tras ocurrencia de suceso, mediante interrupción. Proceso de mayor prioridad expropia recursos. Por tanto generalmente se utliza planificación expropiativa basada en prioridades. Gestión de memoria menos exigente que tiempo compartido, usualmente procesos son residentes permanentes en memoria. Población de procesos estática en gran medida. Poco movimiento de programas entre almacenamiento secundario y memoria. Gestión de archivos se orienta más a velocidad de acceso que a utlización eficiente del recurso. Sistemas Operativos de multiprogramación (o Sistemas Operativos de multitarea). Se distinguen por sus habilidades para poder soportar la ejecución de dos o más trabajos activos (que se están ejecutado) al mismo tiempo. Esto trae como resultado que la Unidad Central de Procesamiento (UCP) siempre tenga alguna tarea que ejecutar, aprovechando al máximo su utilización. Su objetivo es tener a varias tareas en la memoria principal, de manera que cada uno está usando el procesador, o un procesador distinto, es decir, involucra máquinas con más de una UCP. Sistemas Operativos como UNIX, Windows 95, Windows 98, Windows NT, MAC-OS, OS/2, soportan la multitarea. Las características de un Sistema Operativo de multiprogramación o multitarea son las siguientes: Mejora productividad del sistema y utilización de recursos. Multiplexa recursos entre varios programas. Generalmente soportan múltiples usuarios (multiusuarios). Proporcionan facilidades para mantener el entorno de usuarios inndividuales. Requieren validación de usuario para seguridad y protección. Proporcionan contabilidad del uso de los recursos por parte de los usuarios. Multitarea sin soprte multiusuario se encuentra en algunos computadores personales o en sistemas de tiempo real. Sistemas multiprocesadores son sistemas multitareas por definición ya que soportan la ejecución simultánea de múltiples tareas sobre diferentes procesadores. En general, los sistemas de multiprogramación se caracterizan por tener múltiples programas activos compitiendo por los recursos del sistema: procesador, memoria, dispositivos periféricos. Sistemas Operativos de tiempo compartido. Permiten la simulación de que el sistema y sus recursos son todos para cada usuarios. El usuario hace una petición a la computadora, esta la procesa tan pronto como le es posible, y la respuesta aparecerá en la terminal del usuario. Los principales recursos del sistema, el procesador, la memoria, dispositivos de E/S, son continuamente utilizados entre los diversos usuarios, dando a cada usuario la ilusión de que tiene el sistema dedicado para sí mismo. Esto trae como consecuencia una gran carga de trabajo al Sistema Operativo, principalmente en la administración de memoria principal y secundaria. Ejemplos de Sistemas Operativos de tiempo compartido son Multics, OS/360 y DEC-10. Características de los Sistemas Operativos de tiempo compartido: Populares representantes de sistemas multiprogramados multiusuario, ej: sistemas de diseño asistido por computador, procesamiento de texto, etc. Dan la ilusión de que cada usuario tiene una máquina para sí. Mayoría utilizan algoritmo de reparto circular. Programas se ejcutan con prioridad rotatoria que se incrementa con la espera y disminuye después de concedido el servicio. Evitan monopolización del sistema asignando tiempos de procesador (time slot). Gestión de memoria proporciona protección a programas residentes. Gestión de archivo debe proporcionar protección y control de acceso debido a que pueden existir múltiples usuarios accesando un mismo archivos. Sistemas Operativos distribuidos. Permiten distribuir trabajos, tareas o procesos, entre un conjunto de procesadores. Puede ser que este conjunto de procesadores esté en un equipo o en diferentes, en este caso es trasparente para el usuario. Existen dos esquemas básicos de éstos. Un sistema fuertemente acoplado es a es aquel que comparte la memoria y un reloj global, cuyos tiempos de acceso son similares para todos los procesadores. En un sistema débilmente acoplado los procesadores no comparten ni memoria ni reloj, ya que cada uno cuenta con su memoria local. Los sistemas distribuidos deben de ser muy confiables, ya que si un componente del sistema se compone otro componente debe de ser capaz de reemplazarlo. Entre los diferentes Sistemas Operativos distribuidos que existen tenemos los siguientes: Sprite, SolarisMC, Mach, Chorus, Spring, Amoeba, Taos, etc. Caracteristicas de los Sistemas Operativos distribuidos: Colección de sistemas autónomos capaces de comunicación y cooperación mediante interconexiones hardware y software . Gobierna operación de un S.C. y proporciona abstracción de máquina virtual a los usuarios. Objetivo clave es la transparencia. Generalmente proporcionan medios para la compartición global de recursos. Servicios añadidos: denominación global, sistemas de archivos distribuidos, facilidades para distribución de cálculos (a través de comunicación de procesos internodos, llamadas a procedimientos remotos, etc.). Sistemas Operativos de red. Son aquellos sistemas que mantienen a dos o más computadoras unidas através de algún medio de comunicación (fisico o no), con el objetivo primordial de poder compartir los diferentes recursos y la información del sistema. El primer Sistema Operativo de red estaba enfocado a equipos con un procesador Motorola 68000, pasando posteriormente a procesadores Intel como Novell Netware. Los Sistemas Operativos de red mas ampliamente usados son: Novell Netware, Personal Netware, LAN Manager, Windows NT Server, UNIX, LANtastic. Sistemas Operativos paralelos. En estos tipos de Sistemas Operativos se pretende que cuando existan dos o más procesos que compitan por algún recurso se puedan realizar o ejecutar al mismo tiempo. En UNIX existe también la posibilidad de ejecutar programas sin tener que atenderlos en forma interactiva, sinulando paralelismo (es decir, atender de manera concurrente varios procesos de un mismo usuario). Así, en lugar de esperar a que el proceso termine de ejecutarse (como lo haría normalmente), regresa a atender al usuario inmediatamente después de haber creado el proceso. Ejemplos de estos tipos de Sistemas Operativos están: Alpha, PVM, la serie AIX, que es utilizado en los sistemas RS/6000 de IBM. 1.5 Estructura (niveles o estratos de diseño). Internamente los sistemas operativos estructuralmente de se clasifican según como se hayan organizado intérnamente en su diseño, por esto la clasificación más común de los S.O. son: Sistemas monolíticos: En estos sistemas operativos se escriben como un conjunto de procedimientos, cada uno de los cuales puede llamar a cualquiera de los otros siempre que lo necesite. Cuando se emplea esta técnica, cada procedimiento del sistema tiene una interfaz bien definida en términos de parámetros y resultados, y cada una tiene la libertad de llamar a cualquiera otra, si la última ofrece algún cálculo útil que la primera necesite. Para construir el programa objeto real del sistema operativo cuando se usa este método, se compilan todos los procedimientos individuales a archivos que contienen los procedimientos y después se combinan todos en un solo archivo objeto con el enlazador. En términos de ocultamiento de información, esencialmente no existe ninguno; todo procedimiento es visible para todos (al contrario de una estructura que contiene módulos o paquetes, en los cuales mucha información es local a un módulo y sólo pueden llamar puntos de registro designados oficialmente del exterior del módulo) Esta organización sugiere una estructura básica del sistema operativo: 1.- Un programa central que invoque el procedimiento de servicio solicitado (Shell o Kernel) 2.- Un conjunto de procedimientos de servicios que realice las llamadas al sistema. 3.- Un conjunto de procedimientos de uso general que ayude a los procedimientos de servicio Sistemas en estratos: Estos sistemas operativos se organizan como una jerarquía de estratos, cada uno construido arriba del que está debajo de él. El primer sistema construido en esta forma fuel el sistema THE que se fabricó en Technische Hogeschool Eindhoven de Holanda por E. W Dijkstra (1968) y sus alumnos. El sistema THE era un sistema de lote para una computadora alemana, la Electrológica X8, que tenía 32K de palabras de 27 bits ( los bits eran costosos en aquellos días) El sistema tenía 6 estratos, estos se muestran en la siguiente tabla: 5 Operador de THE 4 Programas del usuario 3 Administración de Entrada/Salida 2 Comunicación entre el operador y el proceso 1 Administración de la memoria y el tambor magnético 0 Distribución del procesador y multiprogramación - El estrato 0 trabajaba con la distribución del procesador, cambiando entre procesos cuando ocurrían interrupciones o los relojes expiraban. Sobre el estrato 0, el sistema constaba de procesos secuenciales, cada uno de los cuales podía programarse sin tener que preocuparse por el hecho de que múltiples procesos estuvieran corriendo en un solo procesador. En otras palabras, el estarto 0 ofrecía la multiprogramación básica de la CPU. El estrato 1 realizaba el manejo de memoria. Este distribuía espacio para procesos contenidos en la memoria central y en un tambor de 512K palabras que se usaba para contener partes de procesos (páginas) para las cuales no había espacio en la memoria central. Sobre el estrato 1, los procesos no tenía que preocuparse de si estaban en la memoria o en el tambor; el software del estrato 1 se hacía cargo de asegurar que las páginas se trajeran a la memoria siempre que se necesitaran. El estrato 2 manejaba la comunicación entre cada proceso y la consola de operador. El estrato 3 se hacía cargo de manejar los dispositivos de E/S y de separar la información en flujo que entraba y salí de ellos. Sobre el estrato 3 cada proceso podía trabajar con dispositivos de E/S abstractos con propiedades agradables, en vez de dispositivos reales con muchas peculiaridades El estrato 4 era donde se encontraban los programas de los usuarios. No tenían que preocuparse por el manejo de los procesos, memoria, consola o E/S. El proceso operador del sistema se localizaba en el estrato 5. En esta unidad examinaremos cuatro estructuras distintas que ya han sido probadas, con el fin de tener una idea más extensa de cómo esta estructurado el sistema operativo. Veremos brevemente algunas estructuras de diseños de sistemas operativos. Estructura modular. También llamados sistemas monolíticos. Este tipo de organización es con mucho la mas común; bien podría recibir el subtitulo de "el gran embrollo". La estructura consiste en que no existe estructura alguna. El sistema operativo se escribe como una colección de procedimientos, cada uno de los cuales puede llamar a los demás cada vez que así lo requiera. Cuando se usa esta técnica, cada procedimiento del sistema tiene una interfaz bien definida en términos de parámetros y resultados y cada uno de ellos es libre de llamar a cualquier otro, si este ultimo proporciona cierto cálculo útil para el primero. Sin embargo incluso en este tipo de sistemas es posible tener al menos algo de estructura. Los servicios (llamadas al sistema) que proporciona el sistema operativo se solicitan colocando los parámetros en lugares bien definidos, como en los registros o en la pila, para después ejecutar una instrucción especial de trampa de nombre "llamada al núcleo" o "llamada al supervisor". Esta instrucción cambia la máquina del modo usuario al modo núcleo y transfiere el control al sistema operativo, lo que se muestra en el evento (1) de la figura 1. El sistema operativo examina entonces los parámetros de la llamada, para determinar cual de ellas se desea realizar, como se muestra en el evento (2) de la figura 1. A continuación, el sistema operativo analiza una tabla que contiene en la entrada k un apuntador al procedimiento que realiza la k-esima llamada al sistema. Esta operación que se muestra en (3) de la figura 1, identifica el procedimiento de servicio, al cual se llama. Por ultimo, la llamada al sistema termina y el control regresa al programa del usuario. Figura 1. La forma en que debe hacerse una llamada al sistema: (1) el programa del usuario es atraído hacia el núcleo. (2) el sistema operativo determina el número del servicio solicitado. (3) el sistema operativo localiza y llama al procedimiento correspondiente al servicio. (4) el control regresa al programa del usuario. Esta organización sugiere una organización básica del sistema operativo: 1.- un programa principal que llama al procedimiento del servicio solicitado. 2.- un conjunto de procedimientos de servicio que llevan a cabo las llamadas al sistema. 3.- un conjunto de procedimientos utilitarios que ayudan al procedimiento de servicio. En este modelo, para cada llamada al sistema existe un procedimiento de servicio que se encarga de él. Los procedimientos utilitarios hacen cosas necesarias para varios procedimientos de servicio, por ejemplo buscar los datos de los programas del usuario. Estructura por microkernel. Las funciones centrales de un SO son controladas por el núcleo (kernel) mientras que la interfaz del usuario es controlada por el entorno (shell). Por ejemplo, la parte más importante del DOS es un programa con el nombre "COMMAND.COM" Este programa tiene dos partes. El kernel, que se mantiene en memoria en todo momento, contiene el código máquina de bajo nivel para manejar la administración de hardware para otros programas que necesitan estos servicios, y para la segunda parte del COMMAND.COM el shell, el cual es el interprete de comandos Las funciones de bajo nivel del SO y las funciones de interpretación de comandos están separadas, de tal forma que puedes mantener el kernel DOS corriendo, pero utilizar una interfaz de usuario diferente. Esto es exactamente lo que sucede cuando cargas Microsoft Windows, el cual toma el lugar del shell, reemplazando la interfaz de línea de comandos con una interfaz gráfica del usuario. Existen muchos "shells" diferentes en el mercado, ejemplo: NDOS (Norton DOS), XTG, PCTOOLS, o inclusive el mismo SO MS-DOS a partir de la versión 5.0 incluyó un Shell llamado DOS SHELL. Estructura por anillos concéntricos (capas). El sistema por "capas" consiste en organizar el sistema operativo como una jerarquía de capas, cada una construida sobre la inmediata inferior. El primer sistema construido de esta manera fue el sistema THE (Technische Hogeschool Eindhoven), desarrollado en Holanda por E. W. Dijkstra (1968) y sus estudiantes. El sistema tenia 6 capas, como se muestra en la figura 3. La capa 0 trabaja con la asignación del procesador y alterna entre los procesos cuando ocurren las interrupciones o expiran los cronómetros. Sobre la capa 0, el sistema consta de procesos secuénciales, cada uno de los cuales se podría programar sin importar que varios procesos estuvieran ejecutándose en el mismo procesador, la capa 0 proporcionaba la multiprogramación básica de la CPU. La capa 1 realizaba la administración de la memoria. Asignaba el espacio de memoria principal para los procesos y un recipiente de palabras de 512K se utilizaba para almacenar partes de los procesos (páginas) para las que no existía lugar en la memoria principal. Por encima de la capa 1, los procesos no debían preocuparse si estaban en la memoria o en el recipiente; el software de la capa 1 se encargaba de garantizar que las páginas llegaran a la memoria cuando fueran necesarias. La capa 2 se encargaba de la comunicación entre cada proceso y la consola del operador. Por encima de esta capa, cada proceso tiene su propia consola de operador. La capa 3 controla los dispositivos de E/S y guarda en almacenes (buffers) los flujos de información entre ellos. Por encima de la capa 3, cada proceso puede trabajar con dispositivos exactos de E/S con propiedades adecuadas, en vez de dispositivos reales con muchas peculiaridades. La capa 4 es donde estaban los programas del usuario, estos no tenían que preocuparse por el proceso, memoria, consola o control de E/S. el proceso operador del sistema se localizaba en la capa 5 Una generalización mas avanzada del concepto de capas se presento en el sistema MULTICS. En lugar de capas, MULTICS estaba organizado como una serie de anillos concéntricos, siendo los anillos interiores los privilegiados. Cuando un procedimiento de un anillo exterior deseaba llamar a un procedimiento de un anillo interior, debió hacer el equivalente a una llamada al sistema Mientras que el esquema de capas de THE era en realidad un apoyo al diseño, debido a que todas las partes del sistema estaban ligadas entre si en un solo programa objeto, en MULTICS, el mecanismo de anillos estaba mas presente durante el tiempo de ejecución y era reforzado por el hardware. La ventaja del mecanismo de anillos es su facilidad de extensión para estructurar subsistemas del usuario. 5 El operador 4 Programas del usuario 3 Control de entrada/salida 2 Comunicación operador-proceso 1 Administración de la memoria y del disco 0 Asignación del procesador y multiprogramación Figura 3. Estructura del sistema operativo THE. Estructura cliente – servidor Una tendencia de los sistemas operativos modernos es la de explotar la idea de mover el código a capas superiores y eliminar la mayor parte posible del sistema operativo para mantener un núcleo mínimo. El punto de vista usual es el de implantar la mayoría de las funciones del sistema operativo en los procesos del usuario. Para solicitar un servicio, como la lectura de un bloque de cierto archivo, un proceso del usuario (denominado proceso cliente) envía la solicitud a un proceso servidor, que realiza entonces el trabajo y regresa la respuesta. En este modelo, que se muestra en la figura 4, lo único que hace el núcleo es controlar la comunicación entre los clientes y los servidores. Al separar el sistema operativo en partes, cada una de ellas controla una faceta del sistema, como el servicio a archivos, servicios a procesos, servicio a terminales o servicio a la memoria, cada parte es pequeña y controlable. Además como todos los servidores se ejecutan como procesos en modo usuario y no en modo núcleo, no tienen acceso directo al hardware. En consecuencia si hay un error en el servidor de archivos, éste puede fallar, pero esto no afectará en general a toda la máquina. Otra de las ventajas del modelo cliente-servidor es su capacidad de adaptación para su uso en los sistemas distribuidos Si un cliente se comunica con un servidor mediante mensajes, el cliente no necesita saber si el mensaje se maneja en forma local, en su máquina, o si se envía por medio de una red a un servidor en una máquina remota. En lo que respecta al cliente, lo mismo ocurre en ambos casos: se envió una solicitud y se recibió una respuesta. Sistemas Operativos por su Estructura (Visión Interna). Según, se deben observar dos tipos de requisitos cuando se construye un sistema operativo, los cuales son: Requisitos de usuario: Sistema fácil de usar y de aprender, seguro, rápido y adecuado al uso al que se le quiere destinar. Requisitos del software: Donde se engloban aspectos como el mantenimiento, forma de operación, restricciones de uso, eficiencia, tolerancia frente a los errores y flexibilidad. A continuación se describen las distintas estructuras que presentan los actuales sistemas operativos para satisfacer las necesidades que de ellos se quieren obtener. Estructura Monolítica. Es la estructura de los primeros sistemas operativos constituidos fundamentalmente por un solo programa compuesto de un conjunto de rutinas entrelazadas de tal forma que cada una puede llamar a cualquier otra. Las características fundamentales de este tipo de estructura son: Construcción del programa final a base de módulos compilados separadamente que se unen a través del ligador. Buena definición de parámetros de enlace entre las distintas rutinas existentes, que puede provocar mucho acoplamiento. Carecen de protecciones y privilegios al entrar a rutinas que manejan diferentes aspectos de los recursos de la computadora, como memoria, disco, etc. Generalmente están hechos a medida, por lo que son eficientes y rápidos en su ejecución y gestión, pero por lo mismo carecen de flexibilidad para soportar diferentes ambientes de trabajo o tipos de aplicaciones. Estructura Jerárquica. A medida que fueron creciendo las necesidades de los usuarios y se perfeccionaron los sistemas, se hizo necesaria una mayor organización del software, del sistema operativo, donde una parte del sistema contenía subpartes y esto organizado en forma de niveles. Se dividió el sistema operativo en pequeñas partes, de tal forma que cada una de ellas estuviera perfectamente definida y con un claro interface con el resto de elementos. Se constituyó una estructura jerárquica o de niveles en los sistemas operativos, el primero de los cuales fue denominado THE (Technische Hogeschool, Eindhoven), de Dijkstra, que se utilizó con fines didácticos. Se puede pensar también en estos sistemas como si fueran `multicapa'. Multics y Unix caen en esa categoría. En la estructura anterior se basan prácticamente la mayoría de los sistemas operativos actuales. Otra forma de ver este tipo de sistema es la denominada de anillos concéntricos o "rings". En el sistema de anillos, cada uno tiene una apertura, conocida como puerta o trampa (trap), por donde pueden entrar las llamadas de las capas inferiores. De esta forma, las zonas más internas del sistema operativo o núcleo del sistema estarán más protegidas de accesos indeseados desde las capas más externas. Las capas más internas serán, por tanto, más privilegiadas que las externas. Máquina Virtual. Se trata de un tipo de sistemas operativos que presentan una interface a cada proceso, mostrando una máquina que parece idéntica a la máquina real subyacente. Estos sistemas operativos separan dos conceptos que suelen estar unidos en el resto de sistemas: la multiprogramación y la máquina extendida. El objetivo de los sistemas operativos de máquina virtual es el de integrar distintos sistemas operativos dando la sensación de ser varias máquinas diferentes. El núcleo de estos sistemas operativos se denomina monitor virtual y tiene como misión llevar a cabo la multiprogramación, presentando a los niveles superiores tantas máquinas virtuales como se soliciten. Estas máquinas virtuales no son máquinas extendidas, sino una réplica de la máquina real, de manera que en cada una de ellas se pueda ejecutar un sistema operativo diferente, que será el que ofrezca la máquina extendida al usuario Cliente-Servidor(Microkernel). El tipo más reciente de sistemas operativos es el denominado Cliente-servidor, que puede ser ejecutado en la mayoría de las computadoras, ya sean grandes o pequeñas. Este sistema sirve para toda clase de aplicaciones por tanto, es de propósito general y cumple con las mismas actividades que los sistemas operativos convencionales. El núcleo tiene como misión establecer la comunicación entre los clientes y los servidores. Los procesos pueden ser tanto servidores como clientes. Por ejemplo, un programa de aplicación normal es un cliente que llama al servidor correspondiente para acceder a un archivo o realizar una operación de entrada/salida sobre un dispositivo concreto. A su vez, un proceso cliente puede actuar como servidor para otro." [Alcal92]. Este paradigma ofrece gran flexibilidad en cuanto a los servicios posibles en el sistema final, ya que el núcleo provee solamente funciones muy básicas de memoria, entrada/salida, archivos y procesos, dejando a los servidores proveer la mayoría que el usuario final o programador puede usar. Estos servidores deben tener mecanismos de seguridad y protección que, a su vez, serán filtrados por el núcleo que controla el hardware. Actualmente se está trabajando en una versión de UNIX que contempla en su diseño este paradigma. 1.6 Núcleo. El Núcleo del Sistema Operativo. Todas las operaciones en las que participan procesos son controladas por la parte del sistema operativo denominada núcleo (nucleus, core o kernel, en inglés). El núcleo normalmente representa sólo una pequeña parte de lo que por lo general se piensa que es todo el sistema operativo, pero es tal vez el código que más se utiliza. Por esta razón, el núcleo reside por lo regular en la memoria principal, mientras que otras partes del sistema operativo son cargadas en la memoria principal sólo cuando se necesitan. Los núcleos se diseñan para realizar "el mínimo" posible de procesamiento en cada interrupción y dejar que el resto lo realice el proceso apropiado del sistema, que puede operar mientras el núcleo se habilita para atender otras interrupciones. El núcleo de un sistema operativo normalmente contiene el código necesario para realizar las siguientes funciones: Manejo de interrupciones. Creación y destrucción de procesos. Cambio de estado de los procesos. Despacho. Suspensión y reanudación de procesos. Sincronización de procesos. Comunicación entre procesos. Manipulación de los bloques de control de procesos. Apoyo para las actividades de entrada/salida. Apoyo para asignación y liberación de memoria. Apoyo para el sistema de archivos. Apoyo para el mecanismo de llamada y retorno de un procedimiento. Apoyo para ciertas funciones de contabilidad del sistema. Núcleo o Kernel y niveles de un Sistema Operativo. El Kernel consiste en la parte principal del código del sistema operativo, el cual se encargan de controlar y administrar los servicios y peticiones de recursos y de hardware con respecto a uno o varios procesos, este se divide en 5 capas: Nivel 1. Gestión de Memoria: que proporciona las facilidades de bajo nivel para la gestión de memoria secundaria necesaria para la ejecución de procesos. Nivel 2. Procesador: Se encarga de activar los cuantums de tiempo para cada uno de los procesos, creando interrupciones de hardware cuando no son respetadas. Nivel 3. Entrada/Salida: Proporciona las facilidades para poder utilizar los dispositivos de E/S requeridos por procesos. Nivel 4. Información o Aplicación o Interprete de Lenguajes: Facilita la comunicación con los lenguajes y el sistema operativo para aceptar las ordenes en cada una de las aplicaciones. Cuando se solicitan ejecutando un programa el software de este nivel crea el ambiente de trabajo e invoca a los procesos correspondientes. Nivel 5. Control de Archivos: Proporciona la facilidad para el almacenamiento a largo plazo y manipulación de archivos con nombre, va asignando espacio y acceso de datos en memoria. El núcleo y los procesos. El núcleo (Kernel) de un sistema operativo es un conjunto de rutinas cuya misión es la de gestionar el procesador, la memoria, la entrada/salida y el resto de procesos disponibles en la instalación. Toda esta gestión la realiza para atender al funcionamiento y peticiones de los trabajos que se ejecutan en el sistema. Los procesos relacionados con la entidad básica de los sistemas operativos actuales: Los procesos. El esquema general del mismo es el siguiente: Definición y concepto de proceso. El Bloque de Control de Proceso (PCB) como imagen donde el sistema operativo ve el estado del proceso. Estados por los que pasa un proceso a lo largo de su existencia en la computadora. Operaciones que se pueden realizar sobre un proceso. Clasificación de los procesos según su forma de ejecución, de carga, etc. 1.6.1 Interrupciones (FLIH). El GESTOR DE INTERRUPCIONES DE PRIMER NIVEL: FLIH (First Level Interruption Handler): `Algo' que gestione las interrupciones EL CONTROLADOR DE INTERRUPCIONES DE PRIMER NIVEL: EL FLIH En principio, una señal es una indicación por la que se altera la secuencia de ejecución. Hay varios tipos de interrupción, que se clasifican en función de su origen: ! EXTERNAS: Se producen fuera del procesador ! INTERNAS: Se producen dentro del procesador Si precisamos más: Las interrupciones EXTERNAS, las denominamos: INTERRUPCIONES Las interrupciones INTERNAS, pueden ser: EXTRACÓDIGOS: Operaciones que manipulan elementos internos del procesador TRAPS o EXCEPCIONES La misión del FLIH, está en el núcleo, para dar una respuesta a cualquier tipo de señal que se produce en el sistema. Al producirse una señal, la atrapa el Hardware de interrupciones, que como mínimo, salva el contenido del PC en el PCB del proceso. Además, puede que también salve el resto del entorno volátil (también en el PCB). También direcciona al FLIH, es decir, pone en el PC la dirección del FLIH. Por lo tanto, podemos decir, que el FLIH es un elemento software, es un proceso. Ya hemos dicho que el FLIH es Software, pues se trata de un sencillo programa definido sobre un área de memoria dedicada a él, un área de memoria específica; es decir, el FLIH siempre está en la misma parte de la memoria. El FLIH hace dos cosas: 1º) Determina el origen de la interrupción (Averigua qué interrupción se ha producido) 2º) Direcciona la rutina que trata esa interrupción Si el FLIH es un programa, necesita parte del entorno volátil: PC, ACC, ... Por ello, debe salvarse el entorno volátil del proceso interrumpido. El entorno volátil del proceso interrumpido, se puede salvar en dos momentos: Puede salvarlo el Hardware de interrupciones Si no lo salva el Hardware de interrupciones, será lo primero que haga el FLIH, antes incluso de determinar el origen de la interrupción NOTA: Hay sistemas que definen unos registros máquina para uso exclusivo por parte del Sistema Operativo, para evitar tener que estar salvando y restaurando el contenido del entorno volátil. Formas de determinar el origen de una interrupción: MEDIANTE SOFTWARE: Mediante una cadena de saltos o IFs (o con una CASE) El FLIH, tiene un único punto de entrada: Ventaja: ! Es muy sencillo Desventaja: ! Rendimiento muy pobre (Cuantas más interrupciones, peor rendimiento) Posible solución: Poner al principio de la cadena de saltos las comprobaciones de las interrupciones más frecuentes. MEDIANTE HARDWARE: Mediante el uso de un comparador simultáneo, incluido en el Hardware de interrupciones. El origen de la interrupción, no lo va a detectar el FLIH, lo va a detectar el Hardware de interrupciones. El FLIH, tiene N puntos de entrada, siendo N el número de interrupciones que reconoce el sistema. Ventaja: ! Es casi simultáneo, mucho más rápido que la secuencia de IFs Desventaja: ! Coste Elevado: Un comparador para muchas interrupciones es muy caro COMBINANDO SOFTWARE Y HARDWARE: El comparador distingue los TIPOS de interrupción. Las interrupciones se agrupan por tipos. EL Hardware de interrupciones: 1º) Salva el contenido del entorno volátil 2º) Mediante un comparador simultáneo, determina el tipo al que pertenece la interrupción producida 3º) Se direcciona al FLIH, donde una pequeña cadena de saltos determina la interrupción en concreto que se ha producido Si N es el número de tipos de interrupciones, el FLIH tiene N puntos de entrada. Cuando el FLIH está atendiendo una interrupción, pueden producirse otras. ¿Qué hacemos con esas otras interrupciones que se producen? Inhibir (ignorar) el resto de interrupciones mientras se atiende una. Pero esto no puede hacerse siempre Las interrupciones más prioritarias deben tratarse nada más producirse Posible solución: Definir niveles de prioridad entre las interrupciones, de forma que si se está atendiendo una interrupción, quedarán pendientes (o inhibidas) las de menor o igual prioridad. Problema: Si se produce una interrupción más prioritaria que la que se está atendiendo, debe dejarse de atender la que se estaba atendiendo para atender la más prioritaria. Por lo tanto, debe guardarse el entorno volátil de la interrupción que estaba atendiendo. La interrupción que pasa a ser atendida, también puede tener que dejarse, al llegar otra de mayor prioridad ... Por tanto, es necesario un lugar a para almacenar entornos volátiles, es decir, un PCB, por cada prioridad de interrupción - 1. Inicio del servicio de una interrupción: Las interrupciones no pueden estar inhibidas mucho tiempo, es decir, el tiempo de tratamiento del FLIH debe ser corto. Problema: Hay interrupciones cuyo tratamiento lleva mucho tiempo. En ese caso, el FLIH, sólo inicia su tratamiento, y luego, lama a otra rutina ajena o externa a él, que realiza el resto del tratamiento. Una interrupción puede implicar cambio(s) de estado en algún(os) proceso(s). TIPOS DE INTERRUPCIONES: Interrupciones que provocan cambios de estado del proceso en ejecución Algunos extracódigos: Peticiones de E/S Señales de error para suspensión Interrupciones de reloj: Interrupciones por expiración del temporizador Interrupciones que provocan cambios de estado en procesos que no están en ejecución Interrupciones de E/S http://html.rincondelvago.com/sistemas-operativos_29.html 1.6.2 Despachador(Scheduler). Schedulling.- Colas de Schedulling: Los procesos que están en estado de espera se quedan en una lista llamada lista o cola de ready. Los procesos que hacen uso de E/S se guardan en una cola de E/S. Hay una cola de E/S por cada dispositivo. Schedullers: Componente del sistema operativo responsable de decidir quien hara uso de la CPU. Algoritmos de Schedulling.FCFS (First Come First Served) Cuando un proceso llega a la cola de ready su PCB es agregado al final de la lista. El uso de la CPU es otorgado al primero de la lista y una vez que un proceso comienza a ejecutar no deja de hacerlo hasta que se termina. El tiempo medio de espera para este algoritmo suele ser bastante alto. SJF (Shortest Job First) Una vez que un proceso ejecuta no deja de hacerlo hasta que voluntariamente cambia de estado (no hay interrupción por tiempo). Asocia a cada proceso el tiempo de CPU que habrá de usar en su próxima vuelta y va a decidir por el más pequeño. Si hubiera mas de uno utiliza FCFS para desempatar. El mayor problema de este algoritmo radica en el cálculo de tiempo de uso de CPU. Este se puede aproximar a: Tn+1= .tn+(1- )Tn 0< <1 Tiempo calculado en la vuelta n Próximo uso de CPU Tiempo usado en la vuelta n El problema de este algoritmo es que el tiempo de espera para los procesos largos puede ser demasiado largo. Constantemente se están entregando los procesos mas cortos y el más grande nunca será ejecutado. El FJS se puede subdividir en 2 tipos de algoritmos: PREEMPTIVO o NO PREEMPTIVO Preemptivo significa que si mientras un proceso se esta ejecutando, entra a la cola de ready un proceso mas corto, el proceso en la cola de ready se apropia de la CPU y comienza su ejecución. Priority Schedulling Asocia a cada proceso una prioridad. Luego selecciona el proceso con mas prioridad para desempatar. En caso de que hubieran dos o mas procesos con la misma prioridad, se usa FCFS para desempatar. Hay dos tipo de prioridad en los procesos: la prioridad externa definidas a través del sistema operativo y la prioridad interna definida por el tiempo de uso de la CPU, el control de E/S, etc. Este algoritmo también se puede ejecutar de dos maneras: preemptivo y no preemptivo. El algoritmo soluciona el problema del looping pero el problema es que los procesos con prioridad muy baja tienen chance de no ejecutarse nunca. Para solucionar este problema de espera infinita el envejecimiento de un proceso eleva su prioridad. Round Robin Este es un algoritmo basado en FCFS. Trata la cola de ready como una lista circular. Introduce el concepto de "Quantum" o "Time slice" : mayor tiempo de cpu que podrá hacer uso un proceso en cada vuelta. Si el valor del Quantum fuese muy grande, el algoritmo funcionara como un FCFS. Si el Quantum fuera muy chico se produce un overhead por context switch (significa que el Quantum se setea en un tiempo menor al que demora el context switch). Este algoritmo es fuertemente dependiente del Quantum o Time Slice. El Quantum debe ser mayor que el 80% de los tiempos de CPU que hagan uso los procesos, pero no el proceso entero sino por cada burst. MQS (Multilevel Queue Schedulling) Este algoritmo parte la cola de ready en un numero de colas n. Luego existe un criterio para clasificar en que cola será colocado un proceso cuando que queda en estado de ready. Cada cola puede manejar su propio algoritmo de schedulling MFQS (Multilevel Feed Back Queue Schedulling) Define los siguientes parámetros: Numero de colas Algoritmo de schedulling usado en cada cola Método para decidir a que cola entrara un proceso cuando entre a estado de ready Método para decidir cuando un proceso será enviado a una cola de menor prioridad. Múltiple CPU Para que mas de una CPU no tomen el mismo proceso de la cola de ready se utilizan mecanismos de sincronización. Otro mecanismo seria partir la cola en n colas (n CPUs), pero si se hiciera esto podría llegar a suceder que los procesos de una CPU fueran todos cortos y los de otra fueran largos por lo cual habría una CPU que quedaría libre y otra ejecutando. Otra forma sería que una CPU decidiera cual CPU va a ejecutar cual proceso. Esto puede llevar a que la CPU que esta seleccionando quede un poco mas cargada porque en algún momento estará ejecutando el algoritmo de selección y un proceso asignado a ella. 1.6.3 Primitivas de comunicación(IPC). Hay varias primitivas de comunicación entre procesos (IPC abreviadamente). La mayoría de ellas requieren algún tipo de modificación a los programas para poder usarlas, pero hay una que es fácilmente accesible desde la línea de comandos usando la metáfora de ficheros estándar en UNIX y que no requiere modificación alguna a los programas. Se trata de las tuberías. Siguiendo la metáfora, UNIX nos permite manejar tuberías como si fueran ficheros normales. http://www.es.embnet.org/Doc/ECJ/ECJ-1998-02/dbpipes.es.html Primitivas de comunicación Algunos kernel tienen operaciones específicas ajustadas a la invocación remota. Amoeba, por ejemplo, tiene DoOperation/GetRequest--SendReply. Es más eficiente que el simple Send-Receive (y más fiable y legible). Amoeba y otros sistemas tienen también comunicación con grupos o radiado (parcial) (broadcast). Es importante para tolerancia de fallos, mejora de rendimiento y reconfigurabilidad. Diversas variantes: como mensajes, como múltiples RPCs, con un sólo valor devuelto, con varios valores devueltos (todos juntos o pidiendo uno a uno), etc. En la práctica, mecanismos de comunicación de alto nivel tales como RPC/RMI, radiado y notificación de sucesos (parecido a los manejadores de interrupciones), se implementan en middleware y no en el kernel. Normalmente, sobre un nivel TCP/IP, por razones de transportabilidad, (aunque resulta ``caro"). La IPC ofrece un mecanismo que permite a los procesos cumunicarse y sincronizar sus acciones. La mejor forma de proveer la comunicación entre procesos es mediante un sistema de mensajes. La función de un sistema de mensaje es permitir a los procesos comunicarse entre sí sin tener que recurrir a variables compartidas. Un recurso IPC ofrece por los menos 2 operaciones: enviar (mensaje) (send) y recibir (mesanje) (receive). Sea P y Q dos procesos que requieren comunicarse deberán enviarse mensajes; para ello debe existir un enlace de comunicación entre ellos. Este enlace puede implementarse de diversas maneras. Los métodos para implementar lógicamente un enlace y las operaciones de enviar / recibir son: Comunicación directa o indirecta Uso de buffer automático o explícito Envío por copia o envío por referencia Mensajes de tamaño fijo o variables Comunicación directa: Aquí cada proceso que desee comunicarse debe nombrar explícitamente el destinatario o el remitente de la comunicación. Este esquema se define las primitivas de la sig. manera: Enviar(P,mensaje): Enviar un mensaje al proceso P. Recibir(Q. Mensaje): Recibir un mensaje del proceso Q. Con las siguientes propiedades: Se establece automáticamente el enlace entre cada par de procesos. Lo procesos sólo necesitan conocer la identidad de otro para la comunicación. Solo hay un enlace entre cada par de procesos. El enlace puede ser unidireccional o bidireccional. Este esquema exhibe un simetría de direccionamiento; es decir, los procesos tanto emisor como receptor necesitan nombrar al otro para comunicarse. Otra variante de este esquema es utilizar asimetría de direccionamiento, con la sig. primitivas: Enviar(P,mensaje): enviar un mensaje al proceso P. Recibir(Id,mensaje) : recibir un mensaje de cualquier proceso con el que hubo comunicación. Aquí sólo el emisor nombra al destinatario; el destinatario no ésta obligado a nombrar al emisor. Comunicación indirecta: Aquí los mensajes se envían a, y se reciben de, buzones (también llamados PUERTOS). Un buzón puede considerarse en lo abstracto como un objeto en el que los procesos pueden colocar mensajes y del cual se pueden sacar mensajes. Cada buzón tiene una identificación única. Aquí dos proceso se pueden comunicarse sólo si comparten un buzón. Las primitivas se definen como: Enviar (A,mensaje): enviar un mensaje al buzón A. Recibir (A,mensaje): recibir un mensaje del buzón A. Un enlace de comunicación tiene las sig. propiedades: Se establece un enlace entre un par de procesos sólo si tienen un buzón compartido. Un enlace puede estar asociado a más de dos procesos. Entre cada par de procesos en comunicación puede haber varios enlaces distintos, cada uno de los cuales corresponderá a un buzón. Los enlaces pueden ser unidireccionales o bidereccionales. Hay varias formas de designar el dueño de y los usuarios de un buzón dado. Una posibilidad es permitir que un proceso declare variables de tipo buzón. El proceso que declara un buzón es el dueño de ese buzón. Cualquier otro proceso que conozca el nombre de dicho buzón podrá usarlo. Por otro lado, un buzón propiedad del S.O tiene existencia propia; es independiente y no está unido a ningún proceso específico. El S.O establece un mecanismo que permite a un proceso: Crear un buzón nuevo Enviar y recibir mensajes a través del buzón Destruir un buzón. http://html.rincondelvago.com/sistemas-operativos_26.html Comunicación entre procesos (IPC) Los procesos en UNIX no comparten memoria, ni siquiera los padres con sus hijos. Por tanto, hay que establecer algún mecanismo en caso de que se quiera comunicar información entre procesos concurrentes. El sistema operativo UNIX define tres clases de herramientas de comunicación entre procesos (IPC): los semáforos, la memoria compartida y los mensajes. El tipo de llamadas al sistema para estos IPCs es análogo al de los semáforos: existen sendas funciones shmget y msgget para crear o enlazarse a un segmento de memoria compartida o a una cola de mensajes, respectivamente. Para alterar propiedades de estos IPCs, incluyendo su borrado, están las funciones shmctl y msgctl. Para enviar o recibir mensajes, se utilizan las funciones msgsnd y msgrcv. En este apartado se describirán brevemente algunas llamadas al sistema disponibles para el uso de las IPCs dentro de la programación en C. Semáforos ¿Qué es un semáforo para el UNIX? Formalmente es muy similar a la definición clásica de Dijkstra, en el sentido de que es una variable entera con operaciones atómicas de inicialización, incremento y decremento con bloqueo. El UNIX define tres operaciones fundamentales sobre semáforos: * semget Crea o toma el control de un semáforo * semctl Operaciones de lectura y escritura del estado del semáforo. Destrucción del semáforo * semop Operaciones de incremento o decremento con bloqueo Como el lenguaje C no tiene un tipo "semáforo" predefinido, si queremos usar semáforos tenemos que crearlos mediante una llamada al sistema (semget). Esta llamada permite crear un conjunto de semáforos, en lugar de uno solo. Las operaciones se realizan atómicamente sobre todo el conjunto; esto evita interbloqueos y oscuras programaciones en muchos casos, pero para esta práctica es más bien un engorro. Al crear un semáforo se nos devuelve un número identificador, que va a funcionar casi igual que los identificadores de fichero de las llamadas open, creat, etc. La función semget nos permite además "abrir" un semáforo que ya esté creado. Así, por ejemplo, si un proceso crea un semáforo, otros procesos pueden sincronizarse con aquél (con ciertas restricciones) disponiendo del semáforo con semget. Para darle un valor inicial a un semáforo, se utiliza la función semctl. El UNIX no ofrece las funciones clásicas P y V o equivalentes, sino que dispone de una función general llamada semop que permite realizar una gama de operaciones que incluyen las P y V. semctl también se emplea para destruir un semáforo. Llamadas al sistema para semáforos Esta es una descripción resumida de las tres llamadas al sistema para operar con semáforos (semget, semctl y semop). Para una información más completa y fidedigna, diríjanse al manual de llamadas al sistema (sección 2). Para el correcto uso de todas estas funciones, han de incluir el fichero cabecera <sys/sem.h> Las tres funciones devuelven -1 si algo ha ido mal y en tal caso la variable errno informa del tipo de error. Apertura o creación de un semáforo Sintaxis: int semget ( key_t semget key, int nsems, int semflg ); devuelve el identificador del semáforo correspondiente a la clave key. Puede ser un semáforo ya existente, o bien semget crea uno nuevo si se da alguno de estos casos: a) key vale IPC_PRIVATE. Este valor especial obliga a semget a crear un nuevo y único identificador, nunca devuelto por ulteriores llamadas a semget hasta que sea liberado con semctl. b) key no está asociada a ningún semáforo existente, y se cumple que (semflg & IPC_CREAT) es cierto. A un semáforo puede accederse siempre que se tengan los permisos adecuados. Si se crea un nuevo semáforo, el parámetro nsems indica cuántos semáforos contiene el conjunto creado; los 9 bits inferiores de semflg contienen los permisos estilo UNIX de acceso al semáforo (usuario, grupo, otros). semflg es una máscara que puede contener IPC_CREAT, que ya hemos visto, o IPC_EXCL, que hace crear el semáforo, pero fracasando si ya existía. Ejemplo: int semid = semget ( IPC_PRIVATE, 1, IPC_CREAT | 0744 ); Operaciones de control sobre semáforos Sintaxis: int semctl ( int semid, int semnum, int cmd... ); Esta es una función compleja (y de interfaz poco elegante) para realizar ciertas operaciones con semáforos. semid es un identificador de semáforo (devuelto previamente por semget) y semnum, el semáforo del conjunto sobre el que quieren trabajar. cmd es la operación aplicada; a continuación puede aparecer un parámetro opcional según la operación definida por cmd. Las operaciones que les interesan a ustedes son GETVAL semctl SETVAL retorna el valor actual del semáforo se modifica el valor del semáforo (un cuarto parámetro entero da el nuevo valor) IPC_RMID destruye el semáforo Ejemplos: valor = semctl (semid,semnum,GETVAL); semctl (semid,semnum,SETVAL,nuevo_valor); Operaciones sobre semáforos Sintaxis: int semop ( int semid, struct sembuf* sops, unsigned nsops ); Esta función realiza atómicamente un conjunto de operaciones sobre semáforos, pudiendo bloquear al proceso llamador. semid es el identificador del semáforo y sops es un apuntador a un vector de operaciones. nsops indica el número de operaciones solicitadas. La estructura sembuf tiene estos campos: struct sembuf { unsigned short sem_num; // número del semáforo dentro del conjunto short sem_op; // clase de operación // según sea >0, <0 o ==0 short sem_flg; // modificadores de operación }; Cada elemento de sops es una operación sobre algún semáforo del conjunto de semid. El algoritmo simplificado de la operación realizada es éste (semval es el valor entero contenido en el semáforo donde se aplica la operación). si semop<0 si semval >= |semop| semval -= |semop| si semval < |semop| si (semflag & IPC_NOWAIT)!=0 la función semop() retorna si no bloquearse hasta que semval >= |semop| semval -= |semop| si semop>0 semval += semop si semop==0 si semval = 0 SKIP si semval != 0 si (semflag & IPC_NOWAIT)!=0 la función semop() retorna si no bloquearse hasta que semval == 0 Resumiendo un poco, si el campo semop de una operación es positivo, se incrementa el valor del semáforo. Asimismo, si semop es negativo, se decrementa el valor del semáforo si el resultado no es negativo. En caso contrario el proceso espera a que se dé esa circunstancia. Es decir, semop==1 produce una operación V y semop==-1, una operación P. Ejemplos de uso Para ilustrar de forma concreta el empleo de semáforos bajo UNIX, les mostramos unos ejemplos de subrutinas en C que les pueden servir como modelos para elaborar sus rutinas de sincronización en las prácticas de la asignatura. En concreto, son unas funciones que implementan las operaciones P y V de un semáforo clásico (inicialización, incremento y decremento con posible bloqueo del proceso llamador). Así definidas, o con pocas modificaciones, les pueden servir como la interfaz para uso de semáforos en sus aplicaciones. #include <sys/types.h> /* para key_t */ /* Crea un semáforo con un valor inicial, dada una clave */ /* Devuelve el identificador (válido o no) del semáforo */ int crea_sem ( key_t clave, int valor_inicial ); /* Operaciones P y V sobre un semáforo */ void sem_P ( int semid ); void sem_V ( int semid ); /***********************************/ /******** IMPLEMENTACIÓN *******/ /***********************************/ #include <sys/ipc.h> #include <sys/sem.h> #define PERMISOS 0644 /* crea_sem: abre o crea un semáforo */ int crea_sem ( key_t clave, int valor_inicial { int semid = semget( /* Abre o crea clave, 1, */ IPC_CREAT|PERMISOS ) un semáforo... */ /* con una cierta clave */ /* con un solo elemento /* lo crea (IPC_CREAT) con unos PERMISOS */ ); if ( semid==-1 ) return -1; /* Da el valor inicial al semáforo */ semctl ( semid, 0, SETVAL, valor_inicial ); return semid; } /* abre_sem: Abrir un semáforo que otro proceso ya creó */ int abre_sem (key_t clave) { return semget(clave,1,0); } /* Operaciones P y V */ void sem_P ( int semid ) /* Operación P */ { struct sembuf op_P [] = { 0, -1, 0 /* Decrementa semval o bloquea si cero */ }; semop ( semid, op_P, 1 ); } void sem_V ( int semid ) /* Operación V */ { struct sembuf op_V [] = { 0, 1, 0 /* Incrementa en 1 el semáforo */ }; semop ( semid, op_V, 1 ); } http://labsopa.dis.ulpgc.es/prog_c/IPC.HTM Unidad 2 Administración de procesos y del procesador. Ver archivo: Unidad2.pdf 2.7 Concepto de proceso. Un proceso es un programa en ejecución. Un proceso simple tiene un hilo de ejecución, por el momento dejemos esta última definición como un concepto, luego se verá en más detalle el concepto de hilo. Una vez definido que es un proceso nos podríamos preguntar cuál es la diferencia entre un programa y un proceso, y básicamente la diferencia es que un proceso es una actividad de cierto tipo que contiene un programa, entradas salidas y estados. Los procesos pueden ser cooperantes o independientes, en el primer caso se entiende que los procesos interactúan entre sí y pertenecen a una misma aplicación. En el caso de procesos independientes en general se debe a que no interactúan y un proceso no requiere información de otros o bien porque son procesos que pertenecen a distintos usuarios. • • Proceso - un programa en ejecución; la ejecucución del proceso debe progresar de manera secuencial. Un proceso incluye: – program counter – stack – data section Estados de los procesos • Nuevo: El proceso es creado. • • • • • Ejecución: Se ejecutan instrucciónes. Espera: El proceso esta en espera por la ocurrencia de algún evento. Listo: El proceso esta esperando a que le asignen el procesador. Terminado: El proceso finaliza su ejecución. Diagrama de estados de los procesos. Información asociada con cada proceso: • • • • • • • Estado del proceso Program counter Registros del CPU Información de planificación del CPU Memoria Información para administración Información de estatus de E/S Proceso: programa o comando en ejecución. Características: Un proceso consta de código, datos y pila. Los procesos existen en una jerarquía de árbol (varios Hijos, un sólo padre). El sistema asigna un identificador de proceso (PID) único al iniciar el proceso. El planificador de tareas asigna un tiempo compartido para el proceso según su prioridad (sólo root puede cambiar prioridades). Ejecución en 1er plano: proceso iniciado por el usuario o interactivo. Ejecución en 2o plano: proceso no interactivo que no necesita ser iniciado por el usuario. Demonio: proceso en 2o plano siempre disponible, que da servicio a varias tareas (debe ser propiedad del usuario root). Proceso zombi: proceso parado que queda en la tabla de procesos hasta que termine su padre. Este hecho se produce cuando el proceso padre no recoge el código de salida del proceso hijo. Proceso huérfano: proceso en ejecución cuyo padre ha finalizado. El nuevo identificador de proceso padre (PPID) coincide con el identificador del proceso init (1). Concepto de proceso. Un proceso es básicamente como un programa en ejecución. Consta del programa ejecutable, los datos y la pila del programa, su contador de programa, apuntador de pila y otros registros, y la otra información que se necesita para ejecutar el programa. La manera sencilla de tener una noción intuitiva de lo que es un proceso consiste en pensar en los sistemas con tiempo compartido. En forma periódica el sistema operativo decide suspender la ejecución de un proceso y dar inicio a la ejecución de otro, por ejemplo, porque el primero haya tomado ya más de su parte del tiempo del CPU, en terrenos del segundo. Cuando un proceso se suspende temporalmente como éste, debe reiniciarse después exactamente en el mismo estado en que se encontraba cuando se detuvo. Esto significa que toda la información relativa al proceso debe guardarse en forma explícita en algún lugar durante la suspensión. En muchos sistemas operativos, toda la información referente a cada proceso, diferente del contenido de su espacio de direcciones, se almacena en una tabla de sistema operativo, llamada tabla de procesos, la cual es un arreglo o lista enlazada de estructuras, una para cada proceso en existencia corriente. Si un proceso puede crear uno o más procesos diferentes (conocidos como proceso hijo) y estos procesos a la vez originan procesos hijos, se llega rápidamente a la estructura del árbol de procesos, observe figura # 14. Figura # 14. Estructura de árbol. Proceso Padre - Hijo. El proceso A creó dos procesos derivados, B y C. El proceso B creó tres derivados, D, E y F. Se dispone de otras llamadas al sistema para solicitar más memoria ( o para liberar memoria no utilizada), esperar a que termine un proceso hijo y cubrir su programa con uno diferente. En un sistema de multiprogramación, el (CPU) también cambia de un programa a otro, ejecutando cada uno en decenas o cientos de milisegundos. En tanto que, en rigor, en cualquier instante de tiempo, el CPU está ejecutando sólo un programa, en el curso de un segundo puede trabajar en varios programas, con la ilusión de paralelismo. Proceso: Informalmente se define como la actividad que resulta cuando un proceso ejercita un programa, y formalmente consiste en un vector formado por lo siguiente, figura # 15: P = < C, Co, E, S, A > Algoritmo Datos de salida Conjunto de datos de entrada {E1, E2, ... En} Contexto inicial Conjunto de contexto inicial {C0, C1, C2, ... Cn} Figura # 15. Un proceso puede tomar diferentes estados, puede estar corriendo, puede estar libre o puede estar detenido. Si consideramos que todo proceso esta constituido de una serie finita de actividades elementales una región crítica de un proceso se define como el conjunto de actividades elementales cuya ejecución exige el monopolio de recursos compartidos. Formalmente se define como el conjunto de partes de los contextos internos compartidos. Figura # 16 Figura # 16. Regiones críticas. Los problemas que deben resolverse en un contexto de procesos concurrentes (como regiones críticas) son los siguientes: - Exclusión mutua. - Sincronización. - Dead lock (Abraso mortal ó Interbloqueo) http://eduadis.itlapiedad.edu.mx/~hocegueras/so1/so1_211.html 2.8 Estados y transiciones de los procesos Un proceso puede estar en cualquiera de los siguientes tres estados: Listo, En ejecución y Bloqueado. Los procesos en el estado listo son los que pueden pasar a estado de ejecución si el planificador los selecciona. Los procesos en el estado ejecución son los que se están ejecutando en el procesador en ese momento dado. Los procesos que se encuentran en estado bloqueado están esperando la respuesta de algún otro proceso para poder continuar con su ejecución. Por ejemplo operación de E/S. Un proceso puede variar entre 5 distintos estados: New: cuando el proceso esta siendo creado. Running: cuando el proceso se esta ejecutando. Waiting: cuando el proceso esta esperando que se cumpla algún otro evento. Ready: cuando el proceso esta pronto para ejecutar, esperando por la CPU. Terminated: cuando el proceso esta terminado. Estado de los Procesos. Los bloques de control de los procesos se almacenan en colas, cada una de las cuales representa un estado particular de los procesos, existiendo en cada bloque, entre otras informaciones. Los estados de los procesos son internos del sistema operativo y transparentes al usuario. Los estados de los procesos se pueden dividir en dos tipos: activos e inactivos. 1.- Estados activos: Son aquellos que compiten con el procesador o están en condiciones de hacerlo. Se dividen en: Ejecución. Estado en el que se encuentra un proceso cuando tiene el control del procesador. En un sistema monoprocesador este estado sólo lo puede tener un proceso. Preparado. Aquellos procesos que están dispuestos para ser ejecutados, pero no están en ejecución por alguna causa (Interrupción, haber entrado en cola estando otro proceso en ejecución, etc.). Bloqueado. Son los procesos que no pueden ejecutarse de momento por necesitar algún recurso no disponible (generalmente recursos de entrada/salida). 2.- Estados inactivos: Son aquellos que no pueden competir por el procesador, pero que pueden volver a hacerlo por medio de ciertas operaciones. En estos estados se mantiene el bloque de control de proceso aparcado hasta que vuelva a ser activado. Se trata de procesos que no han terminado su trabajo que lo han impedido y que pueden volver a activarse desde el punto en que se quedaron sin que tengan que volver a ejecutarse desde el principio. Son de dos tipos: Suspendido bloqueado. Es el proceso que fue suspendido en espera de un evento, sin que hayan desaparecido las causas de su bloqueo. Suspendido programado. Es el proceso que han sido suspendido, pero no tiene causa parta estar bloqueado. Estados de los procesos •Nuevo: El proceso es creado. •Ejecución: Se ejecutan instrucciónes. •Espera: El proceso esta en espera por la ocurrencia de algún evento. •Listo: El proceso esta esperando a que le asignen el procesador. •Terminado: El proceso finaliza su ejecución. •Diagrama de estados de los procesos. Información asociada con cada proceso: •Estado del proceso •Program counter •Registros del CPU •Información de planificación del CPU •Memoria •Información para administración •Información de estatus de E/S Creación de Procesos. En UNIX el lanzamiento de procesos se realiza a través de la llamada al sistema fork(). Para utilizar esta llamada al sistema se emplea el header <unistd.h>. Su sintaxis es: Pid=fork(); Una llamada exitosa a fork() crea un proceso que es una copia del proceso que lo invoco. Duplica las variables del proceso original con una excepción, el nuevo proceso creado recibe le nombre de proceso hijo. El proceso que lo creo se denomina proceso padre, y el sistema devuelve un 0 al proceso hijo y un valor positivo distinto de 0 (pid del hijo) al proceso padre. Después de la llamada exitosa a fork(), tanto el proceso padre como el hijo corren en forma simultanea a partir del punto siguiente a la invocación del fork. La figura siguiente muestra esta situación: ….. Printf(“Antes del fork \n”); Pid=fork(); Printf(“Después del fork\n”); ……. AC A Antes ------------------------------------------ fork -----------------------------------------------------------Después ….. Printf(“Antes del fork \n”); Pid=fork(); Printf(“Después del fork\n”); ……. ….. Printf(“Antes del fork \n”); Pid=fork(); AC A Printf(“Después del fork\n”); ……. AC B En la figura se muestran 3 líneas de código de un proceso; un printf, un fork y otro printf. Hay 2 secciones en la figura: antes y después. La sección antes muestra la situación antes de la invocación al fork. Sólo existe el proceso A. El Apuntador AC (apuntador de código) señala a la instrucción que se está ejecutando. Como se está indicando el primer printf Imprime el texto “Antes del fork”. La sección después muestra la situación inmediatamente después de la llamada a fork. Existen ahora 2 procesos: Ay B. A es el proceso original, es decir, el proceso padre. B es una copia de A, es decir el proceso hijo. Ambos corren en forma simultánea. Dado que el apuntador AC, señala al último printf, se imprime el texto “Después del fork”. Se imprime 2 veces, una por parte del padre y la otra por parte del hijo. http://www.ittehuacan.edu.mx/lolguin/Procesos_final.doc Descriptor de procesos y recursos. Es una estructura de datos asociada a una entidad informática ya sea un (Recurso o Proceso), en la cual se indica y actualiza todas las informaciones relativas a dicha entidad. En el caso de un proceso la información general que contiene es: 1).Identificador: Que puede ser interno y externo. - Interno: Sistemas. - Externo: Usuario. 2).3).- 4).- Descripción de la máquina virtual asociada: como espacio virtual asignado, tipo de mapeo, tipo de acceso. Descripción de los recursos de la máquina que usa como: Lista de recursos que el proceso tiene derecho a solicitar, dirección real en la memoria principal, estado de las variables internas del CPU, prioridad, etc. Estados funcionales del proceso: Los estados de los procesos son internos del sistema operativo y transparente al usuario. Para éste, su proceso estará siempre en ejecución independientemente del estado en que se encuentre internamente el sistema. Los procesos se pueden encontrar en tres estados, observe figura # 34. Figura # 34. Estados de los procesos. Un proceso puede encontrarse en estado de ejecución, bloqueado o listo (que también se llama ejecutable). De estos estados de los procesos se derivan las siguientes transiciones y estados: Transición: El paso de un estado a otro. Transiciones: 1. El proceso se bloquea en la entrada. 2. El planificador elige otro proceso. 3. El planificador elige este proceso. 4. La entrada se vuelve disponible. Estados: 1. Ejecución (que en realidad hace uso del CPU en ese instante). 2. Bloqueado (incapaz de correr hasta que suceda algún evento externo. 3. Listo (ejecutable; se detiene temporalmente para permitir que se ejecute otro proceso). En estos tres estados son posibles cuatro transiciones: 1. Ocurre cuando un proceso descubre que no puede continuar. En algún sistema el proceso debe ejecutar una llamada al sistema, BLOCK, para entrar en estado bloqueado. 2 y 3. Son ocasionadas por el planificador del proceso, que es parte del sistema operativo sin que 2. 3. 4. el proceso llegue a saber de ella. Ocurre cuando el planificador decide que el proceso en ejecución ya ha corrido el tiempo suficiente y es tiempo de permitir que otro proceso tome tiempo de CPU. Ocurre cuando todos los procesos han utilizado su parte del tiempo y es hora de que el primer proceso vuelva a correr. Ocurre cuando aparece el evento externo que estaba esperando un proceso (como el arribo de alguna entrada). Si ningún otro proceso corre en ese instante, la transición 3 se activará de inmediato y el proceso iniciara su ejecución, de lo contrario tendrá que esperar, en estado listo. Los estados de los procesos se pueden dividir en dos tipos: activos e inactivos. * Estados activos. Son aquellos que compiten por el procesador o están en condiciones de hacerlo. Se dividen en, observe la figura # 35. Figura # 35. Estados de un proceso y sus transiciones. . Ejecución. . Listo. . Bloqueados. Estado en el que se encuentra un proceso cuando tiene el control del procesador. En un sistema monoprocesador este estado sólo lo puede tener proceso. Aquellos procesos que están dispuestos para ser ejecutados, pero no están en ejecución por alguna causa (interrupción, haber entrado, en la cola estando otro proceso en ejecución, etc. Son los procesos que no pueden ejecutarse de momento por necesitar algún recurso no disponible (generalmente recursos de E/S). * Estados inactivos. Son aquellos que no pueden competir por el procesador, pero que puedan volver a hacerlo por medio de ciertas operaciones. En estos estados se mantiene el bloque de control de proceso suspendido hasta que vuelva a ser activado. Son de dos tipos: Suspendido bloqueado. Es el proceso que fue suspendido en espera de un evento, sin que hayan desaparecido las causas de su bloqueo. Suspendido preparado. Es el proceso que ha sido suspendido, pero no tiene causa para estar bloqueado. Transiciones de estado. Todo proceso a lo largo de su existencia puede cambiar de estado varias veces. Cada uno de estos cambios se denomina transición de estado. Transiciones de estado de proceso, figura # 36. Figura # 36. Transiciones de estado. La asignación del CPU al primer proceso de la lista de listos es llamada despacho, y es ejecutado por la entidad del sistema llamada despachador. Indicamos esta transición de la manera siguiente: Despacho (nombre del proceso): Listo en ejecución. Mientras el proceso tenga CPU, se dice que esta en ejecución. Para prevenir que cualquier proceso monopolice el sistema, ya sea de manera accidental o maliciosamente el sistema operativo ajusta un reloj de interrupción del hardware para permitir al usuario ejecutar su proceso durante un intervalo de tiempo especifico o cuanto. Si el proceso no abandona voluntariamente el CPU, antes de que expire el intervalo, el reloj genera una interrupción, haciendo que el sistema operativo recupere el control. El sistema operativo hace que el proceso que anteriormente se hallaba en estado de ejecución pase al de listo, y hace que el primer proceso de la lista de listos pase al estado de ejecución. Estas transiciones de estado se indican como: - tiempo excedido (nombre del proceso): en ejecución Listo - bloqueado (nombre del proceso): en ejecución bloqueado El proceso cambia del estado bloqueado al estado listo: - despertar ( nombre del proceso): bloqueado Listo. Con esto tenemos definidas 4 transacciones de estado. - despacho ( nombre del proceso): Listo en ejecución - tiempo excedido ( nombre del proceso): en ejecución Listo - bloqueado ( nombre del proceso): en ejecución bloqueado - despertar ( nombre del proceso ): bloqueado Listo. Suspensión y Reanudación. Un proceso suspendido no puede proseguir sino hasta que lo reanuda otro proceso. Reanudar (o activar) un proceso implica reiniciarlo a partir del punto en el que se suspendió. Las operaciones de suspensión y reanudación son importantes por diversa razones: * 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 vez de abortarlo) hasta que verifique si el proceso funciona correctamente o no. * Algunos procesos se puede suspender como respuesta a las fluctuaciones a corto plazo de la carga del sistema y reanudarse cuando las cargas regresen a niveles normales. La figura # 37. Muestra los procesos con suspensión y reanudación. Figura # 37. Transiciones de estados de los procesos con suspensión y reanudación. La figura # 37, muestra el diagrama de transiciones de estado de los procesos, modificado para incluir las operaciones de suspensión y reanudación. Se han añadido dos nuevos estados, denominados suspendido-listo y suspendido bloqueado; no hay necesidad de un estado suspendido-ejecutado. Sobre la línea discontinua se encuentran los estados activos, y debajo de ella los estados suspendidos. Una suspensión puede ser iniciada por el propio proceso o por otro. En un sistema con un solo procesador el proceso en ejecución puede suspenderse a si mismo; ningún otro proceso podría estar en ejecución al mismo tiempo para realizar la suspensión (aunque otro proceso sí podría solicitar la suspensión cuando se ejecute). En un sistema de múltiples procesadores, un proceso en ejecución puede suspender a otro que se esté ejecutando en ese mismo momento en un procesador diferente. Solamente otro proceso puede suspender un proceso listo. La transición correspondiente es: 1) Suspender (nombre_del_proceso): Listo Suspendido-Listo. Un proceso puede hacer que otro proceso que se encuentre en el estado suspendido-listo pase al estado listo. La transición correspondiente es: 2) reanudar ( nombre_del_proceso): Suspendido-Listo Listo. Un proceso puede suspender a otro proceso que esté bloqueado. La transición correspondiente es: 3) suspender ( nombre_del_proceso): Bloqueado Suspendido-Bloqueado. Un proceso puede reanudar otro proceso que esté suspendido-bloqueado. La transición correspondiente es: 4) reanudar ( nombre_del_proceso): Suspendido-Bloqueado Bloqueado. Como la suspensión es por lo general una actividad de alta prioridad, se debe realizar de inmediato. Cuando se presenta finalmente el término de la operación ( si es que termina), el proceso suspendido-bloqueado realiza la siguiente transición. 5) completar(nombre_del _proceso): suspendido-bloqueado 6) suspender (nombre_del_proceso): Ejecución suspendido-listo. Suspendido-Listo. En conclusión 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 (esto se denomina comunicación entre procesos). Crear un proceso implica operaciones como: - Dar un nombre a un proceso. - Insertarlo en la lista de procesos conocidos del sistema ( o tabla de procesos) - Determinar la prioridad inicial de proceso. - Crear el bloque de control de proceso. - Asignar los recursos iniciales al proceso. Un proceso puede crear un nuevo proceso. Si lo hace el proceso creador se denomina proceso padre, y el proceso creado, proceso hijo. Sólo se necesita un padre para crear un hijo. Tal creación origina una estructura jerárquica de procesos. No se puede destruir un proceso cuando este ha creado otros procesos. Destruir un proceso implica eliminarlo del sistema. Se le remueve de la tabla o listas del sistema, sus recursos se devuelven al sistema y su bloque de control de proceso se borra (es decir, el espacio de memoria ocupado por su PCB se devuelve al espacio de memoria disponible. http://eduadis.itlapiedad.edu.mx/~hocegueras/so1/so1_411.html Operaciones de procesos y recursos. Los sistemas operativos poseen una serie de funciones cuyo objetivo es el de la manipulación de los procesos. En general las operaciones que se pueden hacer sobre un proceso son las siguientes: . Crear el proceso. Se produce con la orden de ejecución del programa y suele varios argumentos, como el nombre y la prioridad del proceso, figura # 37. Figura # 37. Creación de un proceso. La creación de un proceso puede ser de dos tipos: necesitar . Jerárquica. En ella cada proceso que se crea es hijo del proceso creador y hereda el entorno de ejecución de su padre. El primer proceso que ejecuta un usuario será hijo del intérprete de comandos con el que interactúa, figura # 39. Figura # 39. Jerarquía de procesos. . No jerárquico. Cada proceso creado por otro proceso se ejecuta independientemente de su creador con un entorno diferente. Es un tipo de creación que no suele darse en los sistemas operativos actuales. Además de los dos tipos anteriores se pueden realizar las operaciones siguientes: . Destruir un proceso. Se trata de la orden de eliminación del proceso con la cual el sistema operativo destruye su PCB ( Proces control Block). . Suspender un proceso. Es una operación de alta prioridad que paraliza un proceso que puede ser reanudado posteriormente. Suele utilizarse en ocasiones de mal funcionamiento o sobrecarga del sistema. . Reanudar un proceso. Trata de activar un proceso que ha sido previamente suspendido. . Cambiar la prioridad de un proceso. . Temporizar la ejecución de un proceso. Hace que un determinado proceso se ejecute cada cierto tiempo (segundos, minutos, horas,...) por etapas o de una sola vez, pero transcurrido un periodo de tiempo fijo. . Despertar un proceso. Es una forma de desbloquear un proceso que habrá sido bloqueado previamente por temporización o cualquier otra causa. http://eduadis.itlapiedad.edu.mx/~hocegueras/so1/so1_412.html 2.9 Procesos ligeros (Hilos o hebras). Procesos ligeros Los procesos ligeros son programas en ejecución son básicamente procesos pero a diferencia de éstos últimos que solo tienen un hilo de ejecución los primeros tienen el hilo principal más hilos secundarios o hijos, en éste caso todos los procesos hijos comparten la información del hilo principal pero además puede cada hilo tener su información privada. Dentro de la información propia tenemos: Contador de programa Pila Registros. Estado del proceso ligero. Dentro de la información compartida tenemos: Variables globales. Archivos abiertos Señales Semáforos. Contabilidad. Los hilos o procesos ligeros son una parte de código o miniprograma que puede ser ejecutada independientemente, de forma que una aplicación o un applet puede tener varios hilos ejecutándose simultáneamente y efectuando distintas tareas; estos hilos se encuentran dentro de un programa y son parte de él. Los hilos, a veces también llamados contextos de ejecución, pueden ser utilizados para la implementación de algoritmos paralelos o procesos concurrentes, sin ser necesario disponer de equipos con estructura de multiprocesador. En el caso de un solo procesador, los procesos ligeros incorporan mecanismos para compartirlo, estableciéndose prioridades entre ellos y también facilidades de sincronización, cuando es necesario. Multiproceso se refiere a dos programas que se ejecutan "aparentemente" a la vez, bajo el control del sistema operativo. Multihilo se refiere a que dos o mas tareas se ejecutan "aparentemente" a la vez, dentro de un mismo programa. http://www.monografias.com/trabajos20/paradigmas-deprogramacion/paradigmas-de-programacion.shtml ver archivo: procesosligeros.doc e hilos.pdf 2.10 Concurrencia y secuenciabilidad. Procesos concurrentes. Los procesos son concurrentes si existen simultáneamente. Los procesos concurrentes pueden funcionar en forma totalmente independiente unos de otros, o pueden ser asíncronos, lo cual significa que en ocasiones requiere cierta sincronización y cooperación. Las siguientes definiciones son esenciales para comprender los conceptos de concurrencia y secuencialidad. * Actividad. . Procesos: Es un programa en ejecución. . Tarea: Son las distintas partes de un proceso que se ejecutan simultáneamente. * Sistemas: . Multiprogramación: Admiten varias actividades que comparten el procesador, pero sólo una puede estar ejecutándose en un momento dado. . Multiproceso: Las actividades se ejecutan en sus propios procesadores, conectados a través de una red de comunicaciones. * Paralelismo: Es la ejecución de diversas actividades simultáneamente en varios procesadores. Si sólo existe un procesador gestionando multiprogramación, se puede decir que existe pseudoparalelismo. Se trata de un concepto físico producido por la existencia de varios procesadores. * Concurrencia: Es la existencia de varias actividades ejecutándose simultáneamente, y necesitan sincronizarse para actuar conjuntamente. Se trata, en este caso, de un concepto lógico, ya que sólo hace referencia a las actividades, sin importar el número de procesadores presentes. Para que dos actividades, sean concurrentes, es necesario que tengan relación entre sí, como puede ser la cooperación en un trabajo determinado o el uso de información compartida. En un sistema monoprocesador, la existencia de multiprogramación es condición necesaria, pero no suficiente para que exista concurrencia, ya que los procesos pueden ejecutarse independientemente. Por ejemplo, un editor y un compilador pueden estar ejecutándose simultáneamente en una computadora sin que exista concurrencia entre ellos. Por otro lado si un programa se está ejecutando y se encuentra grabando datos en un archivo, y otro programa también en ejecución está leyendo datos de ese mismo archivo, sí existe concurrencia entre ellos, pues el funcionamiento de uno interfiere en el funcionamiento de otro. Si un sistema es multiprocesador, también pueden presentarse situaciones de concurrencia siempre y cuando las actividades necesiten actuar entre sí, bien por utilizar información común, o por cualquier otra causa. Los procesos del sistema pueden ejecutarse concurrentemente, puede haber múltiples tareas en el CPU con varios procesos. Existen varias razones para permitir la ejecución concurrente: * Compartir recursos físicos. Ya que los recursos del hardware de la computadora son limitados, nos podemos ver obligados a compartirlos en un entorno multiusuario. * Compartir recursos lógicos. Puesto que varios usuarios pueden interesarse en el mismo elemento de información (por ejemplo un archivo compartido), debemos proporcionar un entorno que permita el acceso concurrente a estos tipos de recursos. * Acelerar los cálculos. Si queremos que una tarea se ejecute con mayor rapidez, debemos dividirla en subtareas, cada una de las cuales se ejecutara, en paralelo con las demás. * Modularidad. Podremos construir el sistema en forma modular, dividiendo las funciones del sistema en procesos separados. * Comodidad. Un usuario puede tener que ejecutar varias tareas a la vez, por ejemplo puede editar, imprimir y compilar en paralelo. La ejecución concurrente que requiere la cooperación entre procesos necesita un mecanismo para la sincronización y comunicación de procesos, exclusión mutua y sincronización. http://eduadis.itlapiedad.edu.mx/~hocegueras/so1/so1_212.html Problemas de Concurrencia En los sistemas de tiempo compartido (aquellos con varios usuarios, procesos, tareas, trabajos que reparten el uso de CPU entre estos) se presentan muchos problemas debido a que los procesos compiten por los recursos del sistema. Imagine que un proceso está escribiendo en la unidad de cinta y se le termina su turno de ejecución e inmediatamente después el proceso elegido para ejecutarse comienza a escribir sobre la misma cinta. El resultado es una cinta cuyo contenido es un desastre de datos mezclados. Así como la cinta, existen una multitud de recursos cuyo acceso debe der controlado para evitar los problemas de la concurrencia. El sistema operativo debe ofrecer mecanismos para sincronizar la ejecución de procesos: semáforos, envío de mensajes, 'pipes', etc. Los semáforos son rutinas de software (que en su nivel más interno se auxilian del hardware) para lograr exclusión mutua en el uso de recursos. Para entender este y otros mecanismos es importante entender los problemas generales de concurrencia, los cuales se describen enseguida. Condiciones de Carrera o Competencia: La condición de carrera (race condition) ocurre cuando dos o más procesos accesan un recurso compartido sin control, de manera que el resultado combinado de este acceso depende del orden de llegada. Suponga, por ejemplo, que dos clientes de un banco realizan cada uno una operación en cajeros diferentes al mismo tiempo. El usuario A quiere hacer un depósito. El B un retiro. El usuario A comienza la transacción y lee su saldo que es 1000. En ese momento pierde su turno de ejecución (y su saldo queda como 1000) y el usuario B inicia el retiro: lee el saldo que es 1000, retira 200 y almacena el nuevo saldo que es 800 y termina. El turno de ejecución regresa al usuario A el cual hace su depósito de 100, quedando saldo = saldo + 100 = 1000 + 100 = 1100. Como se ve, el retiro se perdió y eso le encanta al usuario A y B, pero al banquero no le convino esta transacción. El error pudo ser al revés, quedando el saldo final en 800. Postergación o Aplazamiento Indefinido(a): Esto se mencionó en el apartado anterior y consiste en el hecho de que uno o varios procesos nunca reciban el suficiente tiempo de ejecución para terminar su tarea. Por ejemplo, que un proceso ocupe un recurso y lo marque como 'ocupado' y que termine sin marcarlo como 'desocupado'. Si algún otro proceso pide ese recurso, lo verá 'ocupado' y esperará indefinidamente a que se 'desocupe'. Condición de Espera Circular: Esto ocurre cuando dos o más procesos forman una cadena de espera que los involucra a todos. Por ejemplo, suponga que el proceso A tiene asignado el recurso 'cinta' y el proceso B tiene asignado el recurso 'disco'. En ese momento al proceso A se le ocurre pedir el recurso 'disco' y al proceso B el recurso 'cinta'. Ahi se forma una espera circular entre esos dos procesos que se puede evitar quitándole a la fuerza un recurso a cualquiera de los dos procesos. Condición de No Apropiación: Esta condición no resulta precisamente de la concurrencia, pero juega un papel importante en este ambiente. Esta condición especifica que si un proceso tiene asignado un recurso, dicho recurso no puede arrebatársele por ningún motivo, y estará disponible hasta que el proceso lo 'suelte' por su voluntad. Condición de Espera Ocupada: Esta condición consiste en que un proceso pide un recurso que ya está asignado a otro proceso y la condición de no apropiación se debe cumplir. Entonces el proceso estará gastando el resto de su time slice checando si el recurso fue liberado. Es decir, desperdicia su tiempo de ejecución en esperar. La solución más común a este problema consiste en que el sistema operativo se dé cuenta de esta situación y mande a una cola de espera al proceso, otorgándole inmediatamente el turno de ejecución a otro proceso. Condición de Exclusión Mutua: Cuando un proceso usa un recurso del sistema realiza una serie de operaciones sobre el recurso y después lo deja de usar. A la sección de código que usa ese recurso se le llama 'región crítica'. La condición de exclusión mutua establece que solamente se permite a un proceso estar dentro de la misma región crítica. Esto es, que en cualquier momento solamente un proceso puede usar un recurso a la vez. Para lograr la exclusión mutua se ideo también el concepto de 'región crítica'. Para logar la exclusión mutua generalmente se usan algunas técnicas para lograr entrar a la región crítica: semáforos, monitores, el algoritmo de Dekker y Peterson, los 'candados'. Para ver una descripción de estos algoritmos consulte Condición de Ocupar y Esperar un Recurso: Consiste en que un proceso pide un recurso y se le asigna. Antes de soltarlo, pide otro recurso que otro proceso ya tiene asignado. Los problemas descritos son todos importantes para el sistema operativo, ya que debe ser capaz de prevenir o corregirlos. Tal vez el problema más serio que se puede presentar en un ambiente de concurrencia es el 'abrazo mortal', también llamado 'trabazón' y en inglés deadlock. El deadlock es una condición que ningún sistema o conjunto de procesos quisiera exhibir, ya que consiste en que se presentan al mismo tiempo cuatro condiciones necesarias: La condición de no apropiación, la condición de espera circular, la condición de exclusión mutua y la condición de ocupar y esperar un recurso. Ante esto, si el deadlock involucra a todos los procesos del sistema, el sistema ya no podrá hacer algo productivo. Si el deadlock involucra algunos procesos, éstos quedarán congelados para siempre. 2.10.1 Exclusión mutua de secciones criticas. Exclusión Mutua. Consiste en garantizar que durante la ejecución de una región crítica los recursos compartidos solo se asignen a uno y solo a uno de los procesos. Si un recurso compartido es una variable, la exclusión mutua asegura que a lo más un proceso a la vez ha accedido a ella durante la actualización crítica que conduce a valores temporalmente inestables. Consecuentemente los otros procesos ven solamente valores estables de las variables compartidas. Con los dispositivos compartidos la necesidad para la exclusión mutua puede ser incluso más obvia cuando uno considera el problema que puede provocar sus usos. Por ejemplo, supongamos que en el sistema existe un archivo formado por registros compuestos por 5 campos, figura # 18: Figura # 18. Registro de 5 campos. Para que un registro sea valido debe estar totalmente actualizado, es decir, si se modifica el valor del campo A, el resto de los campos deben ser coherentes con el nuevo valor de dicho campo, ya que de otro modo el registro sería inconsistente. Si en el momento en que un proceso escribe o modifica un registro y existe otro proceso que realiza la lectura de ese mismo registro, y el primero de ellos sólo hubiese tenido tiempo de modificar el campo A, la información obtenida por el segundo proceso seria inconsistente. Para evitar esto se deben sincronizar los procesos de manera que mientras uno escribe, otro pueda leer. Esto no ocurre en aquellos casos en que dos procesos tratan de leer en el mismo archivo, aún coincidiendo en el mismo registro. Generalizando. Supongamos que los dos procesos que coinciden en el mismo registró, uno esta escribiendo y el otro leyendo, llamados ESCRIBIR y LEER, se encuentran en un sistema monoprocesador multiprogramado y son los únicos presentes en ese momento, ver figura # 19 Figura # 19. Concurrencia En el momento de un cambio de proceso del uno al otro se pueden producir las siguientes situaciones: . Sin sincronización entre procesos. Puede darse el caso de que ESCRIBIR esté actualizando un registro y se quede a medías, sorprendiéndole el cambio de proceso, por tanto, terminará de escribirlo cuando vuelva a hacer uso del procesador. Con el cambio le tocará el turno al proceso LEER, que accederá a dicho registro pudiendo leerlo completamente. Es evidente que los datos leídos serán inconsistentes. . Con sincronización entre procesos. Supongamos algún mecanismo que prohíba la lectura (bloqueo de registros) a cualquier proceso, mientras el proceso ESCRIBIR esté realizando alguna operación. En este caso, LEER, al hacer uso del procesador que se encuentra bloqueado, quedaría en espera de que el registro quede totalmente escrito y se proceda a su desbloqueo, LEER pasaría a estado bloqueado, ESCRIBIR terminaría su trabajo sobre el registro y en el siguiente cambio LEER procedería a hacer el suyo. Esta sincronización por la cual una actividad impide que otras puedan tener acceso a un dato mientras se encuentra realizando una operación sobre el mismo es lo que se conoce como exclusión mutua. La zona de código de un proceso que no puede ser interrumpida por otro, por los motivos expuestos anteriormente se le llama Región Crítica. http://eduadis.itlapiedad.edu.mx/~hocegueras/so1/so1_214.html Regiones críticas. Es el conjunto de actividades elementales cuya ejecución exige el monopolio de recursos. Por ejemplo, para indicar que alguna acción se realizará con acceso exclusivo a ciertos datos compartidos. Región datos - compartidos do acción ¿Como evitar la región critica?. La clave para prevenir el problema aquí y en muchas otras situaciones en que interviene la memoria compartida, archivos compartidos y todo lo que se comparte, consiste en determinar alguna manera de prohibir que un proceso lea y escriba los datos compartidos al mismo tiempo. De otra manera lo que se necesita es la sincronización. Una manera de asegurar de que si un proceso ésta utilizando una variable o archivo compartido, es que los otros procesos no pueden hacer lo mismo. Para tener una solución adecuada a la región crítica se necesita que se cumplan cuatro condiciones: 1. Nunca dos procesos pueden encontrarse simultáneamente dentro de sus regiones críticas. 2. No se hacen suposiciones acerca de las velocidades relativas de los procesos o del Número de CPU. 3. Ningún proceso suspendido fuera de la región crítica debe bloquear a otros procesos. 4. Nunca un proceso debe querer entrar en forma arbitraria en su región crítica. Representación de regiones criticas, observe figura # 17 Figura # 17. Representación de regiones criticas Cuando se diseña un proceso que debe contener una o varias regiones críticas se deben de tomar en cuenta las siguientes consideraciones: . La región crítica debe ser ejecutada lo más rápido posible. . Un programa no debe ínter bloquearse en una región crítica. . Las regiones críticas deben ser programadas con mucho cuidado (no se permiten Ciclos indefinidos). . Mientras un proceso está en su región crítica otros procesos pueden continuar Ejecutándose fuera de las regiones críticas. . Cuando se tienen procesos que comparten datos, si un proceso deja la región Crítica otro de los procesos que espera a entrar en su región crítica puede proceder. Cuando el proceso termina, voluntaria o involuntariamente, el sistema operativo debe de realizar la limpieza propia de fin de proceso y liberar la exclusión mutua de otros procesos. http://eduadis.itlapiedad.edu.mx/~hocegueras/so1/so1_213.html La exclusión mutua: Forma de asegurar que si un proceso está usando una variable o archivo compartido, los otros procesos quedarán excluidos de hacer lo mismo. Los procesos pueden tener en su código secciones en que realizan cálculos internos y operaciones que no dan lugar a condiciones de competencia. Sin embargo existen secciones de programa en que el proceso está accediendo a recursos compartidos que pueden dar pié a condiciones de competencia. La parte del programa en que se accede a un recurso compartido se denomina sección o región crítica (requisito necesario, pero no suficiente). Los requisitos para que procesos paralelos cooperen de manera correcta usando datos compartidos son los siguientes: Dos procesos nunca pueden estar simultáneamente dentro de sus regiones críticas. No se puede suponer nada acerca de las velocidades de ejecución de los procesos o el número de las CPU. Ningún proceso que se ejecute fuera de su región crítica puede bloquear a otros procesos. Ningún proceso deberá tener una espera indefinida para entrar en su región crítica. La exclusión mutua debe ponerse en práctica sólo cuando los procesos obtienen acceso a datos compartidos modificables; cuando los procesos realizan operaciones que no entran en conflicto con otras, deben permitirse que procedan concurrentemente. Cuando un proceso obtiene acceso a datos compartidos modificables, se dice que se encuentra en una sección crítica. Es evidente que, para evitar la clase de problemas observados en la sección anterior, debe asegurarse que cuando un proceso se encuentre en una sección crítica, los demás procesos (o al menos los que tengan acceso a los datos compartidos) no pueden entrar a sus propias secciones críticas. Mientras un proceso se encuentra en su sección crítica, otros procesos pueden, claro está, seguir ejecutándose fuera de sus secciones críticas. Cuando un proceso abandona su región crítica, otro proceso que espera entrar en su propia sección crítica (si existe algún proceso en espera). Lograr que se cumpla la exclusión mutua es uno de los problemas fundamentales de la programación concurrente. Se han propuesto muchas soluciones, algunas de software y otras de hardware, algunas sencillas y otras complejas, y algunas que requieren la cooperación voluntaria de los procesos y otras que exigen un escrito ajuste a rígidos protocolos. Encontrarse dentro de una región crítica es un estado especial concedido a un proceso. El proceso tiene acceso exclusivo a los datos compartidos y los demás procesos que requieran acceso a los datos en ese momento deben esperar. Así pues, las secciones críticas deben ejecutarse tan rápido como sea posible; un proceso no se debe bloquear dentro de su propia sección crítica y las secciones críticas deben codificarse con mucho cuidado (para evitar, por ejemplo, la posibilidad de ciclos infinitos). Si un proceso de una sección crítica termina, ya sea voluntaria o involuntariamente, el sistema operativo, al realizar su mantenimiento de terminaciones, debe liberar la exclusión mutua de manera que otros procesos puedan entrar en sus regiones críticas. El problema de la Sección Crítica n procesos compitiendo para utilizar algún dato compartido. Cada proceso tiene un segmento de código, llamado sección crítica, en el que se accede al dato compartido. Problema – asegurarse de que cuando un proceso esta ejecutándose en su sección crítica, a ningún otro proceso se le permite ejecutar la suya. Estructura del proceso Pi repeat entry section sección crítica exit section sección restante until false; Solución al problema de la Sección Crítica Una solución al problema de la sección crítica debe satisfacer los siguientes tres requerimientos: 1. Exclusión Mútua. Si un proceso Pi esta ejecutandose en su sección crítica, entonces ninguno de los otros procesos puede estar en su sección crítica 2. Progreso. Si ningún proceso esta ejecutándose en su sección crítica y existen procesos que quieren entrar en su sección crítica, entonces la selección del próximo proceso que entrará a la sección crítica no puede ser pospuesta indefinidamente. 3. Espera limitada. Debe existir un límite del número de veces que se les permite a otros procesos entrar en sus secciones críticas en el intervalo entre que un proceso ha hecho un requerimiento para entrar en su sección crítica y que se le concede el permiso. Se supone que cada proceso se ejecuta a velocidad distinta de cero. Ninguna suposición respecto a la velocidad relativa de los n procesos. Intentos iniciales para resolver el problema Inhibir las interrupciones. Solo dos procesos, P0 and P1 Estructura general del proceso Pi repeat entry section sección crítica exit section sección restante until false; Los procesos pueden compartir algunas variables comunes para sincronizar sus acciones. Algoritmo 1 Variables compartidas: – var turn: (0..1); inicialmente turn = 0 – turn = i ? Pi puede entrar en su sección crítica Proceso Pi repeat while turn ? i do no-op; sección crítica turn := j; sección restante until false; Satisface la condición de exclusión mútua, pero no la de progreso (si turn=0 y P1 esta listo para entrar en su sección crítica, P1 no puede hacerlo, incluso aunque P0 este en la sección restante) Algoritmo 2 Variables compartidas – var flag: array [0..1] of boolean; inicialmente flag [0] = flag [1] = false. – flag [i] = true ? Pi listo para entrar en su sección crítica Proceso Pi repeat flag[i] := true; while flag[j] do no-op; sección crítica flag [i] := false; sección restante until false; Satisface la exclusión mútua, pero no el requerimiento de progreso. (P0 pone flag[0 ] =true y P1 pone flag[1 ] =true; cada uno esperando al otro indefinidamente) Algoritmo 3 - Combinación de las variables compartidas de los algoritmos 1 y 2. - Proceso Pi repeat flag [i] := true; turn := j; while (flag [j] and turn = j) do no-op; sección crítica flag [i] := false; sección restante until false; - Cumple los tres requerimientos; resuelve el problema de la sección crítica para dos procesos. Algoritmo del panadero Antes de entrar a su sección crítica, los procesos reciben unnúmero. El que posea el número menor entra en la sección crítica. Si los procesos Pi y Pj reciben el mismo número, si i < j, entonces Pi es servido primero; si no lo es Pj . El esquema de numeración siempre genera números en orden creciente; por ejemplo 1,2,3,3,3,3,4,5... 2.10.2 Sincronización de procesos en S.C. Sincronización. En procesos concurrentes, la ejecución de un proceso se desarrolla en forma asíncrona respecto a los otros. Sin embargo cuando dos, o más procesos necesitan entrar en región crítica, es necesario que exista una sincronización entre ellos a fin de garantizar que al menos uno y solo un proceso entrará en región crítica. Si una actividad desea impedir que otra acceda a ciertos datos compartidos, mientras no se cumpla una determinada condición, debemos sincronizar las actividades con dicha condición. Por tanto, la sincronización es un elemento necesario para asegurar la exclusión mutua. Existen tres algoritmos diseñados para este fin, son los siguientes: Espera Activa. Espera no Activa Mecanismos de Hardware. Algoritmo de Espera activa. Estos algoritmos establecen la espera de entrada a la región crítica con un bucle que será roto en el momento en que se cumpla una determinada condición. Se, les llama así por que el proceso no queda bloqueado en su ejecución, sino que constantemente compite por el procesador. Entre los distintos algoritmos de este tipo existentes podemos citar: . Espera con mutex. Algoritmo que utiliza un switch (MUTEX) a través del cual se produce la sincronización. . Alternancia. Ligeramente mejor que el anterior, utiliza también una variable turno para realizar el sincronismo entre los Procesos. . Algoritmo de DEKKER. Resuelve el problema mediante la solución propuesta por DEKKER, basando su funcionamiento en una Tabla unidimensional de dos elementos lógicos (Switches). Algoritmo de Espera no activa. Son los algoritmos que establecen la espera para entrar en la región crítica bloqueando, el proceso, haciendo que deje de competir por el procesador hasta que se cumpla la condición de desbloqueo. Entre estos algoritmos existen los siguientes: . Semáforos: Para eliminar los problemas que se producen con los algoritmos de espera activa, fundamentalmente los referidos a la sobrecarga que producen en el sistema, Dijkstra(1965) diseño un mecanismo basado en una variable entera utilizada como contador de peticiones de entrada a una sección crítica. Esta variable es compartida por todos los procesos del sistema. Este nuevo tipo de variable se denominó semáforo, por su capacidad de gestionar el tráfico de los proceso que desean acceder a datos compartidos. Con este sistema, cuando un proceso intente entrar en una región crítica mientras otro está accediendo a los datos compartidos, se bloqueará de igual manera que cuando un proceso accede a un recurso que está ocupado. Un semáforo se define como una variable entera que puede inicializarse y su valor no debe ser negativo y solo puede ser manipulada por las operaciones P y V. . Operaciones P y V. Estas operaciones son indivisibles, es decir que cuando un proceso ejecuta una de ellas no puede ser interrumpida. Operación V: Esta operación consiste en incrementar en uno el valor del semáforo sobre el que actúa, también es conocida como signal. Es una operación de liberación. Así, si se tiene un semáforo S, V de S V(S) o signal(S) causara S=S+1. V(MUTEX) libera Operación P: Bloqueo, decrementa en uno el valor del semáforo sobre el que actúa siempre y cuando el valor del semáforo es >=0 (positivo) también se le conoce en la literatura inglesa como Wait. Por ejemplo si tenemos P(S), Wait(S) si S=S-1. P(MUTEX) - Espera el proceso. De las definiciones anteriores se puede observar que el valor de un semáforo esta relacionado con el número de veces que se ejecutan, dichas operaciones es decir, el valor del semáforo S es igual a su valor inicial más número de operaciones V menos número de operaciones P realizadas por ese semáforo. VAL(S) = C(S) + NV(S) - NP(S) VALOR VALOR INICIAL NP( ) <= NV( ) +1 Por definición se tiene que el valor del semáforo debe ser mayor que cero, VAL(S)>0. En el caso cuando el valor del semáforo es cero que relación nos queda: NP(S) = C(S) + NV(S) Es importante señalar que la relación anterior será siempre valida independientemente del número de operaciones P y V ejecutadas sobre el semáforo. . Regiones críticas: Son sistemas que permiten establecer protecciones contra una mala utilización de los usuarios. Para ello sólo permiten que los datos compartidos se puedan acceder desde determinadas regiones quedando transparentes desde el resto. Tiene inconvenientes relacionados con la sincronización y no permite que varias actividades puedan realizar operaciones de lectura simultánea. . Regiones criticas condicionales: Es una mejora del método anterior tratando de resolver algunos problemas de sincronización que se presentan. . Monitores: Uno de los problemas en los mecanismos anteriores es que el programador tiene que proporcionar de forma explícita el modo de sincronización. Para evitarlo B. Hansen y C.A.R. Hoare desarrollarón un nuevo mecanismo denominado Monitor, que debe ser soportado por el lenguaje correspondiente. Un monitor permite compartir, segura y eficientemente, datos entre varias actividades, garantizando la exclusión mutua, sin necesidad de que el programador tenga que suministrarla explícitamente. Se basa en dos premisas: la primera es la abstracción de datos consistente en una técnica capaz de separar las operaciones a ejecutar sobre los datos, de los detalles de diseño propio de los mismos (los lenguajes Modula y Ada soportan este tipo de estructuras). La segunda es que realizan la exclusión mutua de forma implícita. La finalidad más útil de los monitores es reunir todas las funciones que operan sobre un conjunto de datos compartidos en un sólo módulo, de manera que todos los accesos a esos datos estarán forzados a utilizar dichas funciones. . Contadores de eventos: Es un mecanismo para sincronizar actividades sin que sea necesario forzar la exclusión mutua, ya sea por que no deseamos limitar la concurrencia de las actividades, o simplemente porque no lo necesitamos. Se basa en una variable entera que cuenta determinadas operaciones. . Mensajes: Mecanismo que permite intercambiar información necesaria durante el desarrollo normal de un proceso en ejecución. Es más un mecanismo de cooperación que de sincronización. Existen dos tipos de comunicación entre procesos: - Directa: Envió y recepción de mensajes entre si; de manera que se asocia un enlace vi direccional único entre cada dos procesos. - Indirecta: Mensajes enviados y recibidos a través de mail boxees o buzones de correo. Con este método cada proceso puede estar relacionado con tantos buzones como desee consiguiendo comunicarse con tantos procesos como sea necesario. Mecanismos de Hardware Son instrucciones hardware que aseguran la exclusión mutua. Entre las más utilizadas son las siguientes: . Deshabilitar interrupciones. Se puede forzar la exclusión mutua deshabilitando las interrupciones mientras haya alguna actividad en la región crítica. De este modo, dicha actividad no podrá ser interrumpida y, por tanto, no se podrá producir ningún cambio de proceso. La habilitación y deshabilitación se realiza con una instrucción máquina, es una operación rápida. . Instrucción TEST-AND-SET. Forza la exclusión mutua. La ventaja es que no puede ser interrumpida por que no muchas computadoras la poseen. . Lock. Se basa en la instrucción anterior y permite el acceso a la región crítica a un proceso en caso de no existir otra actividad dentro de su región crítica, no permitiendo en caso contrario. ¿Como resolver la exclusión mutua usando semáforos?. Para resolver el problema de debe hacer lo siguiente: 1.- Identificar todas las regiones críticas. 2.- Definir tantos semáforos como regiones críticas se tengan, dichos semáforos se inicializarán con 1. 3.- C/U de las regiones críticas será antecedida por la operación P y precedida por la operación V. Ejemplo: MUTEX es el semáforo Región crítica. Con lo anterior solo un proceso podrá entrar a la región crítica con lo que se esta asegurando la exclusión mutua. MUTEX = 1 * Que pasa si se tiene: A) P(MUTEX) SECCION CRITICA P(MUTEX) Entra el proceso, se decrementa en uno el semáforo pero no libera, por lo tanto hay un dead lock, no hay sincronización entre procesos ni exclusión mutua B) V(MUTEX) SECCION CRITICA Sale el proceso se incrementa en uno el semáforo libera el proceso, por lo tanto no hay dead lock, no V(MUTEX) origina proceso de exclusión mutua. C) V(MUTEX) SECCION CRITICA P(MUTEX) Sale el proceso se incrementa en uno el semáforo pero no libera, por lo tanto no hay dead lock. D) P(MUTEX) SECCION CRITICA V(MUTEX) Entra el proceso consume y libera, por lo tanto no hay dead lock, y da solución a la exclusión mutua y a la sincronización. Pregunta. * Varios procesos actualizan en forma concurrente a una lista ligada. a) Que problema se puede producir. R.- Se puede producir un problema de sincronización y no hay exclusión mutua. b) Es un problema de exclusión mutua. R.- Exclusión mutua. c) Como resolver el problema. R.- Dando solución a la exclusión mutua. * Si las operaciones P y V no fueran atómicas, la exclusión mutua seria violada. R.- Si por que los procesos pueden tomar el mismo valor y no se incrementa dos veces sino solo una. http://eduadis.itlapiedad.edu.mx/~hocegueras/so1/so1_215.html Problemas clásicos de sincronización. Este tipo de problemas constituyen ejemplos de una amplia clase de problemas de control de concurrencia. Estos problemas se utilizan para probar casi todos los esquemas de sincronización propuestos. En las soluciones se emplean semáforos para la solución. * El problema de buffer limitado. Supongamos que el depósito consiste en n buffers, cada uno capaz de almacenar un elemento. El semáforo MUTEX proporciona la exclusión mutua para los accesos al depósito de buffers y se le asigna un valor inicial de 1. Los semáforos vacíos y llenos cuentan el número de buffers vacíos y llenos, respectivamente. El semáforo vacío recibe 1 un valor inicial n; al semáforo lleno se le asigna el valor inicial 0. * El problema de los lectores y escritores. Un objeto de datos (como un archivo o un registro) va a ser compartido por varios procesos concurrentes. Algunos de estos procesos sólo quieren leer el contenido del objeto compartido, mientras que otros quieren actualizarlos (o sea, leerlo y escribirlo), hacemos una distinción entre estos dos tipos de procesos refiriéndonos a los procesos interesados sólo en leer como lectores y escritores y a los demás como escritores. Obviamente, el que dos lectores tengan acceso simultáneo al objeto de datos compartido no tendrá ningún efecto adverso; sin embargo, si un escritor y otro proceso (ya sea lector o escritor) tiene acceso simultáneo al objeto compartido, puede surgir el caos. Para asegurar que no surjan estas dificultades, es necesario que los escritores tengan acceso exclusivo al objeto compartido. A este problema de sincronización se le conoce como problema de los lectores y escritores, el cual es ha utilizado para probar casi todas las nuevas primitivas de sincronización. * El problema de los filósofos comensales. Cinco filósofos pasan su vida comiendo u pensando. Los filósofos comparten una mesa circular rodeada por cinco sillas, una para cada uno de ellos. En el centro de la mesa se encuentra una fuente de arroz, y también sobre la mesa hay cinco palillos chinos. Cuando un filósofo piensa, no interactúa con sus colegas. Ocasionalmente, un filósofo tiene hambre y trata de coger los dos palillos que están más cerca de él (los palillos colocados entre él y sus vecinos de la derecha y de la izquierda). Un filósofo sólo puede coger un palillo a la vez y, obviamente, no puede ser el que esta en la mano de un vecino. Cuando un filósofo ambiento tiene sus dos palillos al mismo tiempo come sin soltarlos. Cuando termina de comer, coloca ambos palillos sobre la mesa y comienza a pensar otra vez. * Problema del productor consumidor. En un contexto de procesos concurrentes, se tiene un conjunto de procesos productores de mensajes y otro conjunto de procesos consumidores de mensajes. La zona donde se depositarán y recogerán los mensajes es un buffer de tamaño n (n localidades). Tanto productores como consumidores ejecutaran cíclicamente los siguientes algoritmos. Ver figura # 20. Figura # 20. Productor consumidor. El recurso que se va a compartir es el buffer por lo tanto la sección critica será el acceso y manipulación de dicho buffer. * Para resolver el problema de exclusión mutua será necesario definir un semáforo para controlar el acceso al buffer, figura # 21. Figura # 21. Definición de un semáforo para controlar el accedo a buffer. - Cuando el consumidor se apodera del buffer P ( ) !Sorpresa esta vacío ¡ Productor gana se apodera del buffer ¡¡¡sorpresa el buffer esta lleno!!! no va a poder depositar y por lo tanto va a liberar el buffer nunca hace V( ). Productor consumidor utilizando espera activa, figura # 22. Productor Produce msg. Lock (espacio disponible) Lock (acceso a buffer) Deposita msg. Unlock (acceso a buffer) Unlock (existe msg.) Figura # 22. Consumidor Lock (existe msg.) Lock (acceso a buffer) extrae msg. Unlock (acceso a buffer) Unlock (espacio disponible) Consume msg. Problema de sincronización. La sincronización entre productor y consumidor es necesaria debido a lo siguiente: Los productores no deben depositar mensajes si el buffer se encuentra lleno y los consumidores no deben accesar el buffer cuando este se encuentre vació. Para resolver el problema de definirá un semáforo que defina el espacio disponible y será inicializado con un valor igual a n y un semáforo que defina la existencia de mensaje el cual será inicializado con un 0. X * X Productor produce msg. P (espacio disponible) P (acceso a buffer) deposita msg V (acceso a buffer) V (existe msg) Consumidor P (existe msg.) P (acceso s buffer) extrae msg. V (acceso a buffer) V (espacio disponible) Consume msg. Solución a la exclusión mutua X – - Solución de la sincronización - Buffer lleno Espacio disponible=N, existe msg=0. Casos críticos - Buffer vacío http://eduadis.itlapiedad.edu.mx/~hocegueras/so1/so1_216.html 2.10.2.1 Mecanismo de semáforos. Semáforos Son una herramienta de sincronización. Es una variable protegida que solo puede ser modificada por la rutina de inicialización y por otras dos operaciones atómicas: P( ) <- wait V( ) <- signal Las operaciones a las cuales se puede acceder son: Inicialización: Crea un nuevo semáforo asignándole un valor inicial P(s): while (s=0) do no_op ATÓMICA s:=s-1 V(s): s:=s+1 ATÓMICA Existen básicamente dos tipos de semáforos: Semáforos contadores: Toman valores positivos mayores o iguales a 0. Se utilizan para sincronización de procesos. Semáforos binarios: Toman los valores 0 ó 1 y se utilizan para exclusión mutua. A continuación se presenta una solución mediante semáforos del problema productor/consumidor. #define N 100 semaphore mutex = 1; semaphore empty = N; semaphore full = 0; void productor(void) {int item; while(1){ produce_item(item); down(empty); down(mutex); enter_item(item); up(mutex); up(full);} } void consumidor(void) { int item; while(1){ down(full); down(mutex); remove_item(&item); up(mutex); up(empty); consume_item(item);} } En este caso tenemos la utilización de 3 semáforos, uno destinado al control de la exclusión mutua y los otros dos destinados a la sincronización de los procesos para el control de buffer lleno y vacío. Podríamos utilizar semáforos para un algoritmo de espera ocupada con n procesos, pero los n procesos que están ejecutando el while de la función P(s) van a la cola de ready en un instante de tiempo reduciendo la performance general del equipo. Para evitar la espera ocupada se crea un semáforo que sea un registro de un nuevo tipo: Semáforo = Record Valor:Integer L:Lista_de_Procesos End P(s) { s.Valor:= s.valor - 1 if s.Valor < 0 then agregar este proceso a s.L bloquear; end} V(s){ s.Valor:=s.Valor + 1 if s.Valor 0 then quitar un proceso y a s.L despertar(y) } Semáforos Un semáforo es un tipo de datos abstracto que permite el uso de un recurso de manera exclusiva cuando varios procesos están compitiendo. El tipo de datos abstracto cumple la siguiente semántica: El estado interno del semáforo cuenta cuantos procesos todavía pueden utilizar el recurso. Se puede realizar, por ejemplo, con un número entero que nunca llega a ser negativo. Exiten tres operaciones con un semáforo: init(), wait(), y signal() que realizan lo siguiente: init() : Inicializa el semáforo antes de que cualquier proceso haya ejecutado ni una operación wait() ni una operación signal() al límite de número de procesos que tengan derecho a acceder el recurso. Si se inicializa con 1, se ha contruido un semáforo binario. wait() : Si el estado indica cero, el proceso se queda atrapado en el semáforo hasta que sea despertado por otro proceso. Si el estado indica que un proceso más puede acceder el recurso se decrementa el contador y la operación termina con exito. La operación wait() tiene que estár implementada como una instrucción atómica. Sin embargo, en muchas implementaciones la operación wait() puede ser interrumpida. Normalmente existe una forma de comprobar si la salida del wait() es debido a una interrupción o porque se ha dado acceso al semáforo. signal() : Una vez se ha terminado el uso del recurso, el proceso lo señaliza al semáforo. Si queda algún proceso bloqueado en el semáforo uno de ellos sea despertado, sino se incrementa el contador. La operación signal() también tiene que estár implementada como instrucción atómica. En algunás implementaciones es posible comprobar si se haya despertado un proceso con exito en caso que hubiera alguno bloqueado. Para despertar los procesos se puede implementar varias formas que se destinguen en sus grados de justicia, por ejemplo con un simple sistema tipo FIFO. El acceso mutuo a regiones críticas se arregla con un semáforo que permita el acceso a un sólo proceso S.init(1) P1 a: loop b: S.wait() c: critical region d: S.signal() e: non-critical region f: endloop P2 loop S.wait() critical region S.signal() non-critical region endloop Observamos los siguiente detalles: Si algún proceso no libera el semáforo, se puede provocar un bloqueo. No hace falta que un proceso libere su propio recurso, es decir, la operación signal() puede sea ejecutada por otro proceso. Con simples semáforos no se puede imponer un orden en los procesos accediendo a diferentes recursos. Si existen en un entorno solamente semáforos binarios, se puede simular un semáforo general usando dos semáforos binarios y un contador, por ejemplo, con las variables delay, mutex y count. La operación init() inicializa el contador al número máximo permitido. El semáforo mutex asegura acceso mutuamente exclusivo al contador. El semáforo delay atrapa a los procesos que superan el número máximo permitido. La operación wait() se implementa de la siguiente manera: delay.wait() mutex.wait() decrement count if count greater 0 then delay.signal() mutex.signal() y la operación signal() se implementa de la siguiente manera: mutex.wait() increment count if count equal 1 then delay.signal() mutex.signal() Unas principales desventajas de semáforos son: no se puede imponer el uso correcto de los wait()s y signal()s no existe una asociación entre el semáforo y el recurso entre wait() y signal() el usuario puede realizar cualquier operación con el recurso http://trevinca.ei.uvigo.es/~formella/doc/cd04/node64.html 2.10.2.2 Mecanismo de monitores. Monitores Todas las estructuras que hemos visto hasta ahora siguen provocando problemas para el programador: el control sobre los recursos está distribuido por varios puntos de un programa no hay protección de las variables de control que siempre fueron globales Por eso se usa el concepto de monitores que implementan un nivel aún más alto de abstracción facilitando el acceso a recursos compartidos. Un monitor es un tipo de datos abstracto que contiene un conjunto de procedimientos de control de los cuales solamente un subconjunto es visible desde fuera un conjunto de datos privados, es decir, no visibles desde fuera El acceso al monitor está permitido solamente a través de los procedimientos públicos y el compilador garantiza exclusión mutua para todos los procedimientos. La implementación del monitor controla la exclusión mutua con colas de entrada que contengan todos los procesos bloqueados. Pueden existir varias colas y el controlador del monitor elige de cual cola se va a escoger el siguiente proceso para actuar sobre los datos. Un monitor no tiene acceso a variables exteriores con el resultado de que su comportamiento no puede depender de ellos. Una desventaja de los monitores es la exclusividad de su uso, es decir, la concurrencia está limitada si muchos procesos hacen uso del mismo monitor. Un aspecto que se encuentra en muchas implementaciones de monitores es la sincronización condicional, es decir, mientras un proceso está ejecutando un procedimiento del monitor (con exclusión mutua) puede dar paso a otro proceso liberando el cerrojo. Estas operaciones se suele llamar wait() o delay(). El proceso que ha liberado el cerrojo se queda bloqueado hasta que otro proceso le despierta de nuevo. Este bloqueo temporal está realizado dentro del monitor (dicha técnica se refleja en Java con wait() y notify()). La técnica permite la sincronización entre procesos porque actuando sobre el mismo recurso los procesos pueden cambiar el estado del recurso y pasar así información de un proceso al otro. Lenguajes de alto nivel que facilitan la programación concurrente suelen tener monitores implementados dentro del lenguaje (por ejemplo refJavaMonitoresJava usa el concepto de monitores para realizar el acceso mutuamente exclusivo a sus objetos). El uso de monitores es bastante costoso, porque se pierde eficiencia por tanto bloqueo de los prosesos. Por eso se intenta aprovechar de primitivas más potentes para aliviar este problema, como vemos en la siguiente sección. http://trevinca.ei.uvigo.es/~formella/doc/cd04/node67.html Monitores Es un tipo de procedimientos, variables y estructuras de datos que se agrupan en un tipo de modulo especial. Tienen una propiedad importante: solo un proceso puede estar activo en un monitor en un instante de tiempo. Los monitores proveen un nuevo tipo de variables de condición con dos operaciones que operan sobre el (solo se usan dentro del procedimiento de el monitor). Wait -> wait(a) : produce que el proceso que ejecuta la instrucción sea interrumpido y removido de la cola de ready hasta que otro proceso lo habilite ejecutando la instrucción signal( )con la misma variable de condición. Signal -> signal(a) : Habilita la ejecución de algún proceso en espera por la ejecución de la instrucción wait con la misma variable de condición. 2.10.3 Interbloqueo (DeadLock). Deadlocks Si un conjunto de procesos esta en estado de espera por recursos y nunca cambia de estado porque los recursos por los que espera están siendo utilizados por otros procesos en estado de espera tenemos un DEADLOCK. Los recursos son la memoria, dispositivos de E/S, semáforos, archivos, etc. La forma en que un proceso hace uso de un recurso es: Solicitud: si el recurso esta disponible se le otorga, si no el proceso pasa a estado de espera. Uso: El proceso utiliza el recurso Liberación: el proceso debe liberar el recurso. Condiciones Necesarias para que se produzca DEADLOCK Si se presentan simultáneamente las cuatro siguientes condiciones el sistema esta en DEADLOCK. 1. EXCLUSION MUTUA: Por lo menos un proceso que tenga otorgado un recurso en forma exclusiva. 2. USO Y ESPERA: Debe existir al menos un proceso que este haciendo uso de un recurso y que este esperando por otros recursos asignados a otros procesos. 3. NO INTERRUPCION: Los recursos no pueden ser retirados al proceso. Si un proceso hace uso de un recurso no le podrá ser retirado hasta que voluntariamente el proceso lo libere. 4. ESPERA CIRCULAR: Debe existir un conjunto de procesos {P1.....Pn} tal que P1 espera por un recurso utilizado por P2,......,Pn espera por un recurso utilizado por P1. Resourse Allocation Graph(Grafo de utilizacion de recursos) Conjunto de Vértices: U =P U R P={P1,P2,....,Pn} R={R1,R2,...,Rn} Conjunto de Aristas: Una arista de un proceso Pi a un Recurso Rj significa que el proceso i esta haciendo una solicitud por el recurso Rj. Una arista del recurso Rj al proceso Pi, significa que el recurso esta asignado al proceso. Si un RAG no tiene ciclos el sistema no esta en DEADLOCK, sis si los tiene no se puede afirmar nada. Mecanismos para tratar con Deadlocks Evasion de Deadlocks Si se tiene cuidado al en la forma de asignar los recursos se pueden evitar situaciones de Deadlock. Supongamos un ambiente en el que todos los procesos declaren a priori la cantidad máxima de recursos que habá de usar. Estado Seguro: un estado es seguro si se pueden asignar recursos a cada proceso (hasta su máximo) en algún orden sin que se genere Deadlock. El estado es seguro si existe un ordenamiento de un conjunto de procesos {P1...Pn} tal que para cada Pi los recursos que Pi podrá utilizar pueden ser otorgados por los recursos disponibles mas los recursos utilizados por los procesos Pj,j<i. Si los recursos solicitados por Pi no pueden ser otorgados, Pi espera a que todos los procesos Pj hayan terminado. Algoritmo del banquero de Dijkstra Asigna peticiones de recursos siempre que las mismas den como resultado estados seguros. Solicitudes que den como resultado estados inseguros serán negadas hasta que puedan ser satisfechas. Este algoritmos evita situaciones de Deadlock asignando los recursos en forma correcta. Las debilidades del algoritmo son: que requiere que la cantidad de recursos del sistema sea constante, requiere una cantidad de procesos constante y requiere que los procesos garanticen que los recursos van a ser devueltos en un intervalo finito de tiempo. En el área de la informática, el problema del deadlock ha provocado y producido una serie de estudios y técnicas muy útiles, ya que éste puede surgir en una sola máquina o como consecuencia de compartir recursos en una red. En el área de las bases de datos y sistemas distribuidos han surgido técnicas como el 'two phase locking' y el 'two phase commit' que van más allá de este trabajo. Sin embargo, el interés principal sobre este problema se centra en generar técnicas para detectar, prevenir o corregir el deadlock. Las técnicas para prevenir el deadlock consisten en proveer mecanismos para evitar que se presente una o varias de las cuatro condiciones necesarias del deadlock. Algunas de ellas son: Asignar recursos en orden lineal: Esto significa que todos los recursos están etiquetados con un valor diferente y los procesos solo pueden hacer peticiones de recursos 'hacia adelante'. Esto es, que si un proceso tiene el recurso con etiqueta '5' no puede pedir recursos cuya etiqueta sea menor que '5'. Con esto se evita la condición de ocupar y esperar un recurso. Asignar todo o nada: Este mecanismo consiste en que el proceso pida todos los recursos que va a necesitar de una vez y el sistema se los da solamente si puede dárselos todos, si no, no le da nada y lo bloquea. Algoritmo del banquero: Este algoritmo usa una tabla de recursos para saber cuántos recursos tiene de todo tipo. También requiere que los procesos informen del máximo de recursos que va a usar de cada tipo. Cuando un proceso pide un recurso, el algoritmo verifica si asignándole ese recurso todavía le quedan otros del mismo tipo para que alguno de los procesos en el sistema todavía se le pueda dar hasta su máximo. Si la respuesta es afirmativa, el sistema se dice que está en 'estado seguro' y se otorga el recurso. Si la respuesta es negativa, se dice que el sistema está en estado inseguro y se hace esperar a ese proceso. Para detectar un deadlock, se puede usar el mismo algoritmo del banquero, que aunque no dice que hay un deadlock, sí dice cuándo se está en estado inseguro que es la antesala del deadlock. Sin embargo, para detectar el deadlock se pueden usar las 'gráficas de recursos'. En ellas se pueden usar cuadrados para indicar procesos y círculos para los recursos, y flechas para indicar si un recurso ya está asignado a un proceso o si un proceso está esperando un recurso. El deadlock es detectado cuando se puede hacer un viaje de ida y vuelta desde un proceso o recurso. Por ejemplo, suponga los siguientes eventos: evento 1: Proceso A pide recurso 1 y se le asigna. evento 2: Proceso A termina su time slice. evento 3: Proceso B pide recurso 2 y se le asigna. evento 4: Proceso B termina su time slice. evento 5: Proceso C pide recurso 3 y se le asigna. evento 6: Proceso C pide recurso 1 y como lo está ocupando el proceso A, espera. evento 7: Proceso B pide recurso 3 y se bloquea porque lo ocupa el proceso C. evento 8: Proceso A pide recurso 2 y se bloquea porque lo ocupa el proceso B. En la figura 5.1 se observa como el 'resource graph' fue evolucionando hasta que se presentó el deadlock, el cual significa que se puede viajar por las flechas desde un proceso o recurso hasta regresar al punto de partida. En el deadlock están involucrados los procesos A,B y C. Una vez que un deadlock se detecta, es obvio que el sistema está en problemas y lo único que resta por hacer es una de dos cosas: tener algún mecanismo de suspensión o reanudación [Deitel93] que permita copiar todo el contexto de un proceso incluyendo valores de memoria y aspecto de los periféricos que esté usando para reanudarlo otro día, o simplemente eliminar un proceso o arrebatarle el recurso, causando para ese proceso la pérdida de datos y tiempo. Deadlock Un S.O. tiene un número limitado de recursos y procesos que solicitan los recursos. ¶Como diseñador de un sistema operativo, ¿cuál es el problema para ti si algunos procesos un tu sistema están en deadlock esperando recursos? Los recursos retenidos por los procesos en deadlock no están disponibles para otros procesos, y los procesos en deadlock no pueden avanzar (es mal para los dueños de los procesos). Muchos SS.OO. modernos no tienen apoyo especial para prevenir deadlock (porque cuesta), pero es común en programación de sistemas en general (e.g., en programación distribuida). Características de deadlock El sistema tiene recursos de varios tipos: memoria, archivos, grabadores, impresoras, etc. Podemos tener más de un ejemplar de un tipo de recurso (e.g., tres impresoras). Cada uno de los ejemplares pueden satisfacer un solicitud de un proceso para el recurso. Los recursos son compartibles y permiten acceso a muchos procesos (e.g., los archivos de sólo lectura) o no compartibles (e.g., un grabador). Ejemplo: Tres procesos en un sistema con tres grabadores, cada proceso tiene un grabador y cada uno necesita uno más. Condiciones necesarias de deadlock: o ¶ Exclusión mutua. Por lo menos un recurso debe retenerse no compartido. ¿Por qué? o Retención y espera. Debe haber un proceso que retenga por lo menos un recurso y espere adquirir más recursos retenidos por otros. o No apropiación. Los recursos no se pueden expropiar. Los procesos liberan recursos sólo voluntariamente. o Espera circular. Debe haber un conjunto {P0, P1, ..., Pn} de procesos en espera tales que P0 espere un recurso de P1, P1 un recurso de P2, ..., y Pn un recurso de P0. Podemos usar un grafo de asignación de recursos para describir deadlock. Tenemos procesos (círculos), recursos (rectángulos con un punto para cada ejemplar), aristas de solicitud y de asignación (cambio instantáneamente). Un grafo sin ciclos implica que no hay deadlock. Si hay un ciclo, es posible que exista deadlock. Un ciclo es una condición necesaria pero no suficiente para deadlock. http://www.cs.virginia.edu/~knabe/iic2332/notes07.html Análisis. Definición. Abraso Mortal (Dead lock) o también llamado ínter bloqueo. En un contexto de procesos concurrentes, si el análisis de recursos a compartir no se hace cuidadosamente, se puede tener el riesgo de que dos o más procesos acaparen algún recurso y que se pongan en espera de que otro u otros liberen los recursos para poder continuar su ejecución, de tal manera que cada proceso permanecerá en una espera indefinida (infinita), observe el ejemplo de la figura # 23 Ejemplo: Se tienen 2 procesos P1 y P2. Se tiene 2 recursos Impresora y Unidad de disco: Figura # 23. Dead Lock. Cuando un proceso espera un evento que nunca se va a dar y el otro también lo espera Dead lock de un recurso simple. Muchos de los dead lock se deben a que un proceso retiene un recurso que debe ser usado en forma exclusiva. Es decir, el proceso tiene un recurso que sólo puede ser usado por un usuario a la vez. A estos recursos se les conoce como reutilizables en serie. Dead lock en sistemas de spool. Los sistemas de spool suelen ser los más propensos al dead lock. Varios trabajos parcialmente complejos que generan líneas de impresión a un archivo de spool pueden interbloquearse si el espacio disponible para trabajar se llena antes de completarse alguno de esos trabajos. La solución más común es limitar los spoolers de entrada de modo que no se lean más archivos cuando se llega al límite de su capacidad. Postergación indefinida. En los sistemas que mantienen procesos en espera mientras realizan la asignación de recursos y/o procesan la planificación de decisiones, es posible que un proceso sea postergado de manera indefinida mientras otro reciben la atención del sistema. A esta situación se le conoce como postergación indefinida, es diferente del dead lock pero sus consecuencias son igual de negativas. En algunos sistemas la postergación indefinida se evita aumentando la prioridad de un proceso mientras espera por un recurso, a esto se le llama envejecimiento. Conceptos sobre recursos. Un sistema operativo es sobre todo un administrador de recursos, existen básicamente dos tipos de recursos: * Recursos no apropiativos. Un recurso que no se puede liberar antes de completar su actividad sin perder la validez del proceso que lo usa, se dice que un recurso no apropiativo. Una impresora o una unidad de cinta no pueden ser liberados hasta que no termine su trabajo. * Recursos apropiativos. Un recurso que puede ser usado temporalmente por varios procesos sin comprometer el correcto funcionamiento de dichos procesos se dice que es un recurso apropiativo. El CPU y la memoria principal (mediante las técnicas de paginación) son recursos que pueden ser asignados temporalmente por varios procesos. La apropiatividad de recursos es extremadamente importante en los sistemas de multiprogramación. Los datos y los programas son recursos que tienen características especiales. En un sistema multiusuario donde se pueden compartir editores, compiladores y programas en general, es ineficiente cargar una copia de ellos para cada usuario que lo solicite. En lugar de ello se carga una sola vez a la memoria y se hacen varias copias de los datos, una por cada usuario. El código que no cambia mientras está en uso se llama código reéntrate. El código que puede ser cambiado pero que se inicializa cada vez que se usa se llama reutilizable en serie. El código reéntrate puede ser compartido simultáneamente por varios procesos mientras que el reutilizable en serie sólo puede ser usado por un proceso a la vez. Métodos para manejar los Dead Lock, figura # 24. - Prevención - No permitirlos - Evitarlos - Permitirlos y recuperarlos - Difícil y caro - Por perdida - de información Figura # 24. Prevención de Dead Lock. En principio existen cuatro áreas importantes en la investigación del dead lock, a saber: 1) Prevención: En las técnicas de prevención el interés se centra en condicionar un sistema para que elimine toda probabilidad de que ocurra un dead lock (normalmente a costa de recursos). 2) Evitación: En las técnicas para evitar, la idea es poner condiciones menos estrictas que la prevención, para lograr una mejor utilización de los recursos, pero procurando no caer en un dead lock. 3) Detección: Los métodos de detección se usan en sistemas que permiten la ocurrencia de un dead lock de forma voluntaria o involuntaria. 4) Recuperación: Los métodos de recuperación se usan para romper los dead lock en un sistema, para poder liberarlo de ellos y los procesos estancados pueden continuar y llegar a su fin. http://eduadis.itlapiedad.edu.mx/~hocegueras/so1/so1_311.html Modelo del sistema. Un sistema se compone de un número finito de recursos que se distribuyen entre varios procesos que compiten por ellos. Los recursos se dividen en varios tipos, cada uno de los cuales consiste en varios ejemplares idénticos. Los ciclos del UCP, el espacio de memoria, los archivos y los dispositivos de E/S (como impresoras y unidades de cinta) son ejemplos de tipos de recursos. Un proceso debe solicitar un recurso antes de usarlo, y liberarlo al terminar su uso. Un proceso puede solicitar cuantos recursos quiera para llevar a cabo su tarea. Obviamente, el número no puede exceder del total de recursos disponibles del sistema. En otras palabras, un proceso no puede solicitar tres impresoras si el sistema solo dispone de dos. En el modo de operación normal, un proceso solo puede utilizar un recurso en la secuencia siguiente: 1. 2. 3. Solicitud. Si la solicitud no puede atenderse de inmediato (por ejemplo, otro proceso está utilizando ese recurso), entonces el proceso solicitante debe esperar hasta que pueda adquirir el recurso. Utilización. El proceso puede trabajar con el recurso (por ejemplo, si el recurso es una impresora, el proceso puede imprimir en ella). Liberación. El proceso libera el recurso. La solicitud y liberación de recursos son llamadas al sistema. Algunos ejemplos son las llamadas Solicitar y Liberar dispositivos, Abrir y Cerrar archivos, y Asignar y Liberar memoria. La solicitud y liberación de otros recursos puede lograrse atreves de las operaciones espera (P) y señal (V) sobre semáforos. Además la utilización de recursos solo puede conseguirse mediante llamadas al sistema (por ejemplo, para leer o escribir en un archivo o dispositivo de E/S), de modo que para cada utilización, el sistema operativo verifica que el proceso que dispone del recurso ya lo había solicitado y ya se le había asignado. Una tabla del sistema registra si cada uno de los recursos está libre o asignado y, de estar asignado, a qué proceso. Si un proceso solicita un recurso que se encuentra asignado a otro, puede añadirse a la cola de procesos que esperan tal recurso. Un conjunto de procesos se encuentra en estado de bloqueo mutuo cuando cada uno de ellos espera un suceso que sólo puede originar otro proceso del mismo conjunto. http://eduadis.itlapiedad.edu.mx/~hocegueras/so1/so1_312.html Caracterización. Debe ser obvio que los bloqueos mutuos son indeseables, pues cuando se dan, los procesos nunca terminan su ejecución y los recursos del sistema se paralizan, impidiendo que se inicien otros procesos. Antes de analizar los distintos métodos para tratar el problema del bloqueo mutuo se describirán las circunstancias que los caracterizan. Condiciones necesarias para que ocurra un Dead Lock. Coffman, Elphick y Shoshani. Establecieron las cuatro condiciones necesarias para que se produzca un dead lock. 1.- Los procesos reclaman control exclusivo de los recursos que solicitan (exclusión mutua). 2.- Los procesos mantienen los recursos que se les han asignado mientras esperan por recursos adicionales (condición de espera). 3.- No se pueden tomar los recursos que los procesos tienen hasta su completa utilización (condición de no apropiatividad). 4.- Existe una cadena circular de procesos en la cual cada uno de ellos mantiene uno o más recursos que son requeridos por el siguiente proceso de la cadena (condición de espera circular). Se deben presentar las cuatro condiciones para que puede aparecer un Dead Lock. La condición de espera circular implica la condición de retención y espera, por lo que las cuatro condiciones no son completamente independientes. http://eduadis.itlapiedad.edu.mx/~hocegueras/so1/so1_313.html 2.10.3.1 Prevención. Prevención. En las estrategias de prevención de dead Locks, los recursos son otorgados a los procesos solicitados, de tal manera que la solicitud de un recurso nunca llega a un Dead Lock. Esta estrategia se cerciora de que cuando menos una de cuatro condiciones de Dead Lock nunca llegue a ocurrir. * Exclusión mutua. La condición de exclusión mutua debe conservarse para recursos no compartibles. Los recursos compartibles, no requieren acceso mutuamente excluyente y, por tanto, no pueden participar en un dead lock. Los archivos de sólo lectura son un buen ejemplo de recursos compartibles. Si varios procesos tratan de abrir al mismo tiempo un archivo de sólo lectura, se les puede otorgar accesos simultáneos al archivo, por lo general no es posible evitar dead lock`s negando la condición de exclusión mutua. Por su naturaleza algunos recursos no pueden compartirse. * Negación de la condición de "espera por". La primera estrategia de Havender requiere que todos los recursos que va a necesitar un proceso sean pedidos de una sola vez. El sistema deberá asignarlos según el principio "todo o nada". Si el conjunto de recursos que necesita un proceso está disponible se le asigna (todo) y se le permite entrar en ejecución. Si no es así, el proceso deberá esperar hasta que su conjunto de recursos esté disponible. Mientras un proceso espera. No podrá tener ningún recurso. Esta estrategia presenta las siguientes desventajas: * Puede llevar a la postergación indefinida, ya que quizá todos los recursos estén disponibles al mismo tiempo (costos de operación altos). requeridos * Puede llevar un serio desperdicio de recursos, se requiere tener una gran cantidad de recursos para poder responder a cumplir petición. * Es ineficiente por que decrementa la concurrencia del sistema. Una variante consiste en dividir el programa en bloques que puedan ser ejecutados con relativa independencia uno del otro. Esto reduce el desperdicio, pero implica un trabajo extra en el diseño de las aplicaciones. * Negación de la condición de "no apropiatividad". Cuando un sistema cuenta con los recursos suficientes para que los procesos puedan funcionar sin problemas (bloqueos). Cuando el sistema permite compartir los recursos y los procesos mantienen los que otros necesitan sucede un dead lock. La segunda estrategia sugiere que cuando a un proceso que mantiene recursos se le niegue una petición de recursos adicionales deberá liberar sus recursos y, si es necesario, pedirlos de nuevo, junto con los adicionales. Al retirar los recursos a un proceso que no puede avanzar se niega la condición de "no apropiatividad". Un problema de esta política es la postergación indefinida. * Negación de la condición de "espera circular". Si se da a los recursos una manera exclusiva y se obliga a los procesos a pedirlos en forma ascendente es imposible que ocurra una espera circular. Esta propuesta considera: + + + Los recursos deben ser numerados reflejando el orden en el cual la mayoría de los trabajos los usan, figura # 25. Los procesos deben pedir los recursos en forma ascendente, figura # 25. Para los procesos que requieren de los recursos en un orden diferente, los recursos deberán ser tomados y retenidos mucho antes de su utilización. (Implica el desperdicio de los recursos mantenidos pero no usados). Figura # 25. Ordenamiento lineal del recurso. El ordenamiento lineal elimina la posibilidad de la espera circular, pero, obliga al diseñador a trabajar más con sus códigos. Además, los números de recursos son asignados por la instalación y hay que vivir con ellos durante largos periodos (meses o años). Si los números cambian se tienen que rescribir los programas y los sistemas existentes. La forma más simple de prevenir un Dead Lock es obteniendo todos los recursos necesarios antes que el proceso continué y así se elimine la "condición de espera". En otro método de prevención de dead lock, un proceso bloqueado devuelve los recursos solicitados por un proceso activo, al igual que elimina la condición de "no apropiatividad" Rosenkrantz et al. Ha propuesto la siguiente optimización de este método. Todos los procesos son asignados a prioridades únicas que pueden ser totalmente ordenadas. Un proceso de retención cede el derecho de prioridad a otro proceso que sostiene el recurso necesario solo si el proceso de retención tiene el recurso necesario solo si el proceso de retención tiene mayor prioridad. Este método reduce los derechos de prioridad al 50% al igual que previene los dead locks. En el ordenamiento de Havender's todos los recursos son ordenados de manera única y todos los procesos solicitan los recursos de manera ascendente. Únicamente eliminando la condición de "espera circular". Si un proceso ya sostiene algunos recursos, entonces puede pedir solo aquellos acomodos en un rango superior en el orden. Obteniendo recursos, de ésta forma, previene la formación de un ciclo o de un "knot". http://eduadis.itlapiedad.edu.mx/~hocegueras/so1/so1_314.html Prevenir Se puede prevenir el bloqueo siempre y cuando se consiga que alguna de las condiciones necesarias para la existencia de un bloqueo no se produzca. 1. los procesos tienen que compartir recursos con exclusión mutua: o No se de a un proceso directamente acceso exclusivo al recurso, si no se usa otro proceso que realiza el trabajo de todos los demás manejando una cola de tareas (por ejemplo, un demonio para imprimir con su cola de documentos por imprimir). 2. los procesos quieren acceder a un recurso más mientras ya tienen acceso exclusivo a otro: o Se exige que un proceso pida todos los recursos que va a utilizar al comienzo de su trabajo 3. los recursos no permiten ser usados por más de un proceso al mismo tiempo: o Se permite que un proceso aborte a otro proceso con el fin de obtener acceso exclusivo al recurso. Hay que tener cuidado de no caer en livelock 4. existe una cadena circular entre peticiones de procesos y alocación de recursos: o Se ordenan los recursos línealmente y se fuerza a los procesos que accedan a los recursos en el orden impuesto. Así es imposible que se produzca un ciclo. En las prácticas aplicamos dicho método para prevenir bloqueos en la lista concurrente. http://trevinca.ei.uvigo.es/~formella/doc/cd04/node71.html Prevención de Deadlocks La estrategia consiste en anular alguna de las cuatro condiciones necesarias para que se produzca un Deadlock. 1. No puede ser anulada porque existen recursos que deben ser usados en modalidad exclusiva. 2. La alternativa sería hacer que todos los procesos solicitaran todos los recursos que habrán de utilizar antes de utilizarlos al momento de su ejecución lo cual sería muy ineficiente. 3. Para anular esta condición cuando un proceso solicita un recurso y este es negado el proceso deberá liberar sus recursos y solicitarlos nuevamente con los recursos adicionales. El problema es que hay recursos que no pueden ser interrumpidos. 4. Espera Circular: esta estrategia consiste en que el sistema operativo numere en forma exclusiva los recursos y obligue a los procesos a solicitar recursos en forma ascendente. El problema de esto es que quita posibilidades a la aplicación. Prevención de deadlock ¶ Deadlock no puede occurir a menos que tenemos todas las cuatro condiciones. Si aseguramos que no puede occurir por lo menos una de las condiciones, no podemos tener deadlock. ¶ Exclusión mutua. En general, no podemos eliminar esta condición. Hay recursos como impresoras que no son compartibles. ¶ Retención y espera. Para no occurir esta condición, cuando un proceso solicita recursos, no puede retener otros. Protocolos: o Un proceso puede solicitar recursos solamente si no tiene ningunos. o Un proceso tiene que solicitar todos los recursos antes de la ejecución. ¶ Problemas: o o La utilización de recursos puede ser baja. Starvation (bloqueo indefinido) si se necesitan algunos recursos populares. No apropiación. Si un proceso retiene varios recursos y solicita otro que no está disponible, se le expropian todos los recursos que retiene. El proceso tiene que recuperar todos los recursos antes de ejecutar otra vez. Pero en general no podemos exproprian recursos como impresoras y grabadores. Espera circular. Hacemos una ordenación de los tipos de recursos en el sistema (R1, R2, ...). Un proceso tiene que solicitar sus recursos en orden (y todos los ejemplares de un tipo al mismo tiempo). Si necesita un tipo de recurso más baja en la ordenación, tiene que liberar los otros que retiene. Problemas con la prevención de deadlock: Utilización baja de recursos y reducción de la productividad del sistema. http://www.cs.virginia.edu/~knabe/iic2332/notes07.html Evitar El sistema no da permiso de acceso a recursos si es posible que el proceso se bloquee en el futuro. Un método es el algoritmo del banquero (Dijkstra) que es un algoritmo centralizado y por eso posiblemente no muy practicable en muchas situaciones. Se garantiza que todos los procesos actuan de la siguiente manera en dos fases: 1. primero se obtiene todos los cerrojos necesarios para realizar una tarea, eso se realiza solamente si se puede obtener todos a la vez, 2. despues se realiza la tarea durante la cual posiblemente se liberan recursos que no son necesarias. Ejemplo: Asumimos que tengamos 3 procesos que actuan con varios recursos. El sistema dispone de 12 recursos. proceso recursos pedidos recursos reservados A 4 1 B 6 4 C 8 5 suma 18 10 es decir, de los 12 recursos disponibles ya 10 están ocupados. La única forma que se puede proceder es dar el acceso a los restantes 2 recursos al proceso B. Cuando B haya terminado va a liberar sus 6 recursos que incluso pueden estar distribuidos entre A y C, así que ambos también pueden realizar su trabajo. Con un argumento de inducción se verifica fácilmente que nunca se llega a ningún bloqueo. http://trevinca.ei.uvigo.es/~formella/doc/cd04/node70.html Evitación. Un método para evitar los Dead Lock`s consiste en requerir información adicional sobre cómo se solicitarán los recursos. Por ejemplo en un sistema con una unidad de cinta y una impresora, podríamos saber que el proceso P solicitará primero la unidad de cinta y luego la impresora, antes de liberar ambos recursos. El proceso Q, por otra parte, solicitará primero la impresora y después la unidad de cinta. Con este conocimiento de la secuencia completa de la solicitud y liberación para cada proceso para cada solicitud requiere que el sistema considera los recursos disponibles en ese momento, los actualmente asignados a cada proceso y las futuras solicitudes y liberaciones de cada proceso para decidir si puede satisfacer la solicitud presente o debe esperar para evitar un posible dead lock futuro. Los diversos algoritmos difieren en la cantidad y tipo de información que requieren. El modelo más sencillo y útil requiere que cada proceso declare el número máximo de recursos de cada tipo que puede necesitar. Con información a priori para cada proceso es posible construir un algoritmo que asegure que el sistema nunca entrará en estado de dead lock. Este algoritmo define la estrategia de evitación de dead lock`s. El estado de asignación de recursos viene definido por el número de recursos disponibles y asignados, y por la demanda máxima de los procesos. Un estado es seguro si el sistema puede asignar recursos a cada proceso (hasta el máximo) siguiendo algún orden u aun así evitar el dead lock. Más formalmente, un sistema se encuentra en estado seguro sólo si existe una secuencia segura. Si no existe esta secuencia, se dice que el estado del sistema es inseguro. Un estado seguro no es un estado de dead lock, y un estado de dead lock es un estado inseguro; pero no todos los estados inseguros son dead lock`s. http://eduadis.itlapiedad.edu.mx/~hocegueras/so1/so1_315.html 2.10.3.2 Detección. Detectar y actuar Se implementa un proceso adicional que vigila si los demás forman una cadena circular. Más preciso, se define el grafo de asignación de recursos: Los procesos y los recursos representan los nodos de un grafo. Se añade cada vez una arista entre un nodo tipo recurso y un nodo tipo proceso cuando el proceso ha obtenido acceso exclusivo al recurso. Se añade cada vez una arista entre un nodo tipo recurso y un nodo tipo proceso cuando el proceso está pidiendo acceso exclusivo al recurso. Se eliminan las aristas entre proceso y recurso y al revés cuando el proceso ya no usa el recurso. Cuando se detecta en el grafo resultante un ciclo, es decir, cuando ya no forma un grafo acíclico, se ha producido una posible situación de un bloqueo. Se puede reaccionar de dos maneras si se ha encontrado un ciclo: No se da permiso al último proceso de obtener el recurso. Sí se da permiso, pero una vez detectado el ciclo se aborta todos o algunos de los procesos involucrados. Sin embargo, las técnicas pueden dar como resultado que el programa no avance, incluso, el programa se puede quedar atrapado haciendo trabajo inútil: crear situaciones de bloqueo y abortar procesos continuamente. http://trevinca.ei.uvigo.es/~formella/doc/cd04/node69.html Detección y Recuperación de Deadlocks Algoritmos de Detección de Deadlock 1. Cuando hay una única ocurrencia de cada recurso. (variante del grafo de "wait for graph"). Consiste en reducir el grafo, retirando las aristas que van de recursos a procesos y de procesos a recursos, colocando nuevas aristas que reflejan la situación de espera entre procesos. Si el grafo reducido tiene ciclos el sistema esta en Deadlock. Orden de operaciones = n^2 , n = cantidad de aristas. 2. Cuando hay múltiples ocurrencias de cada recurso Procedure detecta_deadlock var Disponible:array[1..n] of integer //# de recursos Usados:array[1..n] of integer Solicitados:array[1..n] of integer Finalizado:array[1..n] of boolean Begin Work:=Disponibles; For i:=1..n do if(usados[i]≠0) then finish[i]:=false Else finish[i]:=true; While(encontrar_indice_i = true) do { Work:=work + usados[i]; Finish[i]:=true; } If ((finish[i] = false) para algun i), 1≤i≤n then El sistema esta en Deadlock. End Function encontrar_indice_i : Boolean Begin If (existe i tal que (Finish[i]=false && solicitados[i] ≤ work) Then -> true Else -> false End Detección de deadlock La evitacíon de deadlock tiene un costo porque todos los estados inseguros no son estados de deadlock. Esto implica que hay tiempos cuando algunos procesos tienen que esperar y recursos están desocupados sin que es necesario. El sistema operativo puede chequear de vez en cuando si hay un deadlock. ¿Cuán frecuentemente debieramos chequear si hay deadlock? o El costo de algoritmo vs. el número de procesos en deadlock. o Saber quien creó el deadlock. o ¶ Cuando la utilización de la CPU es baja. Tenemos que eliminar los deadlocks que encontramos. Posibilidades: o Abortar todos los procesos en deadlock. ¡Esto es un método común! o Abortar procesos uno a la vez hasta que no haya deadlock. o Retroceder los procesos a algún punto y reiniciar. El deadlock puede reocurrir. o Expropiar recursos de procesos hasta que no haya deadlock. Retrocedemos los procesos expropiados. Tenemos que seleccionar un proceso para abortar o retroceder. Factores: o La prioridad o El tiempo que el proceso ha corrido o El número y tipo de los recursos adquiridos o La clase de proceso (batch o interactiva) La starvation es un problema. http://www.cs.virginia.edu/~knabe/iic2332/notes09.html Detección y Recuperación. Es el hecho de determinar si existe o no un Dead Lock, e identificar cuales son los procesos y recursos implicados en él. El uso de algoritmos de detección de interbloqueo implica una sobrecarga en el tiempo de ejecución. Para ser correcto, un algoritmo de detección de interbloqueo debe de cumplir dos criterios: 1) Debe detectar todos los dead lock´s existentes en un tiempo finito. 2) No debe reportar "falsos" Dead Lock's. Grafo de asignación de recursos. Los Dead Lock pueden describirse con mayor precisión en función de un grafo dirigido llamado grafo de asignación de recursos, que consiste en un conjunto de vértices V y aristas A. El conjunto de vértices V se divide en dos tipos, P = {P1,P2, ... , Pn}, el conjunto formado por todos los procesos del sistema, y R ={R1,R2, ... ,Rn}, el conjunto integrado por todos los tipos de recursos del sistema. Representación mediante grafos del estado del sistema. El estado de un sistema es dinámico; esto es, los procesos del sistema toman y liberan recursos continuamente. La representación del dead lock requiere la representación del estado de la interacción procesos - recursos, la representación se hace mediante un grafo dirigido que se conoce como gráfica de asignación de recursos . En los sistemas de bases de datos distribuidos (DDBS) está representación se conoce como gráfica de espera de transacción (Transaction Wait-For TWF). Los dead lock`s pueden describirse con mayor precisión en función de un grafo dirigido llamado grafo de asignación de recursos. La simbologia es la siguiente de acuerdo a las figura # 26. a, b, c y d. Figura # 26. Gráfica de asignación y petición de recursos La técnica para la reducción de gráficas implica las consideraciones siguientes: * * * Si las peticiones de recursos de un proceso piden ser concedidas, entonces la gráfica puede ser reducida. La reducción de una gráfica consiste en retirar las flechas que van de los recursos a los procesos y retirar las flechas que van del proceso al recurso. Si una gráfica puede ser reducida para todos sus procesos entonces no hay dead lock. Si una gráfica no puede ser reducida para todos sus procesos, entonces los procesos * irreducibles constituyen la serie de procesos interbloqueados de la gráfica. Detección de interbloqueo mediante grafos. * Un grafo G consiste de un conjunto finito no vacío. V = C(G) de: P puntos (vértices) conjunto X de q parejas desordenadas de puntos de V(aristas). cada par X = {U,V} de puntos en X y una línea de G por lo tanto X = UV. Un grafo de p puntos y q líneas se denomina un grafo (p,q), el grafo (1,0) es trivial. Petición = Proceso - Recurso Pi Rx Ry El proceso Pi tiene el recurso Rx y solicita el recurso Ry. Para determinar si existe un ciclo en un grafo se puede usar la representación matricial del grafo dirigido. Dado que se tienen parejas ordenadas {Rx, Ry}, la matriz se construye colocando un 1 en la diagonal en (x,x) y (y,y) y un 1 en la posición (x,y) de la matriz. Ejemplo figura # 27. Figura # 27. Representación matricial del grafo. Reducción de la matriz del grafo de la figura # 27 (b). Observe figura # 28. Figura # 28. Reducción de la matriz del grafo. Reducción de la matriz de un grafo correspondiente. No existen vértices terminales; los vértices 1 y 2 son iniciales y pueden ser eliminados; existe un Inter bloqueo. Ejemplo, figura # 29. Grafo. Figura # 29. a) Representación matricial b) Reducción de la matriz del grafo. Representación vectorial que solo almacena la información que presenta el grafo, de la figura # 29. Ejemplo figura # 30. Figura # 30. Representación vectorial Un vértice terminal sólo aparece en la columna requiere y un vértice inicial sólo aparece en la columna Tiene. Para reducir esta representación se recorren de arriba a abajo los vectores y se buscan los vértices terminales e iniciales y se elimina su renglón. El proceso se repite hasta: 1) No existen renglones o 2) No se pueden eliminar renglones. Si no se pueden eliminar renglones las transiciones producen un Dead Lock. Para el grafo de la (figura # 30 (a) ) en el primer paso se eliminan los procesos P1 (vértice inicial), P2 y P3 (vértice terminal). En el segundo paso se elimina el proceso P4 (vértice terminal), inicial. Para el grafo de la (figura # 30 (b)) el primero se eliminan los procesos P1,P2,P3 (vértices iniciales), P4(vértice inicial al eliminar el proceso P1), Los procesos restantes no pueden ser eliminados, por lo tanto existe un dead lock. El resultado de la reducción es, observe figura # 31. Figura # 31. Reducción del vector del grafo. 2.10.3.3 Recuperación. Recuperación ante Deadlocks 1. Cancelación de procesos a. Cancelación de todos los procesos involucrados. Esto resuelve la situación de Deadlock pero tiene un costo muy alto de reprocesamiento. b. Cancelacion de un proceso por vez hasta resolver la situación de Deadlock. La ventaja de esto es que el costo de reprosesamiento de la información es menor pero cada vez que se cancela un proceso debe ejecutarse el algoritmo de detección de deadlock. Los criterios para elegir el candidato a ser cancelado son: por prioridad, por tiempo de uso de CPU, por cantidad de recursos utilizados y por cuantos recursos adicionales habrá de utilizar. 2. Obtención de recursos (resourse Preemption). El sistema operativo selecciona un proceso y le quita los recursos otorgados. Los criterios para seleccionar el candidato son los mismos que para la cancelación. El proceso seleccionado se le quitan los recursos y se le lleva a un estado consistente (Rollback). Recuperación de un Dead Lock. La única forma en que el sistema operativo puede recuperarse de un interbloqueo es retirando uno o más procesos y reclamar sus recursos para que otros procesos puedan terminar. Normalmente varios procesos perderán una parte o la totalidad del trabajo realizado hasta ese momento. Este puede parecer un precio pequeño comparado con dejar que el interbloqueo se complique por varios factores. * * * * En primer lugar, puede no estar claro que el sistema este bloqueado o no. Muchos sistemas tienen medios pobres para suspender un proceso por tiempo indefinido y reanudarlo más tarde. Aún cuando existan medios efectivos de suspensión /reanudación, con toda seguridad, estos implicarán una sobrecarga, considerable y pueden requerir la atención de un operador altamente calificado. No siempre se dispone de tales operadores. Recuperarse de un interbloqueo de proporciones modestas puede suponer una cantidad razonable de trabajo. Una forma de elegir los procesos que pueden ser retirados es de acuerdo a las prioridades de los procesos. Pero esto también tiene sus dificultades. * Las prioridades de los procesos bloqueados pueden no existir, así que el operador deberá tomar una decisión arbitraria. * * Las prioridades pueden ser incorrectas, o un poco confusas debido a consideraciones especiales. La decisión óptima de cuáles procesos retirar pueden requerir de un esfuerzo considerable para determinarla. El enfoque más deseable a la recuperación del Dead Lock están un mecanismo efectivo de Suspensión / reanudación. Esto permitirá detener temporalmente los procesos y después reanudarlos sin pérdida del trabajo. http://eduadis.itlapiedad.edu.mx/~hocegueras/so1/so1_316.html MECANISMOS PARA EVITARLOS. Havender llegó a la conclusión de que si no se cumple una de las cuatro condiciones necesarias para el interbloqueo es posible que éste ocurra. Para evitarlo sugirió: * * * Cada proceso deberá pedir todos los recursos requeridos de una sola vez y no podrá proceder hasta que le hayan sido asignados todos. Si un proceso que mantiene ciertos recursos se le niega una nueva petición, este proceso deberá liberar sus recursos originales y en caso necesario pedirlos de nuevo con los recursos adicionales. Se impondrá la ordenación lineal de los tipos de recursos en todos los procesos, es decir, si a un proceso le han sido asignados recursos de un tipo dado, en lo sucesivo sólo podrá pedir aquellos recursos de los tipos que siguen en el ordenamiento. Otra alternativa, para manejar los dead lock, es tener información acerca de como los recursos se van a requerir, el modelo más simple y más útil requiere que en cada proceso declare el máximo número de recursos que van a requerir con lo cual es posible construir un algoritmo que asegure que el sistema no entrara en dead lock. Un estado es seguro si el sistema puede asignar recursos a cada proceso en algún orden evitando el dead lock. Formalmente un sistema esta en estado seguro solamente si existe una secuencia segura. Una secuencia de procesos < P1, P2, ... Pn> esta en secuencia segura si para cada Pi, los recursos que Pi pueda requerir pueden ser satisfechos por los recursos disponibles más los recursos que tuvieron los Pj donde j < i. Si no se puede satisfacer Pi entonces Pi espera hasta que los Pj terminen. Cuando Pi termine Pi+1 puede obtener sus recursos y así sucesivamente. Ejemplo, figura # 32. Se tienen 12 unidades de cinta se tiene 3 procesos ¿Ese sistema esta en estado seguro o no?. Figura # 32. Requerimiento procesos - recursos. Requerimiento máximo - Necesidad actual = Necesidad más (Disponible). Se tiene 12 recursos por lo tanto 12-9 = 3, entonces la secuencia es segura. La secuencia segura es < P1,P0,P2> Haga una situación en la cual el sistema estaría es estado inseguro. Un estado seguro esta libre de dead lock y un estado de dead lock, es un estado inseguro pero no todos los estados inseguros producen dead lock. Si se esta en un estado seguro se puede pasar a un estado inseguro. http://eduadis.itlapiedad.edu.mx/~hocegueras/so1/so1_317.html Estrategias para evitarlos. Evitación del interbloqueo y el algoritmo de Dijkstra. Si las condiciones necesarias para que tenga lugar un interbloqueo están en su lugar, aún es posible evitar el interbloqueo teniendo cuidado al asignar los recursos. El algoritmo de planificación que pueda evitar los interbloqueos fue ideado por Dijkstra (1965) y se le conoce como algoritmo del banquero. En ese algoritmo se modela la forma en que un banquero puede tratar a un grupo de clientes a quienes les ha otorgado líneas de crédito. en la (figura # 36 (a)) se observan cuatro clientes, a cada uno de los cuales se le ha otorgado cierto número de unidades de crédito. El banquero sabe que los clientes no necesitan su límite de crédito máximo de inmediato, de manera que sólo ha reservado 10 unidades en lugar de 22 para darles servicio. Los clientes emprenden sus respectivos negocios, haciendo solicitudes de préstamo de cuando en cuando. En cierto momento, la situación es como la que se muestra en la (figura # 33). A una lista de clientes que muestra el dinero que ya se presentó y el máximo del crédito disponible se le llama estado del sistema. Figura # 33. Tres estados de asignación de recursos (a) Seguro. (b) Seguro. (c) Inseguro. Un estado es seguro si existe una secuencia de estados que lleva a todos los clientes que obtienen préstamos hasta sus límites de crédito. El estado de la (figura #33 (b) ) es seguro por que con las dos restantes, el banquero puede demorar cualquier solicitud salvo la de Carlos, con lo que permite que termine y devuelva sus cuatro recursos. Con cuatro unidades, el banquero puede permitir que David o Bárbara tengan las unidades que necesitan para terminar y así sucesivamente. Si estando en el estado de la ( figura #33 (b) ) se le otorga una unidad más a Bárbara, (Figura #33 (c) ), el banquero no podrá completar ninguna de la línea de crédito de su clientes. Un estado inseguro no tiene que conducir a un interbloqueo, ya que un cliente podría no necesitar su línea de crédito disponible, pero el banquero no puede confiar en ese comportamiento. Haciendo una analogía con un Sistema Operativo tenemos: El estado actual del sistema se denomina seguro, Si el Sistema Operativo puede permitir a los usuarios actuales completar sus trabajos en un intervalo de tiempo finito. De lo contrario se le denomina inseguro. En otras palabras: Un estado seguro es aquel en el cual la asignación de recursos es tal que los usuarios pueden llegar a terminar. Un estado seguro es aquel que puede llegar a terminar. Un estado inseguro es aquel que puede llegar a un dead lock, (nunca termina). La asignación de recursos por el algoritmo del banquero es la siguiente: * * * Se permite todas las condiciones de exclusión mutua, espera por y no apropiatividad. Se permite a los procesos mantener sus recursos mientras esperan por otros. El sistema sólo concede peticiones que den como resultado estados seguros. * El algoritmo del banquero para n recursos (de Dijkstra). Sea n un número de proceso y m un número de recurso y sea disponible un vector de longitud m que indica el número de recursos disponibles y sea máxima una matriz de ( n x m) que define la máxima demanda de cada proceso así por ejemplo si tuviéramos máxima ( i,j ) = k define los recursos asignados a cada proceso, por ejemplo la asignación ( i , j ) = k quiere decir que el proceso i tiene asignado K instancias del recurso j necesidades ( n * m ), que indica los recursos que requieren los procesos. Necesidades ( i , j ) = Máxima ( i , j ) - Asignación ( i , j ). Se puede considera cada renglón de las matrices asignación y necesidades como vectores y referirnos como asignación de i y necesidades de i. Algoritmo: Sea requerimiento de i un vector de requerimientos de proceso i. Cuando un requerimiento de un recurso es hecho por el proceso i se realizaran las siguientes acciones: 1).2).3).- Si Requerimiento de i <= Necesidades de i ir al segundo paso. Sino error. Si requerimiento de i <= disponible ir al tercer paso. Si no recurso no disponible Pi debe esperar. Hacer Disponible = Disponible - Requerimiento, Asignación = Asignación + Requerimiento, Necesidades = Necesidades - Requerimiento. Si el estado es seguro se completa la transacción de lo contrario el proceso debe esperar y el estado anterior es restablecido. Algoritmo para ver si el estado es seguro. Sea trabajo (m) y final (n) vectores de longitud m y n respectivamente, hacer Trabajo = Disponible y final ( i ) = falso para i = 1,...n 1).- Encuentre una i tal que final ( i ) de i = falso y Necesidades ( i ) <= Trabajo si no 2).- existe ir al punto tres. Trabajo = Trabajo + Asignación ( i ), Final ( i ) = verdad ir al paso uno. 3).- Si final ( i) = verdad para toda i entonces el sistema esta en estado seguro de lo contrario esta en estado inseguro. http://eduadis.itlapiedad.edu.mx/~hocegueras/so1/so1_318.html 2.11 Niveles, objetivos y criterios de planificación. Uno de los módulos más importantes de un sistema operativo es la de administrar los procesos y tareas del sistema de cómputo. En esta sección se revisarán dos temas que componen o conciernen a este módulo: la planificación del procesador y los problemas de concurrencia. Planificación del procesador La planificación del procesador se refiere a la manera o técnicas que se usan para decidir cuánto tiempo de ejecución y cuando se le asignan a cada proceso del sistema. Obviamente, si el sistema es monousuario y monotarea nohay mucho que decidir, pero en el resto de los sistemas esto es crucial para el buen funcionamiento del sistema. Niveles de planificación En los sistemas de planificación generalmente se identifican tres niveles: el alto, em medio y el bajo. El nivel alto decide que trabajos (conjunto de procesos) son candidatos a convertirse en procesos compitiendo por los recursos del sistema; el nivel intermedio decide que procesos se suspenden o reanudan para lograr ciertas metas de rendimiento mientras que el planificador de bajo nivel es el que decide que proceso, de los que ya están listos (y que en algún momento paso por los otros dos planificadores) es al que le toca ahora estar ejecutándose en la unidad central de procesamiento. En este trabajo se revisaran principalmente los planificadores de bajo nivel porque son los que finalmente eligen al proceso en ejecución. Objetivos de la planificación Una estrategia de planificación debe buscar que los procesos obtengan sus turnos de ejecución apropiadamente, conjuntamente con un buen rendimiento y minimización de la sobrecarga (overhead) del planificador mismo. En general, se buscan cinco objetivos principales: Justicia o Imparcialidad: Todos los procesos son tratados de la misma forma, y en algún momento obtienen su turno de ejecución o intervalos de tiempo de ejecución hasta su terminación exitosa. Maximizar la Producción: El sistema debe de finalizar el mayor numero de procesos en por unidad de tiempo. Maximizar el Tiempo de Respuesta: Cada usuario o proceso debe observar que el sistema les responde consistentemente a sus requerimientos. Evitar el aplazamiento indefinido: Los procesos deben terminar en un plazo finito de tiempo. El sistema debe ser predecible: Ante cargas de trabajo ligeras el sistema debe responder rápido y con cargas pesadas debe ir degradándose paulatinamente. Otro punto de vista de esto es que si se ejecuta el mismo proceso en cargas similares de todo el sistema, la respuesta en todos los casos debe ser similar. Características a considerar de los procesos No todos los equipos de cómputo procesan el mismo tipo de trabajos, y un algoritmo de planificación que en un sistema funciona excelente puede dar un rendimiento pésimo en otro cuyos procesos tienen características diferentes. Estas características pueden ser: Cantidad de Entrada/Salida: Existen procesos que realizan una gran cantidad de operaciones de entrada y salida (aplicaciones de bases de datos, por ejemplo). Cantidad de Uso de CPU: Existen procesos que no realizan muchas operaciones de entrada y salida, sino que usan intensivamente la unidad central de procesamiento. Por ejemplo, operaciones con matrices. Procesos de Lote o Interactivos: Un proceso de lote es más eficiente en cuanto a la lectura de datos, ya que generalmente lo hace de archivos, mientras que un programa interactivo espera mucho tiempo (no es lo mismo el tiempo de lectura de un archivo que la velocidad en que una persona teclea datos) por las respuestas de los usuarios. Procesos en Tiempo Real: Si los procesos deben dar respuesta en tiempo real se requiere que tengan prioridad para los turnos de ejecución. Longevidad de los Procesos: Existen procesos que tipicamente requeriran varias horas para finalizar su labor, mientras que existen otros que solonecesitan algunos segundos. Planificación apropiativa o no apropiativa (preemptive or not preemptive) La planificación apropiativa es aquella en la cual, una vez que a un proceso le toca su turno de ejecución ya no puede ser suspendido, ya no se le puede arrebatar la unidad central de procesamiento. Este esquema puede ser peligroso, ya que si el proceso contiene accidental o deliberadamente ciclos infinitos, el resto de los procesos pueden quedar aplazados indefinidamente. Una planificación no apropiativa es aquella en que existe un reloj que lanza interrupciones periodicas en las cuales el planificador toma el control y se decide si el mismo proceso seguirá ejecutándose o se le da su turno a otro proceso. Este mismo reloj puede servir para lanzar procesos manejados por el reloj del sistema. Por ejemplo en los sistemas UNIX existen los 'cronjobs' y 'atjobs', los cuales se programan en base a la hora, minuto, día del mes, día de la semana y día del año. En una planificación no apropiativa, un trabajo muy grande aplaza mucho a uno pequeño, y si entra un proceso de alta prioridad esté también debe esperar a que termine el proceso actual en ejecución. Planificación de procesos La planificación es el proceso por el cual el sistema operativo selecciona que proceso ejecutar. La selección del proceso se basa en alguno de los algoritmos de planificación que se describen más abajo. Expulsión Es la característica por el cual el sistema operativo puede o no expulsar del estado de ejecución a un proceso dado. En este sentido entonces tenemos la planificación apropiativa en la cual el sistema operativo puede cortar en cualquier momento la ejecución de un proceso y la planificación no apropiativa en la cual una vez que el proceso esta en ejecución el sistema operativo no puede sacarlo de ese estado. Objetivos de la planificación Los objetivos de la planificación de proceso son: Equidad, todos los procesos deben poder ejecutarse Eficacia, mantener ocupada la CPU un 100% del tiempo Tiempo de respuesta, minimizar el tiempo de respuesta al usuario Tiempo de regreso, minimizar el tiempo que deben esperar los usuarios por lotes para obtener sus resultados Rendimiento, maximizar el número de tareas procesadas por hora. Algoritmos de planificación Los algoritmos de planificación son los que definen que política se va a seguir para que un proceso pase al estado de ejecución. Planificación Round-Robin En este tipo de planificación cada proceso tiene asignado un quantum de tiempo para ejecutarse y en el caso de que no pueda terminar la ejecución en su quantum el proceso pasa de nuevo a la cola de procesos para ser ejecutado por otro quantum luego de recorrer la cola para asegurarse que todos los procesos reciban ese quantum de procesamiento. Planificación por prioridad En la planificación round-robin todos los procesos son tratados con la misma prioridad. Para el caso de este tipo de planificación a cada proceso se le asigna una prioridad y los mismos son ejecutados Colas múltiples Las colas múltiples están basadas en una pila que sirve como índice de una lista de procesos que se tienen que ejecutar. Primero el trabajo más corto Este tipo de algoritmo de planificación se usa para trabajos en batch o de procesamiento or lotes en los cuales se puede saber cual es el tiempo de duración de la ejecución de cada proceso y entonces se puede seleccionar primero el trabajo más corto. El problema que se presenta con éste algoritmo es que los grandes procesos podrían sufrir de inanición dado que cualquier proceso pequeño se "cuela" sobre uno de mayor tamaño y como resultado final se podría dar el caso que el proceso grande nunca obtenga procesamiento. Planificación garantizada En este modelo de planificación se tiene en cuenta la cantidad de usuarios en el sistema y se le asigna a cada uno el tiempo de ejecución de 1/n (siendo n la cantidad total de usuarios) de esa forma el planificador tiene que llevar cuenta del tiempo de ejecución de los procesos y balancear el tiempo que están utilizando el procesador para cumplir con la ecuación previa. Conceptos de planificación. El objetivo de la multiprogramación es que en todo momento se ejecute un proceso para maximizar la utilización del CPU. En un sistema monoprocesador nunca habrá más de un proceso en ejecución. Si hay más procesos tendrán que esperar a que el CPU esté libre y pueda volver a planificarse. El concepto de multiprogramación es muy sencillo: un proceso se ejecuta hasta que tenga que esperar, generalmente a que termine una solicitud de E/S. En un sistema de computo sencillo, el CPU permanecerá inactivo; todo este tiempo de espera se desperdicia sin efectuar una actividad útil. Con la multiprogramación tratamos de emplear productivamente este tiempo. Varios procesos se conservan en la memoria a la vez, y cuando uno de ellos tiene que esperar, el sistema operativo le quita el CPU al proceso y se lo da a otro; este modelo continúa, Cada vez que un proceso tiene que esperar, otro pueda utilizar el CPU. Los beneficios de la multiprogramación son un aumento de la utilización del CPU y una mayor productividad. http://eduadis.itlapiedad.edu.mx/~hocegueras/so1/so1_415.html Planificación del CPU La planificación es una función fundamental del sistema operativo. Casi todos los recursos de una computadora se planifican antes de usarse. Por supuesto, el CPU es una de los principales Recursos de la computadora, de modo que su planificación es parte modular del diseño de los sistemas operativos. - Ciclo de ráfaga del CPU y de E/S. El éxito de la planificación del CPU depende de la siguiente prioridad observada de los procesos: la ejecución de un proceso consiste en un ciclo de ejecucióndel CPU y de E/S, y los procesos se alternan entre estos dos estados. La ejecución del proceso se inicia con una rafaga de CPU; a ésta le siguen una ráfaga de E/S, otra ráfaga de CPU, una más de E/S, etc. Finalmente, la última ráfaga de CPU terminará con una solicitud al sistema para que concluya la ejecución, en vez de otra ráfaga de E/S. Las duraciones de estas ráfagas de CPU se han medido, y, aunque varían considerablemente de un proceso a otro y entre computadoras, tienden a presentar una curva de frecuencias similar a la que se muestra en la figura # 41. Generalmente la curva se caracteriza como exponencial o hiperhexponencial. Hay un gran número de ráfagas de CPU de corta duración y un pequeño número de larga duración. Figura # 41. Histograma de tiempos de ráfaga del CPU. - Planificador del CPU. Siempre que el CPU queda inactivo, el sistema operativo debe seleccionar para su ejecución uno de sus procesos de la cola de procesos listos. El proceso de selección es revisado por el planificador a corto plazo. (o planificador del CPU). El planificador selecciona uno de los procesos en memoria que están listos para ejecución y le asigna el CPU. - Estructura de planificación. Las decisiones de planificación del CPU pueden efectuarse en una de las cuatro circunstancias siguientes: 1. Cuando un proceso cambia del estado de ejecución a estado de espera (por ejemplo, solicitud de E/S petición de esperar la terminación de uno de los procesos hijo). 2. 3. 4. Cuando un proceso cambia del estado de ejecución al estado listo (por ejemplo, cuando ocurre una interrupción) Cuando un proceso cambia del estado de espera al estado listo (por ejemplo, al completarse la E/S). Cuando termina un proceso. http://eduadis.itlapiedad.edu.mx/~hocegueras/so1/so1_416.html 2.12 Técnicas de administración del planificador. Algoritmos de planificación. Planificación a plazo fijo. En la planificación a plazo fijo, ciertos trabajos se planifican para ser terminados en un periodo específico. Estos trabajos tienen un alto valor si se entregan a tiempo y pueden carecer de valor si se entregan después del límite. La planificación a plazo fijo es compleja por muchas razones: * Los usuarios deben proporcionar por adelantado y en forma precisa las necesidades de recursos de su trabajo. Tal información rara vez está disponible. * El sistema debe ejecutar el programa de plazo fijo sin una severa degradación de servicio para los otros usuarios. * El sistema debe planificar cuidadosamente las necesidades de recursos permitiendo un libre tránsito del plazo fijo. Esto puede ser difícil debido a la llegada de programas nuevos con demandas impredecibles. * Si se activan muchos trabajos de plazo fijo, la planificación puede llegar a ser tan compleja que necesite métodos de optimización sofisticados para asegurar que el plazo fijo se cumpla. * El manejo intenso de recursos requeridos por la planificación de plazo fijo puede generar una sobrecarga sustancial. http://eduadis.itlapiedad.edu.mx/~hocegueras/so1/so1_417.html 2.12.1 FIFO Planificación Primero en llegar - Primero en Salir (FIFO). Es la disciplina más simple, figura # 42. Los procedimientos son despachados de acuerdo al orden de llegada a la cola de listos. Una vez que un proceso tiene el CPU, se ejecuta hasta su terminación. Esta planificación es No apropiativa; es justa en el sentido formal, pero algo injusta porque los grandes procesos hacen esperar a trabajos pequeños y, los trabajos sin importancia hacen esperar a los trabajos importantes. Figura # 42. Planificación primero en llegar primero en salir. La Planificación FIFO ofrece una varianza en tiempo de respuesta relativamente pequeña y es, por tanto, más predecible que otros esquemas; no es un esquema útil en la planificación de procesos interactivos porque no garantiza buenos tiempos de respuesta. FIFO (Firs In First Out).- Asocia a cada página el tiempo en que fue cargada en memoria. Cuando debe reemplazar una página, se selecciona la que hace mas tiempo que esta en memoria. También se puede implementar mediante la utilización de una lista. Se reemplazan las páginas de la cabeza y se agregan al final. Planificación del Primero en Entrar Primero en Salir (FIFO) Es muy simple, los procesos se despachan de acuerdo con su tiempo de llegada a la cola de listos. Una vez que el proceso obtiene la cpu, se ejecuta hasta terminar, ya que es una disciplina “no apropiativa”. Puede ocasionar que procesos largos hagan esperar a procesos cortos y que procesos no importantes hagan esperar a procesos importantes. Es más predecible que otros esquemas. No puede garantizar buenos tiempos de respuesta interactivos. Suele utilizarse integrado a otros esquemas, por ejemplo, de la siguiente manera: Los procesos se despachan con algún esquema de prioridad. Los procesos con igual prioridad se despachan “FIFO”. SCHED_FIFO: Planificación FIFO (1º en entrar, 1º en salir). SCHED_FIFO sólo puede emplearse con prioridades estáticas mayores que 0, lo que significa que cuando un proceso SCHED_FIFO se convierte en ejecutable, siempre prevalecerá inmediatamente sobre cualquier otro proceso normal SCHED_OTHER ejecutándose. SCHED_FIFO es un simple algoritmo de planificación sin rodajas de tiempo. Para procesos planificados bajo la política SCHED_FIFO, se aplican las siguientes reglas: Un proceso SCHED_FIFO que ha sido apropiado por otro proceso de mayor prioridad permanecerá en la cabeza de la lista para su prioridad y reanudará su ejecución tan pronto como todos los procesos de prioridad más alta se bloqueen de nuevo. Cuando un proceso SCHED_FIFO llegue a ser ejecutable, se insertará al final de la lista para su prioridad. Una llamada a sched_setscheduler o a sched_setparam pondrá el proceso SCHED_FIFO identificado por pid al final de la lista si era ejecutable. Un proceso que llame a sched_yield será colocado al final de la lista. Ningún otro suceso moverá un proceso planificado bajo la política SCHED_FIFO en la lista de espera de procesos ejecutables con igual prioridad estática. Un proceso SCHED_FIFO se ejecuta hasta que es bloqueado por una petición de E/S, hasta que sea apropiado por un proceso de más alta prioridad, o hasta que llame a sched_yield. http://www.hispafuentes.com/hf-doc/man/man2/sched_setscheduler.2.html 2.12.2 SJF Planificación del trabajo más corto (SJF). La disciplina del trabajo más corto primero es NO apropiativa y en ella el trabajo o proceso con tiempo estimado de ejecución hasta terminación más corto, es el siguiente en ser ejecutado. El SJF reduce el tiempo de espera de los procesos, sin embargo, tiene una varianza mayor (es decir, es menos predecible) que en FIFO, sobre todo para los trabajos largos. SJF favorece a los procesos cortos a costa de los procesos largos. Además, selecciona los trabajos que serán atendidos y que dejarán el sistema lo antes posible. Esto último traduce en listas de espera cortas. El SJF es NO apropiativo por lo que resulta de poca utilidad en ambientes de tiempo compartido. http://eduadis.itlapiedad.edu.mx/~hocegueras/so1/so1_417.html Planificación del Trabajo Más Corto Primero (SJF) Es una disciplina no apropiativa y por lo tanto no recomendable en ambientes de tiempo compartido. El proceso en espera con el menor tiempo estimado de ejecución hasta su terminación es el siguiente en ejecutarse. Los tiempos promedio de espera son menores que con “FIFO”. Los tiempos de espera son menos predecibles que en “FIFO”. Favorece a los procesos cortos en detrimento de los largos. Tiende a reducir el número de procesos en espera y el número de procesos que esperan detrás de procesos largos. Requiere un conocimiento preciso del tiempo de ejecución de un proceso, lo que generalmente se desconoce. Se pueden estimar los tiempos en base a series de valores anteriores. Planificación del Tiempo Restante Más Corto (SRT) Es la contraparte apropiativa del SJF. Es útil en sistemas de tiempo compartido. El proceso con el tiempo estimado de ejecución menor para …nalizar es el siguiente en ser ejecutado. Un proceso en ejecución puede ser apropiado por un nuevo proceso con un tiempo estimado de ejecución menor. Tiene mayor sobrecarga que la planificación SJF. Debe mantener un registro del tiempo de servicio transcurrido del proceso en ejecución, lo que aumenta la sobrecarga. Los trabajos largos tienen un promedio y una varianza de los tiempos de espera aún mayor que en SJF. La apropiación de un proceso a punto de terminar por otro de menor duración recién llegado podría significar un mayor tiempo de cambio de contexto (administración del procesador) que el tiempo de finalización del primero. Al diseñarse los Sistemas Operativos se debe considerar cuidadosamente la sobrecarga de los mecanismos de administración de recursos comparándola con los beneficios esperados. Planificación el Siguiente con Relación de Respuesta Máxima (HRN) Corrige algunas de las debilidades del SJF, tales como el exceso de perjuicio hacia los procesos (trabajos) largos y el exceso de favoritismo hacia los nuevos trabajos cortos. Es una disciplina no apropiativa. La prioridad de cada proceso está en función no sólo del tiempo de servicio del trabajo, sino que también influye la cantidad de tiempo que el trabajo ha estado esperando ser servido. Cuando un proceso ha obtenido la cpu, corre hasta terminar. Las prioridades, que son dinámicas, se calculan según la siguiente fórmula, donde pr es la “prioridad”, te es el “tiempo de espera” y ts es el “tiempo de servicio”: Planificación del tiempo restante más corto primero (SRT). La SRT es apropiativa, en ella el proceso con el tiempo estimado de ejecución menor para llegar a su terminación es el siguiente en ser ejecutado, incluyendo las nuevas llegadas. En la disciplina SJF, una vez que el trabajo comienza su ejecución sigue hasta que termina. En SRT, un proceso en ejecución puede ser apropiado por un nuevo proceso con n tiempo estimado de ejecución menor. La SRT tiene una sobrecarga mayor que la SJF. Debe mantener un registro del tiempo de servicio transcurrido del trabajo en ejecución y debe controlar las apropiaciones ocasionales. Planificación el siguiente con relación de respuesta máxima (HRT). Brinch Hansen (1971) desarrolló la estrategia el siguiente con relación de respuesta máxima (HRT), que corrige algunas de las debilidades de SJF, en especial el favoritismo por los tamaños pequeños. La HRT es una disciplina de planificación NO apropiativa en la cual la prioridad de cada trabajo está en función, no sólo del tiempo de servicio del trabajo, sino del tiempo que un proceso ha estado esperando a ser servido, Una vez que un trabajo obtiene el CPU, se ejecuta hasta su terminación. Las prioridades dinámicas en HRT se calculan según la fórmula Tiempo de espera + Tiempo de servicio Prioridad = Tiempo de servicio http://eduadis.itlapiedad.edu.mx/~hocegueras/so1/so1_417.html 2.12.3 RR Planificación Round Robin (RR). En esta planificación, figura # 43. Los procesos son despachados en FIFO, pero, se les otorga una cantidad limitada de tiempo de CPU llamada división de tiempo (time - slice) o cuanto (quantum). Si un proceso no termina antes de que se termine su tiempo de CPU, el CPU es apropiado y asignado al siguiente proceso en espera. El proceso apropiado se coloca al final de la lista de listos. Figura # 43. Planeación round robin. El esquema Round robin es efectivo en un ambiente de tiempo compartido en el cual el sistema necesita garantizar un tiempo de respuesta razonable para los usuarios interactivos. La sobre carga de la apropiación se mantiene baja mediante eficientes mecanismos de cambio de contexto y proporcionado suficiente memoria para que los procesos residan en ella al mismo tiempo. Existe una variante de este esquema llamada selfish round robin (SRR). En este esquema los procesos que entran al sistema se colocan primero en una lista de espera hasta que su prioridad alcanza el nivel de proceso para la lista de activos. Mientras un proceso está en la lista de espera, su prioridad aumenta en una relación a; cuando un proceso entra a la lista de activos su prioridad se incrementa en una relación b. Tamaño del cuanto. La determinación del tamaño del cuanto es decisiva para la operación efectiva de un sistema computacional. ¿Debe ser pequeño o grande el cuanto? ¿Debe ser fijo o variable? ¿Debe ser el mismo para todos los usuarios, o debe ser diferente para cada grupo de usuarios?. Cuando se tiene un cuanto grande cada proceso pude recibir todo el tiempo que necesita para su terminación, de manera que el esquema round robin se convierte en un FIFO. Cuando el cuanto es pequeño, la sobrecarga por el intercambio de contexto se convierte en un factor dominante y el rendimiento del sistema se degrada. ¿Cuál es el cuanto óptimo ? Es claro que cambia de un sistema a otro y que varia de acuerdo a la carga del sistema. http://eduadis.itlapiedad.edu.mx/~hocegueras/so1/so1_417.html SCHED_RR: Planificación circular (Round Robin). SCHED_RR es una mejora simple de SCHED_FIFO. Todo lo descrito arriba para SCHED_FIFO se aplica también a SCHED_RR, excepto que a cada proceso sólo se le permite ejecutarse durante un cuanto de tiempo máximo. Si un proceso SCHED_RR ha estado ejecutándose durante un periodo de tiempo igual o mayor que el cuanto de tiempo, será puesto al final de la lista para su prioridad. Un proceso SCHED_RR que ha sido apropiado por un proceso de más alta prioridad y subsecuentemente reanuda su ejecución como un proceso en ejecución, completará la porción no expirada de su cuanto de tiempo de asignación en rueda. La cantidad del cuanto de tiempo puede ser obtenida con sched_rr_get_interval. http://www.hispafuentes.com/hf-doc/man/man2/sched_setscheduler.2.html Planificación de Asignación en Rueda (RR: Round Robin) Los procesos se despachan en “FIFO” y disponen de una cantidad limitada de tiempo de cpu, llamada “división de tiempo” o “cuanto”. Si un proceso no termina antes de expirar su tiempo de cpu ocurren las siguientes acciones: 1. La cpu es apropiada. 2. La cpu es otorgada al siguiente proceso en espera. 3. El proceso apropiado es situado al final de la lista de listos. Es efectiva en ambientes de tiempo compartido. La sobrecarga de la apropiación se mantiene baja mediante mecanismos eficientes de intercambio de contexto y con suficiente memoria principal para los procesos. Tamaño del Cuanto o Quantum La determinación del tamaño del cuanto es decisiva para la operación efectiva de un sistema computacional [7, Deitel]. Los interrogantes son: ¿cuanto pequeño o grande?, ¿cuanto fijo o variable? y ¿cuanto igual para todos los procesos de usuarios o determinado por separado para cada uno de ellos?. Si el cuanto se hace muy grande, cada proceso recibe todo el tiempo necesario para llegar a su terminación, por lo cual la asignación en rueda (“RR”) degenera en “FIFO”. Si el cuanto se hace muy pequeño, la sobrecarga del intercambio de contexto se convierte en un factor dominante y el rendimiento del sistema se degrada, puesto que la mayor parte del tiempo de cpu se invierte en el intercambio del procesador (cambio de contexto) y los procesos de usuario disponen de muy poco tiempo de cpu. El cuanto debe ser lo suficientemente grande como para permitir que la gran mayoría de las peticiones interactivas requieran de menos tiempo que la duración del cuanto, es decir que el tiempo transcurrido desde el otorgamiento de la cpu a un proceso hasta que genera una petición de Entrada / Salida debe ser menor que el cuanto establecido, de esta forma, ocurrida la petición la cpu pasa a otro proceso y como el cuanto es mayor que el tiempo transcurrido hasta la petición de Entrada / Salida, los procesos trabajan al máximo de velocidad, se minimiza la sobrecarga de apropiación y se maximiza la utilización de la Entrada / Salida. El cuanto óptimo varía de un sistema a otro y con la carga, siendo un valor de referencia 100 mseg (cien milisegundos). 2.12.4 Queves multi-level. Planificación de Dos Niveles Los esquemas analizados hasta ahora suponen que todos los procesos ejecutables están en la memoria principal. Si la memoria principal es insuficiente, ocurrirá lo siguiente [23, Tanenbaum]: Habrá procesos ejecutables que se mantengan en disco. Habrá importantes implicaciones para la planificación, tales como las siguientes: o o El tiempo de alternancia entre procesos para traer y procesar un proceso del disco es considerablemente mayor que el tiempo para un proceso que ya está en la memoria principal. Es más eficiente el intercambio de los procesos con un planificador de dos niveles. El esquema operativo de un planificador de dos niveles es como sigue: 1. Se carga en la memoria principal cierto subconjunto de los procesos ejecutables. 2. El planificador se restringe a ellos durante cierto tiempo. 3. Periódicamente se llama a un planificador de nivel superior para efectuar las siguientes tareas: 1. Eliminar de la memoria los procesos que hayan permanecido en ella el tiempo suficiente. 2. Cargar a memoria los procesos que hayan estado en disco demasiado tiempo. 4. El planificador de nivel inferior se restringe de nuevo a los procesos ejecutables que se encuentren en la memoria. 5. El planificador de nivel superior se encarga de desplazar los procesos de memoria a disco y viceversa. Los criterios que podría utilizar el planificador de nivel superior para tomar sus decisiones son los que se indican a continuación: ¿Cuánto tiempo ha transcurrido desde el último intercambio del proceso?. ¿Cuánto tiempo de cpu ha utilizado recientemente el proceso?. ¿Qué tan grande es el proceso? (generalmente los procesos pequeños no causan tantos problemas en este sentido). ¿Qué tan alta es la prioridad del proceso?. El planificador de nivel superior podría utilizar cualquiera de los métodos de planificación analizados. 2.12.5 Multi-level feedback queves. Colas de Retroalimentación de Niveles Múltiples Proporcionan una estructura para lograr los siguientes objetivos: Favorecer trabajos cortos. Favorecer trabajos limitados por la Entrada / Salida para optimizar el uso de los dispositivos de Entrada / Salida. Determinar la naturaleza de un trabajo lo más rápido posible y planificar el trabajo (proceso) en consecuencia. Un nuevo proceso entra en la red de línea de espera al final de la cola superior. Se mueve por esta cola “FIFO” hasta obtener la cpu. Si el trabajo termina o abandona la cpu para esperar por la terminación de una operación de Entrada / Salida o la terminación de algún otro suceso, el trabajo abandona la red de línea de espera. Si su cuanto expira antes de abandonar la cpu voluntariamente, el proceso se coloca en la parte trasera de la cola del siguiente nivel inferior. El trabajo recibe servicio al llegar a la cabeza de esta cola si la primera está vacía. Mientras el proceso continúe consumiendo totalmente su cuanto en cada nivel, continuará moviéndose hacia el final de las colas inferiores. Generalmente hay una cola en la parte más profunda a través de la cual el proceso circula en asignación de rueda hasta que termina. Existen esquemas en los que el cuanto otorgado al proceso aumenta a medida que el proceso se mueve hacia las colas de los niveles inferiores, en tal caso, cuanto más tiempo haya estado el proceso en la red de línea de espera, mayor será su cuanto cada vez que obtiene la cpu y no podrá obtener la cpu muy a menudo debido a la mayor prioridad de los procesos de las colas superiores. Un proceso situado en una cola dada no podrá ser ejecutado hasta que las colas de los niveles superiores estén vacías. Un proceso en ejecución es apropiado por un proceso que llegue a una cola superior. Es un mecanismo adaptable, es decir que se adapta a cargas variables. A los efectos de una revisión gráfica de lo enunciado precedentemente, ver la figura 2.5 [7, Deitel]. http://exa.unne.edu.ar/depar/areas/informatica/SistemasOperativos/SO2.htm#PP Unidad 3 Administración de memoria. 3.5 Política y filosofía. POLITICAS Y FILOSOFIA DE LA ADMINISTRACION DE LA MEMORIA. La memoria principal es el lugar donde el CPU lee las instrucciones a ejecutar, asi como algunos datos a emplear. Una de las funciones basicas que debe implementar un SO es la Administracion de la Memoria para tener un control sobre los lugares donde estan almacenados los procesos y datos que actualmente se estan utilizando. EL retiro del administrador de la memoria del kernel es un ejemplo de la separación de política y mecanismo. Las decisiones acercá de que proceso se colocará en que sitio de la memoria (política) son tomadas por el administrador de la mempria. La colocación real de mapa de memoria para los procesos (mecanismo) es realizado por la tarea contenida en kernel. Esta división facilita en forma relativa el cambio de la política de administración de la memoria (algoritmos,ect) sin tener que modificar los estratos inferiores del sistema operativo. 1.6 Implantación de mecanismo de memeoria virtual. BASE LIMITE. Una solución alternativa a los problemas de recolección y protección consiste en equipar la máquina con dos registros especiales de hardware, llamados registro de base y de límite. Cuando se programa un proceso, el registro de base se craga con la dirección del inicio de su partición y el registro de límite se encarga con la longitud de la partición. Toda dirección de la memoria generada automaticamente tiene el contenido de registro de base sumado a él antes de enviarselo a la memoria. Las direcciones tambien se verifican contra el registro de limite para asegurar que no intentan direccionar la memoria fuera de la partición corriente. El hardware protege los registro de base y de límite para evitar que los programas de los usuaris los modifiquen. Una ventaja adicional de utilizar un registro de base para la recolocación es que un programa se pueda desplazar a la memoria despues de que haya iniciado la ejecución. Después de que sa ha movido, todo lo que se necesita hacer para dejarlo listo para la ejecución es cambiar el valor del registro de base. 3.6 Memoria real. Memoria real La memoria real o principal es en donde son ejecutados los programas y procesos de una computadora y es el espacio real que existe en memoria para que se ejecuten los procesos. Por lo general esta memoria es de mayor costo que la memoria secundaria, pero el acceso a la información contenida en ella es de más rápido acceso. Solo la memoria cache es más rápida que la principal, pero su costo es a su vez mayor. http://www.monografias.com/trabajos13/gesme/gesme.shtml 3.6.1 Administración de almacenamiento. Asignación del espacio de almacenamiento El subsistema de archivos se debe encargar de localizar espacio libre en los medios de almacenamiento para guardar archivos y para después borrarlos, renombrarlos o agrandarlos. Para ello se vale de localidades especiales que contienen la lista de archivos creados y por cada archivo una serie de direcciones que contienen los datos de los mismos. Esas localidades especiales se llaman directorios. Organización y Administración del Almacenamiento Organización del Almacenamiento Históricamente el almacenamiento principal se ha considerado como un recurso costoso, por lo cual su utilización debía optimizarse [7, Deitel]. Por organización del almacenamiento se entiende la manera de considerar este almacenamiento: ¿ se coloca un solo programa de usuario o varios ?. Si se encuentran varios programas de usuario: o ¿ se concede a cada uno la misma cantidad de espacio o se divide el almacenamiento en porciones o “particiones” de diferente tamaño ?. o o o ¿ se utilizará un esquema rígido de número y tamaño de particiones o un esquema dinámico y adaptable ?. ¿ se requerirá que los trabajos de los usuarios sean diseñados para funcionar en una partición específica o se permitirá que se ejecuten en cualquiera donde quepan ?. ¿ se requerirá o no que cada trabajo sea colocado en un bloque contiguo de memoria ?. Administración del Almacenamiento Independientemente del esquema de organización hay que decidir las estrategias que se utilizarán para optimizar el rendimiento. Las “estrategias de administración” deben considerar: ¿ cuándo se consigue un nuevo programa para colocar en la memoria ?: o ¿ cuando el sistema lo pide específicamente o se intenta anticiparse a las peticiones ?. ¿ dónde se colocará el programa que se ejecutará a continuación ?: o ¿ se prioriza el tiempo de carga o la optimización en el uso del almacenamiento ?. ¿ con qué criterio se desplazarán programas ?. http://exa.unne.edu.ar/depar/areas/informatica/SistemasOperativos/SO3.htm#OAA 3.6.2 Jerarquía. Jerarquía de Almacenamiento Los programas y datos tienen que estar en la memoria principal para poder ejecutarse o ser referenciados [7, Deitel]. Los programas y datos que no son necesarios de inmediato pueden mantenerse en el almacenamiento secundario. El almacenamiento principal es más costoso y menor que el secundario pero de acceso más rápido. Los sistemas con varios niveles de almacenamiento requieren destinar recursos para administrar el movimiento de programas y datos entre niveles (ver Figura 3.1 [7, Deitel]). Un nivel adicional es el “caché” o memoria de alta velocidad, que posee las siguientes características: Es más rápida y costosa que la memoria principal. Impone al sistema un nivel más de traspaso: o Los programas son traspasados de la memoria principal al caché antes de su ejecución. Los programas en la memoria caché ejecutan mucho más rápido que en la memoria principal. Al utilizar memoria caché se espera que: o La sobrecarga que supone el traspaso de programas de un nivel de memoria a otro sea mucho menor que la mejora en el rendimiento obtenida por la posibilidad de una ejecución mucho más rápida en la caché. 3.6.3 Estrategia de administración de memoria. Estrategias de Administración del Almacenamiento Están dirigidas a la obtención del mejor uso posible del recurso del almacenamiento principal [7, Deitel]. Se dividen en las siguientes categorías: Estrategias de búsqueda: o Estrategias de búsqueda por demanda. o Estrategias de búsqueda anticipada. Estrategias de colocación. Estrategias de reposición. Las “estrategias de búsqueda” están relacionadas con el hecho de cuándo obtener el siguiente fragmento de programa o de datos para su inserción en la memoria principal. En la “búsqueda por demanda” el siguiente fragmento de programa o de datos se carga al almacenamiento principal cuando algún programa en ejecución lo referencia. Se considera que la “búsqueda anticipada” puede producir un mejor rendimiento del sistema. Las “estrategias de colocación” están relacionadas con la determinación del lugar de la memoria donde se colocará (cargará) un programa nuevo. Las “estrategias de reposición” están relacionadas con la determinación de qué fragmento de programa o de datos desplazar para dar lugar a los programas nuevos. Intercambio El objetivo del intercambio es dar cabida a la ejecución de mas aplicaciones de las que pueden residir simultáneamente en la memoria del sistema: Consiste en trasladar el código y los datos de un proceso completo de memoria al sistema de almacenamiento secundario , para cargar otro previamente almacenado, no permite a un proceso utilizar mas memoria RAM de la que realmente existe en el sistema. Esta técnica puede ser ineficiente ya que se tiene que hacer el intercambio completo del proceso, aunque éste solo vaya a ejecutar una pequeña porción del código. Durante el intercambio un proceso puede ser sacado temporalmente de memoria y llevado a un lugar especial del disco y posteriormente vuelto a memoria y continuada su ejecución.. El lugar de almacenamiento temporal suele ser un espacio suficientemente grande como para acomodar copias de las imágenes de meoria de todos los usuarios. Asignacion Contigua La memoria principal normalmente se divide en dos particiones: Sistema operativo residente, normalmente en la parte baja de memoria con los vectores de interrupción. Procesos de usuario en la parte alta. Asignación de partición simple: Puede utilizarse un esquema de registro de relocalización y limite para proteger un proceso de usuario de otro y de cambios del código y datos del sistema operativo . El registro de relocalización contiene la dirección contiene la dirección física mas pequeña; el registro limite contiene el rango de las direcciones lógicas cada dirección lógica debe ser menor al registro limite Asignación de particiones múltiples: Bloques de distintos tamaños están distribuidos en memoria , cuando llega un proceso se le asigna un hueco suficientemente grande para acomodarle. El sistema operativo debe tener información sobre: a. Particiones asignadas b. Particiones libres (huecos) Asignación de partición dinámica El proceso de compactación es una instancia particular del problema de asignación de memoria dinámica, el cual es el cómo satisfacer una necesidad de tamaño n con una lista de huecos libres. Existen muchas soluciones para el problema. El conjunto de huecos es analizado para determinar cuál hueco es el más indicado para asignarse. Las estrategias más comunes para asignar algún hueco de la tabla son: Primer ajuste: Consiste en asignar el primer hueco con capacidad suficiente. La búsqueda puede iniciar ya sea al inicio o al final del conjunto de huecos o en donde terminó la última búsqueda. La búsqueda termina al encontrar un hueco lo suficientemente grande. Mejor ajuste: Busca asignar el espacio más pequeño de los espacios con capacidad suficiente. La búsqueda se debe de realizar en toda la tabla, a menos que la tabla esté ordenada por tamaño. Esta estrategia produce el menor desperdicio de memoria posible. Peor ajuste: Asigna el hueco más grande. Una vez más, se debe de buscar en toda la tabla de huecos a menos que esté organizada por tamaño. Esta estrategia produce los huecos de sobra más grandes, los cuales pudieran ser de más uso si llegan procesos de tamaño mediano que quepan en ellos. Se ha demostrado mediante simulacros que tanto el primer y el mejor ajuste son mejores que el peor ajuste en cuanto a minimizar tanto el tiempo del almacenamiento. Ni el primer o el mejor ajuste es claramente el mejor en términos de uso de espacio, pero por lo general el primer ajuste es más rápido. Problema: La fragmentación. 4. Fragmentación La fragmentación es la memoria que queda desperdiciada al usar los métodos de gestión de memoria que se vieron en los métodos anteriores. Tanto el primer ajuste, como el mejor y el peor producen fragmentación externa. La fragmentación es generada cuando durante el reemplazo de procesos quedan huecos entre dos o más procesos de manera no contigua y cada hueco no es capaz de soportar ningún proceso de la lista de espera. La fragmentación puede ser: Fragmentación Externa: existe el espacio total de memoria para satisfacer un requerimiento, pero no es contigua. Fragmentación Interna: la memoria asignada puede ser ligeramente mayor que la requerida; esta referencia es interna a la partición, pero no se utiliza. La fragmentación externa se puede reducir mediante la compactación para colocar toda la memoria libre en un solo gran bloque, pero est a solo es posible si la relocalización es dinámica y se hace en tiempo de ejecución. 5. Paginación Es una técnica de manejo de memoria, en la cual el espacio de memoria se divide en secciones físicas de igual tamaño, denominadas marcos de página. Los programas se dividen en unidades lógicas, denominadas páginas, que tienen el mismo tamaño que los marcos de páginas. De esta forma, se puede cargar una página de información en cualquier marco de página. Las páginas sirven como unidad de almacenamiento de información y de transferencia entre memoria principal y memoria auxiliar o secundaria. Cada marco se identifica por la dirección de marco, que esta en la posición física de la primera palabra en el marco de página. Las páginas de un programa necesitan estar contiguamente en memoria, aunque el programador lo observe de esta forma. Los mecanismos de paginación permiten la correspondencia correcta entre las direcciones virtuales (dadas por los programas) y las direcciones reales de la memoria que se reverencien. Cada pagina consiste en z palabras contiguas; un espacio de direcciones N de un programa consiste de n paginas (0,1,2,3…n-1) (n*z direcciones virtuales) y el espacio de memoria consiste de m marcos de paginas (0,z,2z,…,(m-1)z)(m*z posiciones). Una dirección virtual a es equivalente a una dirección dada como una dupla (p, d), en la cual p es el número de la página y d el número de la palabra dentro de la página, de acuerdo con la relación: a=p*z+d (0<=d<z) p=(a/z) (parte entera de la division) d=a mod z (resto de divisor a/z) En las maquinas que usan aritmética binaria, el calculo de (p, d) es trivial, si z es potencia de 2. Por ejemplo, si el campo de direcciones de la instrucción es de m bits (m>6), los cuatro bits mas significativos indican el numero de la pagina y los m-4 bits restantes, el desplazamiento. Para tener el control de las páginas, debe mantenerse una tabla en memoria que se denomina tabla de Mapas de Pagina (PMT) para cada uno de los procesos. Hasta ahora, los métodos que hemos visto de la administración de la memoria principal, nos han dejado con un problema: fragmentación, (huecos en la memoria que no pueden usarse debido a lo pequeño de su espacio) lo que nos provoca un desperdicio de memoria principal. Una posible solución para la fragmentación externa es permitir que espacio de direcciones lógicas lleve a cabo un proceso en direcciones no contiguas, así permitiendo al proceso ubicarse en cualquier espacio de memoria física que esté disponible, aunque esté dividida. Una forma de implementar esta solución es a través del uso de un esquema de paginación. La paginación evita el considerable problema de ajustar los pedazos de memoria de tamaños variables que han sufrido los esquemas de manejo de memoria anteriores. Dado a sus ventajas sobre los métodos previos, la paginación, en sus diversas formas, es usada en muchos sistemas operativos. Al utilizar la memoria virtual, las direcciones no pasan en forma directa al bus de memoria, sino que van a una unidad administradora de la memoria (MMU –Memory Management Unit). Estas direcciones generadas por los programas se llaman direcciones virtuales y conforman el hueco de direcciones virtuales. Este hueco se divide en unidades llamadas páginas. Las unidades correspondientes en la memoria física se llaman marcos para página o frames. Las páginas y los frames tienen siempre el mismo tamaño. Tablas de páginas Cada página tiene un número que se utiliza como índice en la tabla de páginas, lo que da por resultado el número del marco correspondiente a esa página virtual. Si el bit presente / ausente es 0, se provoca un señalamiento (trap) hacia el sistema operativo. Si el bit es 1, el número de marco que aparece en la tabla de páginas se copia en los bits de mayor orden del registro de salida, junto con el ajuste (offset) de 12 bits, el cual se copia sin modificaciones de la dirección virtual de entrada. Juntos forman una dirección física de 15 bits. El registro de salida se coloca entonces en el bus de la memoria como la dirección en la memoria física. En teoría, la asociación de las direcciones virtuales con las físicas se efectúa según lo descrito. El número de página virtual se divide en un número de página virtual (los bits superiores)y un ajuste (los bits inferiores). El número de página virtual se utiliza como un índice en la tabla de páginas para encontrar la entrada de esa página virtual. El número de marco (si existe) se determina a partir de la tabla de páginas. El número de marco se asocia al extremo superior del ajuste y reemplaza al número de página virtual para formar una dirección física que se puede enviar a la memoria. La finalidad de la tabla de páginas es asociar las páginas virtuales con los marcos. En términos matemáticos, la tabla de páginas es una función, cuyo argumento es el número de página virtual y como resultado el número del marco físico. Mediante el resultado de esta función, se puede reemplazar el campo de la página virtual de una dirección virtual por un campo de marco, lo que produce una dirección en la memoria física. Sin embargo hay que enfrentar dos aspectos fundamentales: 1. La tabla de páginas puede ser demasiado grande. 2. La asociación debe ser rápida. El primer punto proviene del hecho de que las computadoras modernas utilizan direcciones virtuales de al menos 32 bits. Por ejemplo, si el tamaño de página es de 4K, un hueco de direcciones de 32 bits tiene un millón de páginas; en el caso de un hueco de direcciones de 64 bits, se tendría más información de la que uno quisiera contemplar. El segundo punto es consecuencia del hecho de que la asociación virtual – física debe hacerse en cada referencia a la memoria. Una instrucción común tiene una palabra de instrucción y también un operando de memoria. Entonces es necesario hacer una, dos o más referencias a la tabla de páginas por cada instrucción. Características de la paginación: El espacio de direcciones lógico de un proceso puede ser no contiguo. Se divide la memoria física en bloques de tamaño fijo llamados marcos (frames). Se divide la memoria en bloques de tamaño llamados paginas. Se mantiene información en los marcos libres. Para correr un programa de n paginas de tamaño, se necesitan encontrara n marcos y cargar el programa. Se establece una tabla de paginas para trasladar las direcciones lógicas a físicas. Se produce fragmentación interna. Ventajas de la paginación 1. Es posible comenzar a ejecutar un programa, cargando solo una parte del mismo en memoria, y el resto se cargara bajo la solicitud. 2. No es necesario que las paginas estén contiguas en memoria, por lo que no se necesitan procesos de compactación cuando existen marcos de paginas libres dispersos en la memoria. 3. Es fácil controlar todas las páginas, ya que tienen el mismo tamaño. 4. El mecanismo de traducción de direcciones (DAT) permite separar los conceptos de espacio de direcciones y espacios de memoria. Todo el mecanismo es transparente al usuario. 5. Se libera al programador de la restricción de programar para un tamaño físico de memoria, con lo que s e aumenta su productividad. Se puede programar en función de una memoria mucho más grande a la existente. 6. Al no necesitarse cargar un programa completo en memoria para su ejecución, se puede aumentar el numero de programas multiprogramándose. 7. Se elimina el problema de fragmentación externa. Desventajas de la paginación 1. El costo de hardware y software se incrementa, por la nueva información que debe manejarse y el mecanismo de traducción de direcciones necesario. Se consume mucho mas recursos de memoria, tiempo en el CPU para su implantación. 2. Se deben reservar áreas de memoria para las PMT de los procesos. Al no ser fija el tamaño de estas, se crea un problema semejante al de los programas (como asignar un tamaño óptimo sin desperdicio de memoria, u "ovearhead" del procesador). 3. Aparece el problema de fragmentación interna. Así, si se requieren 5K para un programa, pero las paginas son de 4K, deberán asignárseles 2 paginas (8k), con lo que quedan 3K sin utilizar. La suma de los espacios libres dejados de esta forma puede ser mayor que el de varias paginas, pero no podrá ser utilizados. Debe asignarse un tamaño promedio a las páginas, evitando que si son muy pequeñas, se necesiten TABLAS BMT y PMT muy grandes, y si son muy grandes, se incremente el grado de fragmentación interna. Traducción de Direcciones La dirección generada por la CPU se divide en: Numero de pagina (p): utilizado como indice en la tabla de pagins que contiene la dirección base de cada pagina en la memoria fisica. Offset de la pagina (d): combinado con la dirección base dfine la direccion fisica que será enviada a la unidad de memoria. Ejemplo de paginación: 6. Segmentación Es un esquema de manejo de memoria mediante el cual la estructura del programa refleja su división lógica; llevándose a cabo una agrupación lógica de la información en bloques de tamaño variable denominados segmentos. Cada uno de ellos tienen información lógica del programa: subrutina, arreglo, etc. Luego, cada espacio de direcciones de programa consiste de una colección de segmentos, que generalmente reflejan la división lógica del programa. La segmentación permite alcanzar los siguientes objetivos: 1. Modularidad de programas: cada rutina del programa puede ser un bloque sujeto a cambios y recopilaciones, sin afectar por ello al resto del programa. 2. Estructuras de datos de largo variable: ejm. Stack, donde cada estructura tiene su propio tamaño y este puede variar. 3. Protección: se puede proteger los módulos del segmento contra accesos no autorizados. 4. Comparición: dos o más procesos pueden ser un mismo segmento, bajo reglas de protección; aunque no sean propietarios de los mismos. 5. Enlace dinámico entre segmentos: puede evitarse realizar todo el proceso de enlace antes de comenzar a ejecutar un programa. Los enlaces se establecerán solo cuando sea necesario. Ventajas de la segmentación El esquema de segmentación ofrece las siguientes ventajas: El programador puede conocer las unidades lógicas de su programa, dándoles un tratamiento particular. Es posible compilar módulos separados como segmentos el enlace entre los segmentos puede suponer hasta tanto se haga una referencia entre segmentos. Debido a que es posible separar los módulos se hace más fácil la modificación de los mismos. Cambios dentro de un modulo no afecta al resto de los módulos. Es fácil el compartir segmentos. Es posible que los segmentos crezcan dinámicamente según las necesidades del programa en ejecución. Existe la posibilidad de definir segmentos que aun no existan. Así, no se asignara memoria, sino a partir del momento que sea necesario hacer usos del segmento. Un ejemplo de esto, serian los arreglos cuya dimensión no se conoce hasta tanto no se comienza a ejecutar el programa. En algunos casos, incluso podría retardar la asignación de memoria hasta el momento en el cual se referencia el arreglo u otra estructura de dato por primera vez. Desventajas de la segmentación Hay un incremento en los costos de hardware y de software para llevar a cabo la implantación, así como un mayor consumo de recursos: memoria, tiempo de CPU, etc. Debido a que los segmentos tienen un tamaño variable se pueden presentar problemas de fragmentación externas, lo que puede ameritar un plan de reubicación de segmentos en memoria principal. Se complica el manejo de memoria virtual, ya que los discos almacenan la información en bloques de tamaños fijos, mientras los segmentos son de tamaño variable. Esto hace necesaria la existencia de mecanismos más costosos que los existentes para paginación. Al permitir que los segmentos varíen de tamaño, puede ser necesarios planes de reubicación a nivel de los discos, si los segmentos son devueltos a dicho dispositivo; lo que conlleva a nuevos costos. No se puede garantizar, que al salir un segmento de la memoria, este pueda ser traído fácilmente de nuevo, ya que será necesario encontrar nuevamente un área de memoria libre ajustada a su tamaño. La comparticion de segmentos permite ahorrar memoria, pero requiere de mecanismos adicionales da hardware y software. Estas desventajas tratan de ser minimizadas, bajo la técnica conocida como Segmentación paginada. 7. Segmentación Paginada Paginación y segmentación son técnicas diferentes, cada una de las cuales busca brindar las ventajas enunciadas anteriormente. Para la segmentación se necesita que estén cargadas en memoria, áreas de tamaños variables. Si se requiere cargar un segmento en memoria; que antes estuvo en ella y fue removido a memoria secundaria; se necesita encontrar una región de la memoria lo suficientemente grande para contenerlo, lo cual no es siempre factible; en cambio "recargar" una pagina implica solo encontrar un merco de pagina disponible. A nivel de paginación, si quiere referenciar en forma cíclicas n paginas, estas deberán ser cargadas una a una generándose varias interrupciones por fallas de paginas; bajo segmentación, esta pagina podría conformar un solo segmento, ocurriendo una sola interrupción, por falla de segmento. No obstante, si bajo segmentación, se desea acceder un área muy pequeña dentro de un segmento muy grande, este deberá cargarse completamente en memoria, desperdiciándose memoria; bajo paginación solo se cargara la página que contiene los ítems referenciados. Puede hacerse una combinación de segmentación y paginación para obtener las ventajas de ambas. En lugar de tratar un segmento como una unidad contigua, este puede dividirse en páginas. Cada segmento puede ser descrito por su propia tabla de páginas. Los segmentos son usualmente múltiplos de páginas en tamaño, y no es necesario que todas las páginas se encuentren en memoria principal a la vez; además las páginas de un mismo segmento, aunque se encuentren contiguas en memoria virtual; no necesitan estarlo en memoria real. Las direcciones tienen tres componentes: (s, p,d), donde la primera indica el numero del segmento, la segunda el numero de la pagina dentro del segmento y la tercera el desplazamiento dentro de la pagina. Se deberán usar varias tablas: SMT (tabla de mapas de segmentos): una para cada proceso. En cada entrada de la SMT se almacena la información descrita bajo segmentación pura, pero en el campo de dirección se indicara la dirección de la PMT (tabla de mapas de páginas) que describe a las diferentes páginas de cada segmento. PMT (tabla de mapas de páginas): una por segmento; cada entrada de la PMT describe una página de un segmento; en la forma que se presento la pagina pura. TBM (tabla de bloques de memoria): para controlar asignación de páginas por parte del sistema operativo. JT (tabla de Jobs): que contiene las direcciones de comienzo de cada una de las SMT de los procesos que se ejecutan en memoria. En el caso, de que un segmento sea de tamaño inferior o igual al de una pagina, no se necesita tener la correspondiente PMT, actuándose en igual forma que bajo segmentación pura; puede arreglarse un bit adicional (S) a cada entrada de la SMT, que indicara si el segmento esta paginado o no. Ventajas de la segmentación paginada El esquema de segmentación paginada tiene todas las ventajas de la segmentación y la paginación: Debido a que los espacios de memorias son segmentados, se garantiza la facilidad de implantar la comparticion y enlace. Como los espacios de memoria son paginados, se simplifican las estrategias de almacenamiento. Se elimina el problema de la fragmentación externa y la necesidad de compactación. Desventajas de la segmentación paginada Las tres componentes de la dirección y el proceso de formación de direcciones hace que se incremente el costo de su implantación. El costo es mayor que en el caso de de segmentación pura o paginación pura. Se hace necesario mantener un número mayor de tablas en memoria, lo que implica un mayor costo de almacenamiento. Sigue existiendo el problema de fragmentación interna de todas- o casi- todas las páginas finales de cada uno de los segmentos. Bajo paginación pura se desperdician solo la última página asignada, mientras que bajo segmentación – paginada el desperdicio puede ocurrir en todos los segmentos asignados. http://www.monografias.com/trabajos13/gesme/gesme.shtml 3.6.4 Asignación contigua v.s. no contigua. Para asignarle espacio a los archivos existen tres criterios generales que se describen enseguida. Asignación contigua: Cada directorio contiene la los nombres de archivos y la dirección del bloque inicial de cada archivo, así como el tamaño total de los mismos. Por ejemplo, si un archivo comienza en el sector 17 y mide 10 bloques, cuando el archivo sea accesado, el brazo se moverá inicialmente al bloque 17 y de ahí hasta el 27. Si el archivo es borrado y luego creado otro más pequeño, quedarán huecos inútiles entre archivos útiles, lo cual se llama fragmentación externa. Asignación encadenada: Con este criterio los directorios contienen los nombres de archivos y por cada uno de ellos la dirección del bloque inicial que compone al archivo. Cuando un archivo es leído, el brazo va a esa dirección inicial y encuentra los datos iniciales junto con la dirección del siguiente bloque y así sucesivamente. Con este criterio no es necesario que los bloques estén contiguos y no existe la fragmentación externa, pero en cada "eslabón" de la cadena se desperdicia espacio con las direcciones mismas. En otras palabras, lo que se crea en el disco es una lista ligada. Asignación con índices ( indexada ): En este esquema se guarda en el directorio un bloque de índices para cada archivo, con apuntadores hacia todos sus bloques constituyentes, de mabnera que el acceso directo se agiliza notablemente, a cambio de sacrificar varios bloques para almacenar dichos apuntadores. Cuando se quiere leer un archivo o cualquiera de sus partes, se hacen dos accesos: uno al bloque de índices y otro a la dirección deseada. Este es un esquema excelente para archivos grandes pero no para pequeños, porque la relación entre bloques destinados para índices respecto a los asignados para datos es incosteable. Asignación Contigua de Almacenamiento Versus No Contigua En la “asignación contigua” cada programa ocupa un bloque contiguo y sencillo de localizaciones de almacenamiento. En la “asignación no contigua” un programa se divide en varios bloques o “segmentos” que pueden almacenarse en direcciones que no tienen que ser necesariamente adyacentes, por lo que es más compleja pero más eficiente que la asignación continua. Asignación Contigua de Almacenamiento de Un Solo Usuario Se consideran S. O. que ya poseen desarrollado el “sistema de control de entrada / salida”: IOCS: input / output control system (ver Figura 3.2 [7, Deitel]). El tamaño de los programas está limitado por la cantidad de memoria principal, pero se puede superar este límite con técnicas de “recubrimientos”, con las siguientes características (ver Figura 3.3 [7, Deitel]): Si una sección particular del programa ya no es necesaria, se carga otra sección desde el almacenamiento secundario ocupando las áreas de memoria liberadas por la sección que ya no se necesita. La administración manual por programa del recubrimiento es complicada y dificulta el desarrollo y el mantenimiento. Protección en los sistemas de un solo usuario El usuario tiene un completo control sobre la totalidad del almacenamiento principal: El almacenamiento se divide en porciones que contienen el S. O., el programa del usuario y una porción sin usar. El programa del usuario podría destruir áreas del S. O. que podrían: o Detener el sistema. o Producir salidas erróneas. El S. O. debe estar protegido contra el proceso usuario: o La protección se instrumenta mediante un “registro de límites” incorporado a la cpu: Contiene la dirección de la instrucción más alta utilizada por el S. O. Si se intenta ingresar al S. O. la instrucción es interceptada y el proceso finaliza. Procesamiento por lotes de flujo único Los sistemas de un solo usuario se dedican a un trabajo durante más tiempo del que toma su ejecución. Los trabajos requieren de: “tiempo de instalación”: el necesario para preparar el entorno operativo requerido. “tiempo de descarga”: el necesario para desmontar el entorno operativo que fue requerido. Durante la instalación y descarga de los trabajos la cpu no está ejecutando dichos trabajos requeridos, por lo cual: Automatizar la “transición de trabajo a trabajo” reduce la cantidad de tiempo perdido entre trabajos. Surgieron los sistemas de “procesamiento por lotes”. En el “procesamiento por lotes de flujo único” los trabajos se agrupan en “lotes” encolándose para su ejecución. El “procesador de flujos de trabajos”: Lee las instrucciones del “lenguaje de control de trabajos”. Facilita la preparación del trabajo siguiente. Emite instrucciones al operador del sistema. Automatiza funciones anteriormente manuales. Cuando finaliza un trabajo efectúa las “operaciones de mantenimiento” apropiadas para facilitar la transición del siguiente trabajo. http://exa.unne.edu.ar/depar/areas/informatica/SistemasOperativos/SO3.htm#OAA MÉTODOS DE ASIGNACIÓN DE ESPACIO EN DISCO. Un método de asignación de espacio en disco determina la manera en que un Sistema Operativo controla los lugares del disco ocupados por cada archivo de datos. Se debe controlar básicamente la identificación del archivo, sector de inicio y sector final. Para el control del espacio ocupado en disco se puede utilizar como base alguno de los métodos teóricos: Asignación Contigua, Asignación Ligada, Asignación Indexada. ASIGNACIÓN CONTIGUA. Este método consiste en asignar el espacio en disco de tal manera que las direcciones de todos los bloques correspondientes a un archivo definen un orden lineal. Por ejemplo: VENTAJAS DESVENTAJAS - La cabeza de lectura no se mueve demasiado en la lectura de un archivo. - Produce fragmentación externa. ASIGNACIÓN LIGADA En este método, cada archivo es una lista ligada de bloques de disco. En el directorio hay un apuntador al bloque de inicio y un apuntador al bloque final para cada archivo. En cada uno de los bloques donde se encuentra un archivo hay un apuntador al siguiente bloque de la lista. Por ejemplo: VENTAJAS - No produce fragmentación externa. DESVENTAJAS La cabeza de lectura se puede mover demasiado en la lectura de un archivo. - Si una liga se pierde, se perderá el archivo completo. Es ineficiente para la implementación de archivos directos. Se necesita un campo extra para el apuntador. ASIGNACIÓN INDEXADA Como ya se vio, la asignación ligada resuelve problemas de fragmentación externa, sin embargo, la asignación ligada no soporta eficientemente el acceso directo a los archivos. La asignación indexada resuelve este problema poniendo todos los apuntadores en una sola localidad: El bloque índice. Cada archivo tiene su bloque índice, El cual es un arreglo de direcciones de bloques de disco. La i-ésima entrada en el bloque índice apunta al i-ésimo bloque que conforma el archivo. En el directorio se controla la dirección del bloque índice de cada archivo, por ejemplo: VENTAJAS No produce fragmentación externa. Eficiente para la implementación de archivos directos. DESVENTAJAS Existe desperdicio cuando hay archivos muy chicos. Desbordamiento de bloque índice. (Solución: creación de un esquema ligado; el ultimo bloque índice apunta a otro índice) http://www.itlp.edu.mx/publica/tutoriales/sistemasoperativos2/unidad4.htm#ASIG NACIÓN%20CONTIGUA. 3.6.5 Multiprogramación de partición fija, partición variable, con intercambio de almacenamiento. Multiprogramación de partición fija.- La memoria se divide en particiones de tamaño fijo (puede ser distinto el tamaño de cada partición). Originalmente los programas se compilaban y link editaban para ejecutar en una partición en particular (direcciones absolutas). Posteriormente los compiladores y link editores generan código reubicable para que un programa pudiera ejecutar en cualquier partición de memoria suficientemente grande. Con esta estructura de administración de memoria se desperdicia memoria y tiempo de CPU (si hay un programa corriendo los demás quedan encolados aunque haya otra partición libre). Multiprogramación de partición variable.- Cada programa o usuario utiliza tanta memoria como sea necesaria siempre que quepa en el almacenamiento real. Cuando los programas van terminando su ejecución se van generando agujeros en memoria. Particiones fijas o particiones variables En el esquema de la multiprogramación en memroia real se manejan dos alternativas para asignarle a cada programa su partición correspondiente: particiones de tamaño fijo o particiones de tamaño variable. La alternativa más simple son las particiones fijas. Dichas particiones se crean cuando se enciende el equipo y permanecerán con los tamaños iniciales hasta que el equipo se apague. Es una alternativa muy vieja, quien hacía la división de particiones era el operador analizando los tamaños estimados de los trabajos de todo el día. Por ejemplo, si el sistema tenía 512 kilobytes de RAM, podia asignar 64 k para el sistema operativo, una partición más de 64 k, otra de 128k y una mayor de 256 k. Esto era muy simple, pero inflexible, ya que si surgían trabajos urgentes, por ejemplo, de 400k, tenían que esperar a otro día o reparticionar, inicializando el equipo desde cero. La otra alternativa, que surgió después y como necesidad de mejorar la alternativa anterior, era crear particiones contiguas de tamaño variable. Para esto, el sistema tenía que mantener ya una estructura de datos suficiente para saber en dónde habían huecos disponibles de RAM y de dónde a dónde habían particiones ocupadas por programas en ejecución. Así, cuando un programa requería ser cargado a RAM, el sistema analizaba los huecos para saber si había alguno de tamaño suficiente para el programa que queria entrar, si era así, le asignaba el espacio. Si no, intentaba relocalizar los programas existentes con el propósito de hacer contiguo todo el espacio ocupado, así como todo el espacio libre y así obtener un hueco de tamaño suficiente. Si aún así el programa no cabía, entonces lo bloqueaba y tomaba otro. El proceso con el cual se juntan los huecos o los espacios ocupados se le llama `compactación'. El lector se habrá dado cuenta ya de que surgen varios problemas con los esquemas de particiones fijas y particiones variables: ø En base a qué criterio se elige el mejor tamaño de partición para un programa ? Por ejemplo, si el sistema tiene dos huecos, uno de 18k y otro de 24 k para un proceso que desea 20 k, ø Cual se le asigna ? Existen varios algoritmos para darle respuesta a la pregunta anterior, los cuales se ennumeran y describen enseguida. Primer Ajuste: Se asigna el primer hueco que sea mayor al tamaño deseado. Mejor Ajuste: Se asigna el hueco cuyo tamaño exceda en la menor cantidad al tamaño deseado. Requiere de una búsqueda exhaustiva. Peor Ajuste: Se asigna el hueco cuyo tamaño exceda en la mayor cantidad al tamaño deseado. Requiere también de una búsqueda exhaustiva. El Siguiente Ajuste: Es igual que el `primer ajuste' con la diferencia que se deja un apuntador al lugar en donde se asignó el último hueco para realizar la siguiente búsqueda a partir de él. Ajuste Rápido: Se mantienen listas ligadas separadas de acuerdo a los tamaños de los huecos, para así buscarle a los procesos un hueco más rápido en la cola correspondiente. Otro problema que se vislumbra desde aquí es que, una vez asignado un hueco, por ejemplo, con "el peor ajuste", puede ser que el proceso requiriera 12 kilobytes y que el hueco asignado fuera de 64 kilobytes, por lo cual el proceso va a desperdiciar una gran cantidad de memoria dentro de su partición, lo cual se le llama `fragmentación interna'. Por otro lado, conforme el sistema va avanzando en el día, finalizando procesos y comenzando otros, la memoria se va configurando como una secuencia contigua de huecos y de lugares asignados, provocando que existan huecos, por ejemplo, de 12 k, 28k y 30 k, que sumados dan 70k, pero que si en ese momento llega un proceso pidiéndolos, no se le pueden asignar ya que no son localidades contiguas de memoria ( a menos que se realice la compactación ). Al hecho de que aparezcan huecos no contiguos de memoria se le llama `fragmentación externa'. De cualquier manera, la multiprogramación fue un avance significativo para el mejor aprovechamiento de la unidad central de procesamiento y de la memoria misma, así como dio pie para que surgieran los problemas de asignación de memoria, protección y relocalización, entre otros. Los overlays Una vez que surgió la multiprogramación, los usuarios comenzaron a explorar la forma de ejecutar grandes cantidades de código en áreas de memoria muy pequeñas, auxiliados por algunas llamadas al sistema operativo. Es así como nacen los `overlays'. Esta técnica consiste en que el programador divide lógicamente un programa muy grande en secciones que puedan almacenarse el las particiones de RAM. Al final de cada sección del programa ( o en otros lugares necesarios ) el programador insertaba una o varias llamadas al sistema con el fin de descargar la sección presente de RAM y cargar otra, que en ese momento residía en disco duro u otro medio de almacenamiento secundario. Aunque esta técnica era eficaz ( porque resolvía el problema ) no era eficiente ( ya que no lo resolvía de la mejor manera ). Esta solución requería que el programador tuviera un conocimiento muy profundo del equipo de cómputo y de las llamadas al sistema operativo. Otra desventaja era la portabilidad de un sistema a otro: las llamadas cambiaban, los tamaños de particiones también. Resumiendo, con esta técnica se podían ejecutar programas más grandes que las particiones de RAM, donde la división del código corría a cuenta del programador y el control a cuenta del sistema operativo. Multiprogramación de Partición Fija Los sistemas de un solo usuario desperdician gran cantidad de recursos computacionales debido a que [7, Deitel] (ver Figura 3.4 [7, Deitel]): Cuando ocurre una petición de e / s la cpu normalmente no puede continuar el proceso hasta que concluya la operación de e / s requerida. Los periféricos de e / s frenan la ejecución de los procesos ya que comparativamente la cpu es varios órdenes de magnitud más rápida que los dispositivos de e / s. Los sistemas de “multiprogramación” permiten que varios procesos usuarios compitan al mismo tiempo por los recursos del sistema: Un trabajo en espera de e / s cederá la cpu a otro trabajo que esté listo para efectuar cómputos. Existe paralelismo entre el procesamiento y la e / s. Se incrementa la utilización de la cpu y la capacidad global de ejecución del sistema. Es necesario que varios trabajos residan a la vez en la memoria principal. Multiprogramación de Partición Fija: Traducción y Carga Absolutas Las “particiones” del almacenamiento principal: Son de tamaño fijo. Alojan un proceso cada una. La cpu se cambia rápidamente entre los procesos creando la ilusión de simultaneidad. Los trabajos se traducían con ensambladores y compiladores absolutos para ser ejecutados solo dentro de una partición específica (ver Figura 3.5 [7, Deitel]). El S. O. resulta de implementación relativamente sencilla pero no se optimiza la utilización de la memoria. Multiprogramación de Partición Fija: Traducción y Carga Relocalizables Los compiladores, ensambladores y cargadores de relocalización: Se usan para producir programas relocalizables que puedan ser ejecutados en cualquier partición disponible de tamaño suficiente para aceptarlos (ver Figura 3.6 [7, Deitel]). Son más complejos que los absolutos. Mejoran la utilización del almacenamiento. Confieren más flexibilidad en el armado de la carga de procesos. Protección en los Sistemas de Multiprogramación Si se utiliza asignación contigua de memoria la protección suele implementarse con varios “registros de límites” (ver Figura 3.7 y Figura 3.8 [7, Deitel]). Los extremos superior e inferior de una partición pueden ser: Delineados con dos registros. Indicados el límite inferior o superior y el tamaño de la partición o región. Fragmentación en la Multiprogramación de Partición Fija La “fragmentación de almacenamiento” ocurre en todos los sistemas independientemente de su organización de memoria. En los S. O. de multiprogramación de partición fija la fragmentación se produce cuando: Los trabajos del usuario no llenan completamente sus particiones designadas. Una partición permanece sin usar porque es demasiado pequeña para alojar un trabajo que está en espera. Multiprogramación de Partición Variable Los procesos ocupan tanto espacio como necesitan, pero obviamente no deben superar el espacio disponible de memoria [7, Deitel] (ver Figura 3.9 [7, Deitel]). No hay límites fijos de memoria, es decir que la partición de un trabajo es su propio tamaño. Se consideran “esquemas de asignación contigua”, dado que un programa debe ocupar posiciones adyacentes de almacenamiento. Los procesos que terminan dejan disponibles espacios de memoria principal llamados “agujeros”: Pueden ser usados por otros trabajos que cuando finalizan dejan otros “agujeros” menores. En sucesivos pasos los “agujeros” son cada vez más numerosos pero más pequeños, por lo que se genera un desperdicio de memoria principal. Combinación de agujeros (áreas libres) Consiste en fusionar agujeros adyacentes para formar uno sencillo más grande. Se puede hacer cuando un trabajo termina y el almacenamiento que libera tiene límites con otros agujeros. Compresión o Compactación de Almacenamiento Puede ocurrir que los agujeros (áreas libres) separados distribuidos por todo el almacenamiento principal constituyan una cantidad importante de memoria: Podría ser suficiente (el total global disponible) para alojar a procesos encolados en espera de memoria. Podría no ser suficiente ningún área libre individual (ver Figura 3.10 [7, Deitel]). La técnica de compresión de memoria implica pasar todas las áreas ocupadas del almacenamiento a uno de los extremos de la memoria principal: Deja un solo agujero grande de memoria libre contigua. Esta técnica se denomina “recogida de residuos” (ver Figura 3.11 [7, Deitel]). Principales desventajas de la compresión Consume recursos del sistema (ver Figura 3.12 [7, Deitel]). El sistema debe detener todo mientras efectúa la compresión, lo que puede afectar los tiempos de respuesta. Implica la relocalización (reubicación) de los procesos que se encuentran en la memoria: La información de relocalización debe ser de accesibilidad inmediata. Una alta carga de trabajo significa mayor frecuencia de compresión que incrementa el uso de recursos. Estrategias de Colocación del Almacenamiento Se utilizan para determinar el lugar de la memoria donde serán colocados los programas y datos que van llegando y se las clasifica de la siguiente manera: “Estrategia de mejor ajuste”: o Un trabajo nuevo es colocado en el agujero en el cual quepa de forma más ajustada: Debe dejarse el menor espacio sin usar. “Estrategia de primer ajuste”: o Un trabajo nuevo es colocado en el primer agujero disponible con tamaño suficiente para alojarlo. “Estrategia de peor ajuste”: o Consiste en colocar un programa en el agujero en el que quepa de la peor manera, es decir en el más grande posible: El agujero restante es también grande para poder alojar a un nuevo programa relativamente grande. Multiprogramación con Intercambio de Almacenamiento En el esquema de “intercambio” los programas del usuario no requieren permanecer en la memoria principal hasta su terminación [7, Deitel]. Una variante consiste en que un trabajo se ejecuta hasta que ya no puede continuar: Cede el almacenamiento y la cpu al siguiente trabajo. La totalidad del almacenamiento se dedica a un trabajo durante un breve período de tiempo. Los trabajos son “intercambiados”, dándose que un trabajo puede ser intercambiado varias veces antes de llegar a su terminación. Es un esquema razonable y eficiente para un número relativamente reducido de procesos de usuarios. Los sistemas de intercambio fueron los predecesores de los sistemas de paginación. El rendimiento de los sistemas de intercambio mejora al reducir el tiempo de intercambio: Manteniendo al mismo tiempo varias “imágenes de usuario o imágenes de memoria” en la memoria principal. Retirando una imagen de usuario de la memoria principal solo cuando es necesario su almacenamiento para una nueva imagen. Incrementando la cantidad de memoria principal disponible en el sistema. Las imágenes de usuario (imágenes de memoria) retiradas del almacenamiento principal se graban en el almacenamiento secundario (discos). 3.7 Organización de memoria virtual. Multiprogramación en memoria virtual La necesidad cada vez más imperiosa de ejecutar programas grandes y el crecimiento en poder de las unidades centrales de procesamiento empujaron a los diseñadores de los sistemas operativos a implantar un mecanismo para ejecutar automáticamente programas más grandes que la memoria real disponible, esto es, de ofrecer `memoria virtual'. La memoria virtual se llama así porque el programador ve una cantidad de memoria mucho mayor que la real, y en realidad se trata de la suma de la memoria de almacenamiento primario y una cantidad determinada de almacenamiento secundario. El sistema operativo, en su módulo de manejo de memoria, se encarga de intercambiar programas enteros, segmentos o páginas entre la memoria real y el medio de almacenamiento secundario. Si lo que se intercambia son procesos enteros, se habla entonces de multiprogramación en memoria real, pero si lo que se intercambian son segmentos o páginas, se puede hablar de multiprogramación con memoria virtual. La memoria virtual se apoya en varias técnicas interesantes para lograr su objetivo. Una de las teorias más fuertes es la del `conjunto de trabajo', la cual se refiere a que un programa o proceso no está usando todo su espacio de direcciones en todo momento, sino que existen un conjunto de localidades activas que conforman el `conjunto de trabajo'. Si se logra que las páginas o segmentos que contienen al conjunto de trabajo estén siempre en RAM, entonces el programa se desempeñará muy bien. Otro factor importante es si los programas exhiben un fenómeno llamado `localidad', lo cual quiere decir que algunos programas tienden a usar mucho las instrucciones que están cercanas a la localidad de la instrucción que se está ejecutando actualmente. 3.7.1 Evaluación de las organizaciones de almacenamiento. Introducción a la Organización del Almacenamiento Virtual “Almacenamiento virtual ” significa la capacidad de direccionar un espacio de almacenamiento mucho mayor que el disponible en el almacenamiento primario de determinado sistema de computación [7, Deitel]. Esta tecnología apareció en 1960 en la Universidad de Manchester (Inglaterra), en el sistema “Atlas”. Los métodos más comunes de implementación son mediante: Técnicas de “paginación”. Técnicas de “segmentación”. Una combinación de ambas técnicas. Las direcciones generadas por los programas en su ejecución no son, necesariamente, aquellas contenidas en el almacenamiento primario (memoria real), ya que las direcciones virtuales suelen seleccionarse dentro de un número mucho mayor de direcciones que las disponibles dentro del almacenamiento primario. La evolución en las organizaciones de almacenamiento puede resumirse como sigue: Real: o Sistemas dedicados a un solo usuario. Real: o Sistemas de multiprogramación en memoria real: Multiprogramación en partición fija: Absoluta. Relocalizable (reubicable). Multiprogramación en partición variable. Virtual: o Multiprogramación en almacenamiento virtual: Paginación pura. Segmentación pura. Combinación paginación / segmentación. Conceptos Básicos de Almacenamiento Virtual La clave del concepto de memoria (almacenamiento) virtual esta en la disociación: De las direcciones a las que hace referencia un programa. De las direcciones disponibles en la memoria real (almacenamiento primario). Los principales conceptos son los siguientes: “Direcciones virtuales”: o Son las referidas por un proceso en ejecución. “Direcciones reales”: o Son las disponibles dentro del almacenamiento primario. “Espacio de direcciones virtuales (v)” de un proceso: o Es el número de direcciones virtuales a que puede hacer referencia el proceso. “Espacio de direcciones reales (r)” de un computador: o Es el número de direcciones reales disponibles en el ordenador. Los procesos hacen referencia a direcciones virtuales pero éstas deben ejecutarse en el almacenamiento real: Las direcciones virtuales deben ser transformadas dentro de las direcciones reales, mientras el proceso está en ejecución. La traducción de direcciones deberá hacerse rápidamente para no degradar al sistema. Existen varios medios para asociar las direcciones virtuales con las reales (ver Figura 3.13 [7, Deitel]). Los mecanismos de “traducción dinámica de direcciones” (dat) convierten las direcciones virtuales en reales al ejecutarse el proceso. Las direcciones contiguas dentro del espacio de direcciones virtuales de un proceso no tienen por qué ser contiguas dentro del almacenamiento real, a esto se denomina “contigüidad artificial ” (ver Figura 3.14 [7, Deitel]). Organización del Almacenamiento de Niveles Múltiples Se deben proporcionar los medios para retener programas y datos en un gran almacenamiento auxiliar para: Permitir que el espacio de direcciones virtuales de un usuario sea mayor que el espacio de direcciones reales. Soportar multiprogramación de forma efectiva en un sistema con muchos usuarios que compartan el almacenamiento real. Se utiliza un esquema de almacenamiento de dos niveles (ver Figura 3.15 [7, Deitel]): Primer nivel: “almacenamiento real ”: o En él se ejecutan los procesos y en él deben estar los datos para que un proceso pueda referirse a ellos. Segundo nivel: “almacenamiento auxiliar, secundario o adicional ”: o Generalmente consta de discos de gran capacidad que pueden mantener los programas y datos que no caben al mismo tiempo en el más limitado almacenamiento real. Cuando se va a ejecutar un proceso su código y datos se pasan al almacenamiento principal. El almacenamiento real es compartido por varios procesos: Cada proceso puede tener un espacio de direcciones virtuales mucho mayor que el almacenamiento real. Solo se mantiene al mismo tiempo una pequeña parte de los programas y datos de cada proceso en el almacenamiento real. Transformación de Bloques Los mecanismos de traducción dinámica de direcciones deben mantener “mapas” que ilustren qué direcciones del almacenamiento virtual se encuentran en el almacenamiento real y dónde se encuentran [7, Deitel]. La información se agrupa en “bloques”: El sistema está informado del lugar del almacenamiento real donde han sido colocados los bloques de almacenamiento virtual. Cuanto mayor sea el bloque menor será la fracción del almacenamiento real que debe dedicarse a contener la información del mapa. Con bloques grandes: o Se reduce la sobrecarga de almacenamiento del mecanismo de transformación. o Se incrementa el tiempo de transferencia entre los almacenamientos secundario y primario. o Consumen más almacenamiento real pudiendo limitar el número de procesos que pueden compartirlo. Los bloques pueden ser de tamaño: o Igual : se denominan “páginas” y la organización de almacenamiento virtual asociada se denomina “paginación”. o Diferente: se denominan “segmentos” y la organización de almacenamiento virtual asociada se denomina “segmentación”. Se pueden combinar ambas técnicas: segmentos de tamaño variable compuestos de páginas de tamaño fijo. Las direcciones son “bidimensionales”, es decir que una dirección virtual “v” se indica por un par ordenado “(b,d)”, donde: “b”: número del bloque donde reside. “d”: desplazamiento a partir del inicio del bloque. La traducción de una dirección virtual “v = (b,d)” a la dirección real “r” considera lo siguiente (ver Figura 3.16 y Figura 3.17 [7, Deitel]): Cada proceso tiene su “tabla de mapa de bloques” mantenida por el sistema en el almacenamiento real. Un registro especial del procesador llamado “registro origen de la tabla de bloques” se carga con la dirección real “a” de la “tabla de mapa de bloques”: o Contiene una entrada para cada bloque del proceso. o Las entradas se mantienen en orden secuencial para el bloque 0, bloque 1, etc. o Se añade el bloque número “b” a la dirección base “a” de la “tabla de bloques” para formar la dirección real de la entrada de la “tabla de mapa de bloques” para el bloque “b”: Contiene la dirección real “b ’ ” para el bloque “b”. El desplazamiento “d” se añade a la dirección de inicio del bloque, “b ’ ”, para formar la “dirección real” deseada: “r = b ’ + d”. La transformación de bloques se efectúa en forma dinámica mientras se ejecuta un proceso, por lo cual, si la implementación no es eficiente, su sobrecarga puede causar una degradación del rendimiento que podría eliminar en parte las ventajas de la utilización del almacenamiento virtual. http://exa.unne.edu.ar/depar/areas/informatica/SistemasOperativos/SO3.htm#OAA 3.7.2 Paginación. Conceptos Básicos de Paginación Frecuentemente se diferencia entre la “paginación pura” y la “combinación de paginación y segmentación”[7, Deitel]. Las páginas se transfieren del almacenamiento secundario al primario en bloques llamados “marcos de páginas”: Tienen el mismo tamaño que las páginas. Comienzan en direcciones del almacenamiento real que son múltiplos enteros del tamaño fijo de la página. Podrá colocarse una nueva página dentro de cualquier “marco de página” o “celda de página” disponible. La “traducción dinámica de direcciones” incluye: Un proceso en ejecución hace referencia a una dirección virtual “v = (p,d)” (ver Figura 3.18 [7, Deitel]). Un mecanismo de transformación de páginas busca la página “p” en la “tabla de páginas” y determina si la página “p” se encuentra en el marco de página “p ’ ”. La dirección de almacenamiento real se forma por la concatenación de “p ’ ” y “d”. La tabla de “mapa de páginas” debe indicar si se encuentra o no en el almacenamiento primario la página referenciada: En caso afirmativo dónde está en la memoria real. En caso negativo dónde puede estar en el almacenamiento secundario. La dirección de almacenamiento primario “a”, donde comienza el marco de pagina “p ’ ” (suponiendo un tamaño de página “p”), está dada por: “a = (p) (p ’)”; se supone marcos de página numerados 0, 1, 2, etc. (ver Figura 3.19, Figura 3.20 y Figura 3.21 [7, Deitel]). Traducción de Direcciones de Paginación por Transformación Directa Un proceso en ejecución hace referencia a la dirección virtual v = (p,d). Antes que un proceso comience su ejecución, el S. O. carga la dirección de almacenamiento primario de la “tabla de mapa de páginas” en el “registro origen de la tabla de mapa de páginas” (Ver Figura 3.22 [7, Deitel]). La dirección base de la tabla de mapa de páginas es “b”. El número de página es “p”. La dirección en el almacenamiento primario de la entrada en la tabla de mapa de páginas para la página “p” es “b + p”: Indica que el marco de página “p ’ ” corresponde a la página virtual. “p ’ ” se concatena con el desplazamiento “d” par formar la dirección real “r”. “Esto es un ejemplo de transformación directa debido a que la tabla de mapa de páginas contiene una entrada por cada una de las páginas del almacenamiento virtual de este proceso”. La dirección virtual que se está traduciendo y la dirección base de la tabla de mapa de páginas son mantenidas en un registro de alta velocidad del control del procesador. La tabla de mapa de páginas transformada directamente suele mantenerse en el almacenamiento primario: Las referencias a esta tabla requieren un ciclo completo de almacenamiento primario, que generalmente es la parte más larga de un ciclo de ejecución de instrucciones. Se requiere otro ciclo de ejecución de almacenamiento primario para la transformación de páginas, lo que puede ocasionar degradación equivalente a un 50%, para lo cual una solución sería tener la tabla completa de mapa de páginas de transformación directa en la “caché” de muy alta velocidad. Traducción de Direcciones de Paginación por Transformación Asociativa Una forma de acelerar la traducción dinámica de páginas consiste en colocar la tabla completa de mapa de páginas en un “almacenamiento asociativo” que tenga un tiempo de ciclo mucho más rápido que el almacenamiento primario. Una variante es la “transformación asociativa pura” (ver Figura 3.23 [7, Deitel]). Un programa en ejecución hace referencia a la dirección virtual v = (p,d). Cada entrada en el almacenamiento asociativo se busca de forma simultánea para la página “p”: Se obtiene “p ’ ” como el marco de página correspondiente a la página “p”. Se concatena “p ’ ” con “d” formando la dirección real “r”. Cada una de las células del almacenamiento asociativo se registra de manera simultánea: Hace costoso el almacenamiento asociativo. Implementar la transformación asociativa pura resulta demasiado costoso, tal lo ocurrido con la implementación de la transformación directa pura utilizando “caché”. Traducción de Direcciones de Paginación por Combinación de Transformación Asociativa / Directa Se utiliza un almacenamiento asociativo capaz de mantener solo un pequeño porcentaje del mapa completo de páginas para un proceso (ver Figura 3.24 [7, Deitel]). Las entradas de página contenidas en este mapa reducido corresponden solo a las páginas referenciadas recientemente: Se presupone que una página recientemente referenciada tendrá posibilidades de serlo de nuevo próximamente. Los rendimientos obtenidos con este esquema de mapa asociativo parcial superan aproximadamente en un 100 % a los rendimientos obtenidos con esquemas de mapa asociativo de página completo. Un programa hace referencia a la dirección virtual v = (p,d). El mecanismo de traducción de direcciones intenta encontrar la página “p” en el mapa de página asociativo parcial: Si “p” se encuentra allí: o El mapa asociativo devuelve “p ’ ” como el número de marco de página correspondiente a la página virtual “p”. o “p ’ ” se concatena con el desplazamiento “d” para formar la dirección real “r” que corresponde a la dirección virtual v = (p,d). Si “p” no se encuentra en el mapa de pagina parcial: o Se utiliza un mapa directo convencional. o La dirección “b” del registro de origen de la tabla de páginas se añade a “p” para localizar la entrada apropiada a la página “p” en la tabla de mapa de páginas de transformación directa del almacenamiento primario. o La tabla indica que “p ’ ” es el marco de página correspondiente a la página virtual “p”. o “p ’ ” se concatena con el desplazamiento “d” para formar la dirección real “r” correspondiente a la dirección virtual v = (p,d). Compartimiento de Recursos en un Sistema de Paginación En sistemas multiprogramados, especialmente en los de tiempo compartido, es común que más de un usuario estén ejecutando los mismos programas: Para optimizar el uso de la memoria real se comparten las páginas que pueden ser compartidas: o El compartimiento debe ser cuidadosamente controlado para evitar que un proceso modifique datos que otro proceso esta leyendo (ver Figura 3.25 [7, Deitel]). o Los programas se encuentran divididos en áreas separadas de “procedimiento” y “datos”. o Los procedimientos no modificables se llaman “procedimientos puros reentrantes”. o Los datos y procedimientos modificables no pueden ser compartidos. o Los datos no modificables (ej.: tablas fijas) son compartibles. Se debe identificar cada página como compartible o no. Habrá marcos (celdas) de páginas compartidos por varios procesos. El compartimiento: Reduce la cantidad de almacenamiento primario necesario para la ejecución eficaz de un grupo de procesos. Puede hacer posible que un sistema determinado mantenga una cantidad mayor de usuarios (procesos). http://exa.unne.edu.ar/depar/areas/informatica/SistemasOperativos/SO3.htm#OAA Paginación pura La paginación pura en el majejo de memoria consiste en que el sistema operativo divide dinámicamente los programas en unidades de tamaño fijo ( generalmente múltiplos de 1 kilobyte ) los cuales va a manipular de RAM a disco y viceversa. Al proceso de intercambiar páginas, segmentos o programas completos entre RAM y disco se le conoce como `intercambio' o `swapping'. En la paginación, se debe cuidar el tamño de las páginas, ya que si éstas son muy pequeñas el control por parte del sistema operativo para saber cuáles están en RAM y cuales en disco, sus direcciones reales, etc; crece y provoca mucha `sobrecarga' (overhead). Por otro lado, si las páginas son muy grandes, el overhead disminuye pero entonces puede ocurrir que se desperdicie memoria en procesos pequeños. Debe haber un equilibrio. Uno de los aspectos más importantes de la paginación, asi como de cualquier esquema de memoria virtual, es la forma de traducir una dirección virtual a dirección real. Para explicarlo, obsérvese la figura Como se observa, una dirección virtual `v' = ( b,d) está formada por un número de página virtual `b' y un desplazamiento `d'. Por ejemplo, si el sistema ofrece un espacio de direcciones virtuales de 64 kilobytes, con páginas de 4 kilobytes y la RAM sólo es de 32 kilobytes, entonces tenemos 16 páginas virtuales y 8 reales. La tabla de direcciones virtuales contiene 16 entradas, una por cada página virtual. En cada entrada, o registro de la tabla de direcciones virtuales se almacenan varios datos: si la página está en disco o en memoria, quién es el dueño de la página, si la página ha sido modificada o es de lectura nada mas, etc. Pero el dato que nos interesa ahora es el número de página real que le corresponde a la página virtual. Obviamente, de las 16 virtuales, sólo ocho tendrán un valor de control que dice que la página está cargada en RAM, así como la dirección real de la página, denotada en la figura 4.3 como b' . Por ejemplo, supóngase que para la página virtual número 14 la tabla dice que, efectivamente está cargada y es la página real 2 ( dirección de memoria 8192 ). Una vez encontrada la página real, se le suma el desplazamiento, que es la dirección que deseamos dentro de la página buscada ( b' + d ). La tabla de direcciones virtuales a veces está ubicada en la misma meoria RAM, por lo cual se necesita saber en qué dirección comienza, en este caso, existe un registro con la dirección base denotada por la letra `a' en la figura 4.3. Cuando se está buscando una página cualquiera y ésta no está cargada, surge lo que se llama un `fallo de página' (page fault ). Esto es caro para el manejador de memoria, ya que tiene que realizar una serie de pasos extra para poder resolver la dirección deseada y darle su contenido a quien lo pide. Primero, se detecta que la página no está presente y entonces se busca en la tabla la dirección de esta página en disco. Una vez localizada en disco se intenta cargar en alguna página libre de RAM. Si no hay páginas libres se tiene que escoger alguna para enviarla hacia el disco. Una vez escogida y enviada a disco, se marca su valor de control en la tabla de direcciones virtuales para indicar que ya no está en RAM, mientras que la página deseada se carga en RAM y se marca su valor para indicar que ahora ya está en RAM. Todo este procedimiento es caro, ya que se sabe que los accesos a disco duro son del orden de decenas de veces más lentos que en RAM. En el ejemplo anterior se mencionó que cuando se necesita descargar una página de RAM hacia disco se debe de hacer una elección. Para realizar esta elección existen varios algoritmos, los cuales se describen enseguida. _ La primera en entrar, primera en salir: Se escoge la página que haya entrado primero y esté cargada en RAM. Se necesita que en los valores de control se guarde un dato de tiempo. No es eficiente porque no aprovecha ninguna característica de ningún sistema. Es justa e imparcial. _ La no usada recientemente: Se escoge la página que no haya sido usada (referenciada) en el ciclo anterior. Pretende aprovechar el hecho de la localidad en el conjunto de trabajo. La usada menos recientemente: Es parecida a la anterior, pero escoge la página que se usó hace más tiempo, pretendiendo que como ya tiene mucho sin usarse es muy probable que siga sin usarse en los próximos ciclos. Necesita de una búsqueda exhaustiva. La no usada frecuentemente: Este algoritmo toma en cuenta no tanto el tiempo, sino el número de referencias. En este caso cualquier página que se use muy poco, menos veces que alguna otra. La menos frecuentemente usada: Es parecida a la anterior, pero aquí se busca en forma exhaustiva aquella página que se ha usado menos que todas las demás. En forma aleatoria: Elige cualquier página sin aprovechar nada. Es justa e imparcial, pero ineficiente. Otro dato interesante de la paginación es que ya no se requiere que los programas estén ubicados en zonas de memoria adyacente, ya que las páginas pueden estar ubicadas en cualquier lugar de la memoria RAM. 3.7.3 Segmentación. Segmentación En los sistemas de “segmentación” un programa y sus datos pueden ocupar varios bloques separados de almacenamiento real (ver Figura 3.26 [7, Deitel]). Los bloques: No necesitan ser de igual tamaño. Los bloques separados no necesitan ser adyacentes. Deben estar compuestos de posiciones contiguas de almacenamiento. Se complica la protección de bloques de memoria de un proceso de usuario. Es más difícil limitar el rango de acceso de cualquier programa [7, Deitel]. Un esquema posible de protección es el uso de claves de protección del almacenamiento (ver Figura 3.27 [7, Deitel]): Las claves están bajo el control estricto del S. O. Un programa de usuario, a quien corresponde una cierta clave en la cpu, solo puede hacer referencia a los otros bloques del almacenamiento con igual clave de protección. Una dirección virtual es un par ordenado v=(s,d) (ver Figura 3.28 [7, Deitel]): “s” es el número del segmento del almacenamiento virtual en el cual residen los elementos referidos. “d” es el desplazamiento en el segmento “s” en el cual se encuentra el elemento referido. Un proceso solo puede ejecutarse si su segmento actual (como mínimo) está en el almacenamiento primario. Los segmentos se transfieren del almacenamiento secundario al primario como unidades completas. Un nuevo segmento puede ser colocado en una serie disponible de posiciones contiguas del almacenamiento primario de tamaño suficiente para alojar al segmento. La traducción dinámica de direcciones utiliza una “tabla de mapa de segmentos”. Inicio: Fin: Control de Acceso en Sistemas de Segmentación Se le otorga a cada proceso ciertos derechos de acceso a todos los segmentos y se le niega completamente el acceso a muchos otros. Si un proceso tiene “acceso de lectura” a un segmento, puede obtener cualquier elemento de información contenido en ese segmento. Si un proceso tiene “acceso de escritura” a un segmento, puede modificar cualquier contenido del segmento y puede introducirle información adicional, incluso destruir toda la información del segmento. Un proceso con “acceso de ejecución” de un segmento puede ejecutarlo como si fuera un programa. Un proceso con “acceso de adición” puede escribir información adicional al final del segmento, pero no puede modificar la información existente. En base a los “tipos de control de acceso” indicados pueden crearse distintos “modos de control de acceso”. Ejemplos de combinación de los accesos de lectura, escritura y ejecución para producir modos de protección útiles se dan en la Tabla 3.1 y en la Tabla 3.2 [7, Deitel]. Modo Lectura Escritura Ejecución Explicación 0 N N N No hay permiso de acceso 1 N N S Solo ejecución 2 S N N Solo lectura 3 S N S Lectura / ejecución 4 S S N Lectura / escritura pero no ejecución 5 S S S Acceso no limitado Tabla 3.1: Ejemplo de combinación de accesos. Modo Aplicación 0 Seguridad 1 Un programa disponible a los usuarios, que no pueden copiarlo ni modificarlo, pero sí ejecutarlo 2 Recuperación de información 3 Un programa puede ser copiado o ejecutado, pero no puede ser modificado 4 Protege los datos contra un intento erróneo de ejecutarlos 5 Este acceso se concede a los usuarios de confianza Tabla 3.2: Ejemplo de aplicaciones de la combinación de accesos. Inicio: Fin: Traducción de Direcciones de Segmentación por Transformación Directa Existen varias estrategias para la implementación de la traducción de direcciones de segmentación: Por transformación directa, asociativa o combinación de asociativa / directa. Con caché suficiente para alojar la tabla completa de mapa de segmentos o caché parciales que contengan solo las entradas de los segmentos de referencia más reciente (ver Figura 3.29 [7, Deitel]). Se considerará la traducción de direcciones de segmentación con la tabla completa de mapa de segmentos en la caché. Un proceso en ejecución hace referencia a la dirección virtual v = (s,d): El segmento número “s” se añade a la dirección base “b” en el registro origen de la tabla de mapa de segmentos formando la dirección de memoria real “b + s”, de la entrada para el segmento “s” de la tabla de mapa de segmentos, que contiene la dirección del almacenamiento primario “s ’ ”, donde comienza el segmento. El desplazamiento “d” se añade a “s ’ ” formando la dirección real “r = d + s ’ ”, correspondiente a la dirección virtual “v = (s,d)”. Un “bit de residencia”, “r”, indica si en la actualidad el segmento se encuentra o no en el almacenamiento primario. Si el segmento se encuentra en el almacenamiento primario “s ’ ” es la dirección en este almacenamiento donde comienza el segmento. Si el segmento no se encuentra en el almacenamiento primario “a” es la dirección en el almacenamiento secundario de donde debe recuperarse antes que el proceso pueda continuar. Se compara cada referencia a un segmento con los bits de protección para determinar si se permite la operación que se está intentando. Si el segmento buscado no está en el almacenamiento primario se genera un “fallo de pérdida de segmento”: El S. O. obtiene el control y carga el segmento referido desde la dirección “a” del almacenamiento secundario. Se comprueba si el desplazamiento “d” es menor o igual a la longitud del segmento “l ”: o Si no es así se genera un “fallo de desbordamiento de segmento” y el S. O. obtiene el control y termina la ejecución del proceso. o Si el desplazamiento está en el rango del segmento se comprueban los bits de protección para asegurarse si se permite la operación que se está intentando: Si es así entonces la dirección base del segmento, “s ’ ”, en el almacenamiento primario se añade al desplazamiento “d” formando la dirección de memoria real “r = s ’ + d”, que corresponde a la dirección del almacenamiento virtual “v = (s,d)”. Si la operación intentada no se permite se genera un “fallo de protección de segmento” y el S. O. obtiene el control y termina la ejecución del proceso. Inicio: Fin: Compartimiento en un Sistema de Segmentación Una de las ventajas de la segmentación sobre la paginación es que se trata más de un hecho lógico que físico: En un sistema de segmentación, una vez que un segmento ha sido declarado como compartido, entonces las estructuras que lo integran pueden cambiar de tamaño. Lo anterior no cambia el hecho lógico de que residen en un segmento compartido. Dos procesos pueden compartir un segmento con solo tener entradas en sus tablas generales que apunten al mismo segmento del almacenamiento primario (ver Figura 3.30 [7, Deitel]). http://exa.unne.edu.ar/depar/areas/informatica/SistemasOperativos/SO3.htm#OAA Segmentación pura La segmentación se aprovecha del hecho de que los programas se dividen en partes lógicas, como son las partes de datos, de código y de pila (stack). La segmentación asigna particiones de memoria a cada segmento de un programa y busca como objetivos el hacer fácil el compartir segmentos ( por ejemplo librerías compartidas ) y el intercambio entre memoria y los medios de almacenamiento secundario. Por ejemplo, en la versión de UNIX SunOS 3.5, no existían librerías compartidas para algunas herramientas, por ejemplo, para los editores de texto orientados al ratón y menús. Cada vez que un usuario invocaba a un editor, se tenía que reservar 1 megabyte de memoria. Como los editores son una herramienta muy solicitada y frecuentemente usada, se dividió en segmentos para le versión 4.x ( que a su vez se dividen en páginas ), pero lo importante es que la mayor parte del editor es común para todos los usuarios, de manera que la primera vez que cualquier usuario lo invocaba, se reservaba un megabyte de memoria como antes, pero para el segundo, tercero y resto de usuarios, cada editor extra sólo consumía 20 kilobytes de memoria. El ahorro es impresionante. Obsérvese que en la segmentación pura las particiones de memoria son de tamaño variable, en contraste con páginas de tamaño fijo en la paginación pura. También se puede decir que la segmentación pura tiene una granularidad menor que la paginación por el tamanó de segmentos versus tamaño de páginas. Nuevamente, para comprender mejor la segmentación, se debe dar un repaso a la forma en que las direcciones virtuales son traducidas a direcciones reales, y para ellos se usa la figura 4.4. Prácticamente la traducción es igual que la llevada a cabo en la paginación pura, tomando en consideracióñ que el tamaño de los bloques a controlar por la tabla de traducción son variables, por lo cual, cada entrada en dicha tabla debe contener la longitud de cada segmento a controlar. Otra vez se cuenta con un registro base que contiene la dirección del comienzo de la tabla de segmentos. La dirección virtual se compone de un número de segmento (s) y un desplazamiento ( d ) para ubicar un byte (o palabra ) dentro de dicho segmento. Es importante que el desplazamiento no sea mayor que el tamaño del segmento, lo cual se controla simplemente checando que ese valor sea mayor que la dirección del inicio del segmento y menor que el inicio sumado al tamaño. Una ves dada una dirección virtual v=( s,d ), se realiza la operación b + s para hallar el registro (o entrada de la tabla de segmentos ) que contiene la dirección de inicio del segmento en la memoria real, denotado por s'. Ya conociendo la dirección de inicio en memoria real s' sólo resta encontrar el byte o palabra deseada, lo cual se hace sumándole a s' el valor del desplazamiento, de modo que la dirección real ® r = s'+ d. Cada entrada en la tabla de segmentos tiene un formato similar al mostrado en la figura 4.5. Se tienen campos que indican la longitud, los permisos, la presencia o ausencia y dirección de inicio en memoria real del segmento. Según amplios experimentos [Deitel93] sugieren que un tamaño de páginas de 1024 bytes generalmente ofrece un desempeño muy aceptable. Intuitivamente parecería que el tener páginas del mayor tamaño posible haría que el desempeño fuera óptimo pero no es así, a menos que la página fuera del tamaño del proceso total. No es así con tamaños grandes de página menores que el proceso, ya que cuando se trae a memoria principal una página por motivo de un solo byte o palabra, se están trayendo muchísimos más bytes de los deseados. La dependencia entre el número de fallas respecto al tamaño de las páginas se muestra en la figura 4.6. Un hecho notable en los sistemas que manejan paginación es que cuando el proceso comienza a ejecutarse ocurren un gran número de fallos de página, porque es cuando está referenciando muchas direcciones nuevas por vez primera, después el sistema se estabiliza, conforme el número de marcos asignados se acerca al tamaño del conjunto de trabajo. El la figura 4.7 se muestra la relación entre el tiempo promedio entre fallas de página y el número de marcos de página asignados a un proceso. Allí se ve que el tiempo entre fallas decrece conforme se le asignan más páginas al proceso. La gráfica se curva en un punto, el cual corresponde a que el proceso tiene un número de páginas asignado igual al que necesita para almacenar su conjunto de trabajo. Después de eso, el asignarle a un proceso más páginas que las de su conjunto de trabajo ya no conviene, ya que el tiempo promedio entre fallas permanece sin mucha mejora. Un aspecto curioso de aumentar el número de páginas a un proceso cuando el algoritmo de selección de páginas candidatas a irse a disco es la primera en entrar primera en salir es la llamada `anomalía FIFO' a `anomalía de Belady'. Belady encontró ejemplos en los que un sistema con un número de páginas igual a tres tenía menos fallas de páginas que un sistema con cuatro páginas. El ejemplo descrito en [Tanxx] es injusto. Si se mira con cuidado, obviamente si se compara un sistema con 10 páginas contra otro de 5, ya de inicio el primer sistema tendrá 5 fallos de página más que el de 5, porque se necesitan diez fallos para cargarlo. A esto debería llamársele `anomalía de Belady con corrección. 3.7.4 Sistemas de paginación segmentación. Sistemas de Paginación / Segmentación Ofrecen las ventajas de las dos técnicas de organización del almacenamiento virtual [7, Deitel]. El tamaño de los segmentos es múltiplo del de las páginas. No es necesario que todas las páginas de un segmento se encuentren al mismo tiempo en el almacenamiento primario. Las páginas de almacenamiento virtual, que son contiguas en este almacenamiento, no necesitan ser contiguas en el almacenamiento real. El direccionamiento es tridimensional con una dirección de almacenamiento virtual “v = (s,p,d)”: “s” es el número del segmento. “p” es el número de página. “d” es el desplazamiento en la página donde se encuentra asignado el elemento deseado. Inicio: Fin: Traducción Dinámica de Direcciones en Sistemas de Paginación / Segmentación Se considera la traducción dinámica de direcciones de virtuales a reales en un sistema de paginación / segmentación utilizando la combinación de transformación asociativa / directa (ver Figura 3.31 [7, Deitel]). El proceso en ejecución hace referencia a la dirección virtual v = (s,p,d) (ver Figura 3.32 [7, Deitel]). Las páginas de referencia más reciente tienen entradas en un almacenamiento asociativo. Se realiza una búsqueda asociativa para intentar localizar (s,p) en el almacenamiento asociativo: Si se encuentra (s,p), entonces el marco de página “p ’ ” en el cual reside dicha página en la memoria real, se concatena al desplazamiento “d” para formar la dirección de memoria real “r” correspondiente a la dirección virtual v= (s,p,d). Si no se encuentra (s,p), entonces: o o o La dirección base “b” de la tabla de segmentos se añade al número de segmento “s” formando la dirección “b + s” de la entrada de la tabla de mapa de segmentos para el segmento “s” de la memoria real. La entrada de la tabla de mapa de segmentos indica la dirección base “s ’ ” de la tabla de páginas para el segmento “s”. El número de página “p” se añade a “s ’ ” formando la dirección “p + s ’ ” de la entrada en la tabla de páginas para la página “p” del segmento “s”: Indica que “p ’ ” es el número del marco correspondiente a la página virtual “p”. “p ’ ” se concatena con el desplazamiento “d” formando la dirección real “r ” que corresponde a la dirección virtual v = (s,p,d). Si el segmento “s” no se encuentra en el almacenamiento primario se produce un “fallo de pérdida de segmento”, cuyo caso el S. O. localiza el segmento en el almacenamiento secundario, crea una tabla de páginas para el segmento y carga la página apropiada en el almacenamiento primario, pudiendo producir reemplazos de páginas. Si el segmento “s” está en el almacenamiento primario y si la referencia a la tabla de mapa de páginas indica que la página deseada no se encuentra en el almacenamiento primario, se produce un “fallo de pérdida de página”, en tal caso el S. O. obtiene el control, localiza la página en el almacenamiento secundario y la carga, pudiendo reemplazar otra página. Si una dirección de almacenamiento virtual está más allá del final del segmento se genera un “fallo de desbordamiento de segmento”, el que debe ser atendido por el S. O. Si los bits de protección indican que la operación que se va a ejecutar en la dirección virtual referida no se permite, se genera un “fallo de protección de segmento”, el que también debe ser atendido por el S. O. Si se utiliza un mecanismo de transformación directa pura, manteniendo el mapa completo dentro del almacenamiento primario, la referencia promedio de almacenamiento virtual requeriría: Un ciclo de almacenamiento para acceder a la tabla de mapa de segmentos. Un segundo ciclo de almacenamiento para hacer referencia a la tabla de mapa de páginas. Un tercer ciclo de almacenamiento para referenciar al elemento deseado del almacenamiento real. Cada referencia a un elemento comprende tres ciclos de almacenamiento: El sistema correría casi a 1 / 3 de su velocidad nominal. La traducción de direcciones insumiría 2 / 3 del tiempo. Con la utilización de registros asociativos (por ej. 16 registros), se logran velocidades de ejecución del 90 % o más de la velocidad total de procesamiento de sus procesadores de control. La estructura de tablas de procesos, de mapas de segmentos y de mapas de páginas puede consumir un porcentaje importante del almacenamiento primario cuando se ejecutan un gran número de procesos. La traducción procede mucho más rápido si todas las tablas están en el almacenamiento primario, lo que resta espacio para los procesos. Inicio: Fin: Compartimiento en un Sistema de Paginación / Segmentación Se implementa disponiendo entradas en tablas de mapa de segmentos para diferentes procesos que apunten a la misma tabla de mapa de páginas (ver Figura 3.33 [7, Deitel]). El compartimiento requiere una administración cuidadosa por parte del S. O., ya sea en sistemas de paginación, segmentación o paginación / segmentación, pues se debe considerar qué sucedería si una nueva página reemplazara a otra página compartida por muchos procesos. http://exa.unne.edu.ar/depar/areas/informatica/SistemasOperativos/SO3.htm#OAA Sistemas combinados La paginación y la segmentación puras son métodos de manejo de memoria bastante efectivos, aunque la mayoría de los sistemas operativos modernos implantan esquemas combinados, es decir, combinan la paginación y la segmentación. La idea de combinar estos esquemas se debe a que de esta forma se aprovechan los conceptos de la división lógica de los programas (segmentos) con la granularidad de las páginas. De esta forma, un proceso estará repartido en la memoria real en pequeñas unidades (páginas) cuya liga son los segmentos. También es factible así el compartir segmentos a medida que las partes necesitadas de los mismos se van referenciando (páginas). Para comprender este esquema, nuevamente se verá cómo se traduce una dirección virtual en una localidad de memoria real. Para la paginación y segmentacíon puras se puede decir que el direccionamiento es `bidimensional' porque se necesitan dos valores para hallar la dirección real. Para el caso combinado, se puede decir que se tiene un direccionamiento `tridimensional'. En la figura 4.8 [ Deitel93] se muestran las partes relevantes para lograr la traducción de direcciones. El sistema debe contar con una tabla de procesos (TP). Por cada renglón de esa tabla se tiene un número de proceso y una dirección a una tabla de segmentos. Es decir, cada proceso tiene una tabla de segmentos. Cuando un proceso hace alguna referencia a memoria, se consulta TP para encontrar la tabla de segmentos de ese proceso. En cada tabla de segmentos de proceso (TSP) se tienen los números de los segmentos que componen a ese proceso. Por cada segmento se tiene una dirección a una tabla de páginas. Cada tabla de páginas tiene las direcciones de las páginas que componen a un solo segmento. Por ejemplo, el segmento `A' puede estar formado por las páginas reales `a','b','c','p' y `x'. El segmento `B' puede estar compuesto de las páginas `f','g','j','w' y `z'. Para traducir una dirección virtual v=(s,p,d) donde `s' es el segmento, `p' es la página y `d' el desplazamiento en la página se hace lo siguiente. Primero se ubica de qué proceso es el segmento y se localiza la tabla de segmentos de ese proceso en la TP. Con `s' como índice se encuentra un renglón ( registro) en la tabla de segmentos de ese proceso y en ese renglón está la dirección de la tabla de páginas que componen al segmento. Una vez en la tabla de páginas se usa el valor `p' como índice para encontrar la dirección de la página en memoria real. Una vez en esa dirección de memoria real se encuentra el byte (o palabra) requerido por medio del valor de `d'. Ahora, en este esquema pueden haber dos tipos de fallos: por fallo de página y por fallo de segmento. Cuando se hace referencia a una dirección y el segmento que la contiene no está en RAM ( aunque sea parcialmente ), se provoca un fallo por falta de segmento y lo que se hace es traerlo del medio de almacenamiento secundario y crearle una tabla de páginas. Una vez caragado el segmento se necesita localizar la página correspondiente, pero ésta no existe en RAM, por lo cual se provoca un fallo de página y se carga de disco y finalmente se puede ya traer la dirección deseada por medio del desplazamiento de la dirección virtual. La eficiencia de la traducción de direcciones tanto en paginación pura, segmentación pura y esquemas combinados se mejora usando memorias asociativas para las tablas de páginas y segmentos, así como memorias cache para guardar los mapeos más solicitados. Otro aspecto importante es la estrategia para cargar páginas ( o segmentos ) a la memoria RAM. Se usan más comunmente dos estrategias: cargado de páginas por demanda y cargado de páginas anticipada. La estrategia de caragdo por demanda consiste en que las páginas solamente son llevadas a RAM si fueron solicitadas, es decir, si se hizo referencia a una dirección que cae dentro de ellas. La carga anticipada consiste en tratar de adivinar qué páginas serán solicitadas en el futuro inmediato y cargarlas de antemano, para que cuando se pidan ya no ocurran fallos de página. Ese `adivinar' puede ser que se aproveche el fenómeno de localidad y que las páginas que se cargan por anticipado sean aquellas que contienen direcciones contiguas a la dirección que se acaba de refenciar. De hecho, el sistema operativo VMS usa un esquema combinado para cargar páginas: cuando se hace referencia a una dirección cuya página no está en RAM, se provoca un fallo de página y se carga esa página junto con algunas páginas adyacentes. En este caso la página solicitada se cargó por demanda y las adyacentes se cargaron por anticipación. 3.8 Administración de memoria virtual. 3.8.1 Estrategias de administración. Estrategias de Administración del Almacenamiento Virtual Las diferentes organizaciones de almacenamiento virtual generalmente implementadas son [7, Deitel]: Paginación. Segmentación. Segmentación y paginación. Las estrategias para la administración de sistemas de almacenamiento virtual condicionan la conducta de los sistemas de almacenamiento virtual que operan según esas estrategias. Se consideran las siguientes estrategias: “Estrategias de búsqueda”: o Tratan de los casos en que una página o segmento deben ser traídos del almacenamiento secundario al primario. o Las estrategias de “búsqueda por demanda” esperan a que se haga referencia a una página o segmento por un proceso antes de traerlos al almacenamiento primario. o Los esquemas de “búsqueda anticipada” intentan determinar por adelantado a qué páginas o segmentos hará referencia un proceso para traerlos al almacenamiento primario antes de ser explícitamente referenciados. “Estrategias de colocación”: o Tratan del lugar del almacenamiento primario donde se colocará una nueva página o segmento. o Los sistemas toman las decisiones de colocación de una forma trivial ya que una nueva página puede ser colocada dentro de cualquier marco de página disponible. “Estrategias de reposición”: o Tratan de la decisión de cuál página o segmento desplazar para hacer sitio a una nueva página o segmento cuando el almacenamiento primario está completamente comprometido. http://exa.unne.edu.ar/depar/areas/informatica/SistemasOperativos/SO3.htm#OAA 3.8.2 Técnicas de reemplazo de páginas. Reemplazo de Página.- Si al momento de generarse un page fault no hubiera ningún frame disponible, se debe proceder a reemplazar una pagina de memoria. LA rutina de page fault debe ser modificada para incluir reemplazo de páginas: 1. Encontrar un frame disponible. 2. Si hay un frame disponible usarlo 3. Si no hay frames disponibles utilizar algoritmo de reemplazo de paginas para seleccionar la víctima 4. Escribir la pagina víctima a disco y actualizar tabla de paginas . Estrategias de Reposición de Página Las principales son: El principio de optimización. Reposición de páginas al azar. Primero en entrar - primero en salir. Menos recientemente usada. Menos frecuentemente usada. No usada recientemente. Conjuntos de trabajo. El Principio de Optimización El “principio de optimización” indica que para obtener un rendimiento óptimo, la página que se va a reponer es una que no se va a utilizar en el futuro durante el período de tiempo más largo. El problema es que no es factible predecir el futuro. Reposición de Página al Azar Consiste en escoger al azar la página que va a ser reemplazada. Todas las páginas del almacenamiento principal deben tener la misma probabilidad de ser reemplazadas. Debe poder seleccionar cualquier página, incluyendo la que va a ser referenciada a continuación (peor selección). Este esquema es raramente usado. Reposición de Página por el Sistema de Primero en Entrar -Primero en Salir (FIFO) Se registra el momento en que cada página ingresa al almacenamiento primario. Para reemplazar una página, se selecciona aquella que ha estado más tiempo almacenada. Se presenta el inconveniente de que se pueden reemplazar páginas muy usadas, que serán llamadas de nuevo al almacenamiento primario casi de inmediato. Se puede presentar la llamada “anomalía FIFO”: Belady, Nelson y Shedler descubrieron que con la reposición FIFO, ciertos patrones de referencias de páginas causan más fallos de páginas cuando se aumenta el número de marcos (celdas) de páginas asignados a un proceso: en esto consiste la “anomalía FIFO”. Esta anomalía contradice a la intuición (ver Figura 3.34 [7, Deitel]). Reposición de Página Menos - Recientemente - Usada (LRU) Esta estrategia selecciona para ser reemplazada la página que no ha sido usada durante el mayor período de tiempo. Se basa en la heurística de que el pasado reciente es un buen indicador del futuro próximo. Requiere que cada página reciba un “sello de tiempo” cada vez que se referencia: Puede significar una sobrecarga adicional importante. No se implementa frecuentemente. La página seleccionada para reemplazo podría ser la próxima en ser requerida, por lo que habría que paginarla de nuevo al almacenamiento principal casi de inmediato. Reposición de Página Menos - Frecuentemente - Usada (LFU) Acá interesa la intensidad de uso que haya tenido cada página. La página que será reemplazada es aquella que ha sido usada con menos frecuencia o que ha sido referida con menos intensidad. El inconveniente es que se puede seleccionar fácilmente para su reposición la página equivocada: Ej.: La página de uso menos frecuente puede ser la página de entrada más reciente al almacenamiento principal, y por lo tanto existe una alta probabilidad de que sea usada de inmediato. Reposición de Página No Usada - Recientemente (NUR) Presupone que las páginas que no han tenido uso reciente tienen poca probabilidad de ser usadas en el futuro próximo y pueden ser reemplazadas por otras nuevas. Es deseable reemplazar una página que no ha sido cambiada mientras estaba en el almacenamiento primario. La estrategia NUR se implementa con la adición de dos bits de hardware por página: “Bit referenciado”: o = 0 si la página no ha sido referenciada. o = 1 si la página ha sido referenciada. “Bit modificado” (también llamado “bit sucio”): o = 0 si la página no ha sido modificada. o = 1 si la página ha sido modificada. La selección de la página que será reemplazada comienza buscando una página que no ha sido referenciada, pero si no la encuentra habrá que reemplazar una página que ha sido referenciada. Si una página ha sido referenciada se comprueba si ha sido modificada o no: Si no ha sido modificada se la reemplaza: o Su reposición representa menos sobrecarga que la de una página modificada, ya que debería grabarse de nuevo en el almacenamientos secundario. Si no se encuentra una página que no ha sido modificada será reemplazada una página modificada. Con el transcurso del tiempo la mayoría de los “bits referenciados” serán activados: Se pierde la capacidad para distinguir las páginas más deseables para ser reemplazadas. Para evitarlo se ajustan periódicamente todos los “bits referenciados” a “0”: o Se logra un nuevo inicio. o Se vuelve vulnerable al reemplazo aún a las páginas activas, pero solo brevemente, mientras se reajustan los bits. Los “bits modificados” no se ajustan periódicamente según esta estrategia. Localidad El concepto de “localidad” expresa [7, Deitel]: “Los procesos tienden a hacer referencia al almacenamiento en patrones no uniformes y muy localizados”. La “localidad” se manifiesta en el “tiempo” y en el “espacio”: Es una propiedad empírica (observada). Nunca está garantizada pero es altamente probable. Ej.: Los procesos tienden a favorecer ciertos subconjuntos de páginas, las que tienden a ser adyacentes entre sí en el espacio de direcciones virtuales del proceso. Está relacionada con la forma en que se escriben los programas y se organizan los datos. “Localidad temporal ”: significa que las localidades de almacenamiento referenciadas recientemente tienen una alta probabilidad de ser referenciadas en un futuro próximo: Se apoya en la utilización de: o Formación de ciclos (loops). o Subrutinas. o Pilas. o Variables usadas para contar y totalizar. “Localidad en el espacio”: significa que las referencias de almacenamiento tienden a acumularse de manera tal que, una vez que se hace referencia a una localidad, es muy probable que las localidades cercanas sean también referenciadas: Se apoya en la utilización de: o Recorrido de arreglos. o Ejecución secuencial de código. o Tendencia de los programadores a colocar definiciones de variables relacionadas, próximas entre sí. Un programa puede ejecutar eficientemente mientras su subconjunto de páginas preferido se encuentre en el almacenamiento primario. El número de fallos de páginas de un proceso depende de la cantidad de almacenamiento primario disponible para sus páginas. Generalmente los procesos no muestran patrones de referencias aleatorios uniformemente distribuidos por sus diferentes páginas. Al reducir el número de marcos (celdas) de páginas disponibles para un proceso existe un intervalo durante el cual la razón de fallos de páginas no se afecta excesivamente. En determinado punto, cuando se reduce más el número de marcos de páginas, el número de fallos de páginas aumenta drásticamente. Mientras el subconjunto de páginas favorecidas por un proceso permanezca en el almacenamiento primario, el número de fallos de páginas no aumenta mucho. Tan pronto como las páginas del subconjunto favorecido son retiradas del almacenamiento primario, la actividad de paginación del proceso aumenta en gran medida al referenciar y traer de nuevo estas páginas al almacenamiento primario. Los “subconjuntos favorecidos” también son llamados “conjuntos de trabajo” o “working sets” (ver Figura 3.35 [7, Deitel]). Inicio: Fin: Conjuntos de Trabajo Denning desarrolló un punto de vista de la actividad de paginación de un programa llamado la “teoría de conjunto de trabajo del comportamiento de un programa” [7, Deitel]. Un “conjunto de trabajo” es una colección de páginas a las cuales un proceso hace activamente referencia. Denning sostenía que para que un programa se ejecutara eficientemente, su conjunto de trabajo debe ser mantenido en el almacenamiento primario, para evitar la “hiperpaginación”. Una “política de administración de almacenamiento por conjunto de trabajo” trata de mantener el conjunto de trabajo de los programas activos en el almacenamiento primario. La decisión de añadir un nuevo proceso al conjunto activo de procesos (aumentar el nivel de multiprogramación): Se basa en si hay suficiente espacio disponible en el almacenamiento primario como para acomodar el conjunto de trabajo del nuevo proceso. Se toma generalmente de forma heurística ya que es imposible para el sistema conocer por anticipado el tamaño del conjunto de trabajo de un proceso dado. El conjunto de trabajo de páginas de un proceso “w(t,w)” en el momento “t” es el conjunto de páginas referidas por un proceso durante el intervalo de tiempo del proceso “t - w” a “t ” (ver Figura 3.36 [7, Deitel]). El “tiempo del proceso” es el tiempo durante el cual este proceso tiene la cpu. La variable “w” se denomina “tamaño de la ventana del conjunto de trabajo”: La determinación del tamaño de “w” es muy importante. Al aumentar el tamaño de la ventana “w” aumenta el tamaño del conjunto de trabajo (ver Figura 3.37 [7, Deitel]). “El verdadero conjunto de trabajo de un proceso es el conjunto de páginas que deben estar en el almacenamiento primario para la ejecución eficaz de este proceso”. Los conjuntos de trabajo cambian mientras un proceso está en ejecución: Complica la administración precisa del almacenamiento primario en base a esta estrategia. “Los conjuntos de trabajo son transitorios y el siguiente conjunto de trabajo del proceso puede diferir substancialmente de su conjunto de trabajo anterior”. Se debe evitar un exceso de compromiso del almacenamiento primario y la consecuente hiperpaginación. http://exa.unne.edu.ar/depar/areas/informatica/SistemasOperativos/SO3.htm#OAA 3.8.3 Paginación por demanda. Paginación por demanda.- Es similar a lo visto para la paginación introduciendo el concepto de swapping. Los procesos residen en el disco y al ser ejecutados deben ser cargados en memoria. Cuando un proceso va a ser ejecutado, el mismo es swappeado a memoria, utilizando lazy swapping. El lazy swapping nunca trae paginas a memoria si no van a ser ejecutadas. Se necesita determinar si un pagina esta en memoria o en disco, por lo cual se utiliza el bit de válido / inválido de la tabla de páginas. Si el bit = 1 la página es valida y esta cargada en memoria si es 0 la página es inválida y no esta cargada en memoria (esta en disco). Cuando un proceso intenta acceder a una página que no esta cargada en memoria ocurre un page fault (tomo de página). El procedimiento para manejar un page fault es el siguiente: 1. Verificar si la referencia a la pagina es valida (se utiliza una tabla interna (generalmente llevada en PCB) donde se indica las paginas validas. 2. Si la referencia no es valida, se cancela la ejecución del proceso. 3. Encontrar un frame disponible para cargarla (la página esta en disco)(por ejemplo de la free frame list) 4. Solicitar operación de I/O para leer la página de disco cargarla en el frame obtenido. 5. Modificar la tabla interna y la tabla de paginas para que ahora esta pagina figure como que esta en memoria. 6. Continuar con la ejecución del proceso en la instrucción en la que fue interrumpido. Paginación por Demanda Las paginas son cargadas por demanda [7, Deitel]. No se llevan páginas del almacenamiento secundario al primario hasta que son referenciadas explícitamente por un proceso en ejecución. Las razones del atractivo de esta estrategia son: Los resultados de computabilidad, en especial el “problema de parada”, indican que el camino que tomará la ejecución de un programa no se puede predecir con exactitud. Garantiza que solo las páginas que necesita el proceso sean traídas al almacenamiento principal. La sobrecarga de proceso para decidir qué página traer al almacenamiento principal es mínima. El principal inconveniente está en los procesos que requieren acumular sus páginas una por una: Los tiempos de espera de páginas son considerables. Es creciente la cantidad de almacenamiento primario afectada al proceso que espera páginas, por lo que el “producto espacio - tiempo” se incrementa. El “producto espacio - tiempo” indica la cantidad de almacenamiento que usa un proceso y la cantidad de tiempo que lo usa. “La reducción del producto espacio - tiempo de las esperas de páginas de un proceso es una meta importante de las estrategias de administración del almacenamiento” (ver Figura 3.38 [7, Deitel]). http://exa.unne.edu.ar/depar/areas/informatica/SistemasOperativos/SO3.htm#OAA 3.8.4 Paginación anticipada. Paginación Anticipada El S. O. intenta predecir las páginas que un proceso va a necesitar y a continuación precarga estas páginas cuando hay espacio disponible [7, Deitel]. Mientras el proceso ejecuta sus páginas actuales, el sistema carga páginas nuevas que estarán disponibles cuando el proceso las pida, debido a ello, el tiempo de ejecución de un proceso se puede reducir. http://exa.unne.edu.ar/depar/areas/informatica/SistemasOperativos/SO3.htm#OAA 3.8.5 Liberación de página. Liberación de Página Un proceso usuario puede emitir una “liberación voluntaria de página” para liberar el marco de página cuando ya no necesitara esa página [7, Deitel]. Se puede eliminar el “desperdicio” y acelerar la ejecución. El inconveniente es que la incorporación de mandatos de liberación de páginas dentro de los programas de usuarios puede ser peligroso y retrasar el desarrollo de aplicaciones. “Los compiladores y S. O. deberían detectar automáticamente situaciones de liberación de página mucho antes de lo que es posible con estrategias de conjuntos de trabajo”. http://exa.unne.edu.ar/depar/areas/informatica/SistemasOperativos/SO3.htm#OAA 3.8.6 Tamaño de página. Tamaño de Página Generalmente el almacenamiento real se divide en marcos o celdas de página de tamaño fijo [7, Deitel]. Los interrogantes tienen que ver con el tamaño de las páginas, si todas las páginas tendrán igual tamaño, si en caso de utilizar páginas de diferente tamaño las páginas mayores deben ser o no múltiplos enteros de las menores, etc. Algunas consideraciones para determinar el tamaño de página son las siguientes: Cuanto más pequeño sea el tamaño de una página, más páginas y marcos de páginas habrá y mayores serán las tablas de páginas: o El desperdicio de almacenamiento debido al tamaño excesivo de las tablas de página se llama “fragmentación de tablas”. o Esto indica la necesidad de páginas más grandes. Con páginas grandes, grandes cantidades de información que nunca llegaría a ser referenciada, se paginarán hacia el almacenamiento primario: o Esto indica la necesidad de páginas más pequeñas. Debido a que las transferencias de e / s del disco (paginación) consumen bastante tiempo, se debe minimizar la paginación que un proceso requiera: o Esto indica la necesidad de páginas grandes. Los programas tienden a mostrar la propiedad de localidad de referencia y esta localidad tiende a ser pequeña: o Esto indica la necesidad de páginas pequeñas. Los procedimientos y datos rara vez comprenden un número entero de páginas, por lo que los sistemas de paginación experimentan una “fragmentación interna”: o El desperdicio promedio es de 1 / 2 página no usada por segmento (grupo) de páginas, que estará en la última página del segmento. o Esto indica la necesidad de páginas pequeñas. Los tamaños de pagina mas utilizados son: 512 b, 1 kb, 2 kb, 4 kb. http://exa.unne.edu.ar/depar/areas/informatica/SistemasOperativos/SO3.htm#OAA Unidad 4 Administración de entrada/salida. 4.5 Dispositivos y manejadores de dispositivos (device drivers). Dispositivos de Entrada - Salida Los dispositivos de entrada salida se dividen, en general, en dos tipos: dispositivos orientados a bloques y dispositivos orientados a caracteres. Los dispositivos orientados a bloques tienen la propiedad de que se pueden direccionar, esto es, el programador puede escribir o leer cualquier bloque del dispositivo realizando primero una operación de posicionamiento sobre el dispositivo. Los dispositivos más comunes orientados a bloques son los discos duros, la memoria, discos compactos y, posiblemente, unidades de cinta. Por otro lado, los dispositivos orientados a caracteres son aquellos que trabajan con secuencias de byes sin importar su longitud ni ningúna agrupación en especial. No son dispositivos direccionables. Ejemplos de estos dispositivos son el teclado, la pantalla o display y las impresoras. La clasificación anterior no es perfecta, porque existen varios dispositivos que generan entrada o salida que no pueden englobarse en esas categorías. Por ejemplo, un reloj que genera pulsos. Sin embargo, aunque existan algunos periféricos que no se puedan categorizar, todos están administrados por el sistema operativo por medio de una parte electrónica - mecánica y una parte de software. Controladores de Dispositivos ( Terminales y Discos Duros) Los controladores de dispositivos (también llamados adaptadores de dispositivos) son la parte electrónica de los periféricos, el cual puede tener la forma de una tarjeta o un circuito impreso integrado a la tarjeta maestra de la computadora. Por ejemplo, existen controladores de discos que se venden por separado y que se insertan en una ranura de la computadora, o existen fabricantes de computadoras que integran esa funcionalidad en la misma tarjeta en que viene la unidad central de procesamiento (tarjeta maestra). Los controladores de dispositivos generalmente trabajan con voltajes de 5 y 12 volts con el dispositivo propiamente, y con la computadora a través de interrupciones. Estas interrupciones viajan por el 'bus' de la computadora y son recibidos por el CPU el cual a su vez pondrá en ejecución algún programa que sabrá qué hacer con esa señal. A ese programa se le llama 'manejador de disposito' (device driver). Algunas veces el mismo controlador contiene un pequeño programa en una memoria de solo lectura o en memoria de acceso aleatoria no volátil y re-escribible que interactúa con el correspondiente manejador en la computadora. En la figura 6.1 se muestra un esquema simple de dispositivos orientados a bloques y otros a caracteres. Por ejemplo, la terminal (CRT) tiene un 'chip' que se encarga de enviar cadenas de bits por medio de un cable serial que a su vez son recibidos por un controlador de puerto serial en la computadora. Este 'chip' también se encarga de leer secuencias de bits que agrupa para su despiegue en la pantalla o para ejecutar algunas funciones de control. Lo importante en todos estos dispositivos es que se debe ejercer un mecanismo para sincronizar el envío y llegada de datos de manera concurrente. Para intercambiar datos o señales entre la computadora y los controladores, muchas veces se usan registros o secciones predefinidas de la memoria de la computadora. A este esquema se le llama 'manejo de entrada - salida mapeado por memoria' (memory mapped I/O). Por ejmplo, para una IBM PC se muestran los vectores de interrupción y las direcciones para la entrada -salida en la tabla 6.1. Controlador Dirección(Hex) Vector de Interrupción Reloj 040 - 043 8 Teclado 060 - 063 9 Disco Duro 320 - 32F 13 Impresora 378 - 37F 15 Monitor Mono 380 - 3BF Monitor Color 3D0 - 3DF Disco Flexible 3F0 - 3F7 14 Tabla 6.1 Direcciones de Mapeo de Entrada - Salida 4.6 Mecanismos y funciones de los manejadores de dispositivos (device drivers). 4.7 Estructuras de datos para manejo de dispositivos. 4.8 Operaciones de Entrada /salida. Unidad 5 Sistema de archivos. 5.9 Concepto. Sistema de Archivos: La estructura de un sistema de archivos es en forma de árbol. El sistema de archivos son los archivos y directorios. Las funciones son crear y eliminar archivos, compartir archivos para intercambiar información, agrupar archivos en forma conveniente al usuario, respaldo y recuperación, el acceso de los usuarios a la información sin la necesidad de conocer la ubicación física (sabiendo solo los nombres simbólicos). Un archivo es un conjunto de información, que se encuentra almacenada o guardada en la memoria principal del computador, en el disco duro, en el disquete flexible o en los discos compactos (Cd-Rom). Antes de que un archivo pueda leerse o escribirse en él, debe abrirse, momento en el cual se verifican los permisos. Estos archivos se abren especificando en el computador la ruta de acceso al archivo desde el directorio raíz, que es la unidad principal del disco del computador, este puede ser un disco duro o disco flexible. Entonces el sistema operativo visualiza el entorno al abrir un archivo. Uno de los problemas mas frecuentes en el manejo de archivos son los deadlock, un deadlock es una situación no deseada de espera indefinida y se da cuando en un grupo de procesos, dos o más procesos de ese grupo esperan por llevar a cabo una tarea que será ejecutada por otro proceso del mismo grupo, entonces se produce el bloqueo. Los bloqueos se dan tanto en los sistemas operativos tradicionales como en los distribuidos, solo que en estos últimos es más difícil de prevenirlos, evitarlos e incluso detectarlos, y si se los logra detectar es muy complicado solucionarlos ya que la información se encuentra dispersa por todo el sistema. Una vez que un deadlock se detecta, es obvio que el sistema está en problemas y lo único que resta por hacer es una de dos cosas: tener algún mecanismo de suspensión o reanudación que permita copiar todo el contexto de un proceso incluyendo valores de memoria y aspecto de los periféricos que esté usando para reanudarlo otro día, o simplemente eliminar un proceso o arrebatarle el recurso, causando para ese proceso la pérdida de datos y tiempo. Funciones del Sistema de Archivos Los usuarios deben poder crear, modificar y borrar archivos. Se deben poder compartir los archivos de una manera cuidadosamente controlada [7, Deitel]. El mecanismo encargado de compartir los archivos debe proporcionar varios tipos de acceso controlado: Ej.: “Acceso de Lectura”, “Acceso de Escritura”, “Acceso de Ejecución”, varias combinaciones de estos, etc. Se debe poder estructurar los archivos de la manera más apropiada a cada aplicación. Los usuarios deben poder ordenar la transferencia de información entre archivos. Se deben proporcionar posibilidades de “respaldo” y “recuperación” para prevenirse contra: La pérdida accidental de información. La destrucción maliciosa de información. Se debe poder referenciar a los archivos mediante “Nombres Simbólicos”, brindando “Independencia de Dispositivos”. En ambientes sensibles, el sistema de archivos debe proporcionar posibilidades de “Cifrado” y “Descifrado”. El sistema de archivos debe brindar una interfase favorable al usuario: Debe suministrar una “visión lógica” de los datos y de las funciones que serán ejecutadas, en vez de una “visión física”. El usuario no debe tener que preocuparse por: o Los dispositivos particulares. o Dónde serán almacenados los datos. o El formato de los datos en los dispositivos. o Los medios físicos de la transferencia de datos hacia y desde los dispositivos. El Sistema de Archivos Un “Archivo” es un conjunto de registros relacionados [23, Tanenbaum]. El “Sistema de Archivos” es un componente importante de un S. O. y suele contener [7, Deitel]: “Métodos de acceso” relacionados con la manera de acceder a los datos almacenados en archivos. “Administración de archivos” referida a la provisión de mecanismos para que los archivos sean almacenados, referenciados, compartidos y asegurados. “Administración del almacenamiento auxiliar” para la asignación de espacio a los archivos en los dispositivos de almacenamiento secundario. “Integridad del archivo” para garantizar la integridad de la información del archivo. El sistema de archivos está relacionado especialmente con la administración del espacio de almacenamiento secundario, fundamentalmente con el almacenamiento de disco. Una forma de organización de un sistema de archivos puede ser la siguiente: Se utiliza una “raíz ” para indicar en qué parte del disco comienza el “directorio raíz ”. El “directorio raíz ” apunta a los “directorios de usuarios”. Un “directorio de usuario” contiene una entrada para cada uno de los archivos del usuario. Cada entrada de archivo apunta al lugar del disco donde está almacenado el archivo referenciado. Los nombres de archivos solo necesitan ser únicos dentro de un directorio de usuario dado. El nombre del sistema para un archivo dado debe ser único para el sistema de archivos. En sistemas de archivo “jerárquicos” el nombre del sistema para un archivo suele estar formado como el “nombre de la trayectoria” del directorio raíz al archivo. http://exa.unne.edu.ar/depar/areas/informatica/SistemasOperativos/SO4.htm 5.10 Noción de archivo real y virtual. Noción de archivo real y virtual. Un archivo virtual, es un archivo de uso temporal que es utilizado por los procesos del sistema mientras se están ejecutando dichos procesos. Estos archivos se crean durante la ejecución de un sistema y los utiliza para el almacenamiento de información, intercambio y organización mientras se ejecuta el sistema, su tamaño es muy variable y terminan al detener la ejecución del sistema, muchos de ellos son borrados, por ejemplo, los archivos *.tmp Archivo Real: Es un objeto que contiene programas, datos o cualquier otro elemento. En UNIX se define un File System como un sistema de software dedicado a la creación, destrucción, organización y lectura, escritura y control de acceso de los archivos, funcionalmente los componentes de un sistema de archivos son lenguajes de comandos, interpretador de comandos, manejador del almacenamiento secundario, sistema de entrada y salida y mecanismos de respaldo y recuperación. http://eduadis.itlapiedad.edu.mx/~hocegueras/so2/so2_42.html Archivos Se considerará el punto de vista del usuario. Nombre de los Archivos Las reglas exactas para los nombres de archivos varían de sistema a sistema [23, Tanenbaum]. Algunos sistemas de archivos distinguen entre las letras mayúsculas y minúsculas, mientras que otros no. Muchos S. O. utilizan nombres de archivo con dos partes, separadas por un punto: La parte posterior al punto es la extensión de archivo y generalmente indica algo relativo al archivo, aunque las extensiones suelen ser meras convenciones. Estructura de un Archivo Los archivos se pueden estructurar de varias maneras, las más comunes son [23, Tanenbaum]: “Secuencia de bytes”: o El archivo es una serie no estructurada de bytes. o Posee máxima flexibilidad. o El S. O. no ayuda pero tampoco estorba. “Secuencia de registros”: o El archivo es una secuencia de registros de longitud fija, cada uno con su propia estructura interna. “Árbol ”: o El archivo consta de un árbol de registros, no necesariamente de la misma longitud. o Cada registro tiene un campo key (llave o clave) en una posición fija del registro. o El árbol se ordena mediante el campo de clave para permitir una rápida búsqueda de una clave particular. Tipos de Archivos Muchos S. O. soportan varios tipos de archivos, por ej.: archivos regulares, directorios, archivos especiales de caracteres, archivos especiales de bloques, etc., donde [23, Tanenbaum]: Los Archivos Regulares son aquellos que contienen información del usuario. Los Directorios son archivos de sistema para el mantenimiento de una estructura del sistema de archivos. Los Archivos Especiales de Caracteres: o Tienen relación con la e / s. o Se utilizan para modelar dispositivos seriales de e / s (terminales, impresoras, redes, etc.). Los Archivos Especiales de Bloques se utilizan para modelar discos. Acceso a un Archivo Los tipos de acceso más conocidos son: Acceso Secuencial: el proceso lee en orden todos los registros del archivo comenzando por el principio, sin poder: o Saltar registros. o Leer en otro orden. Acceso Aleatorio: el proceso puede leer los registros en cualquier orden utilizando dos métodos para determinar el punto de inicio de la lectura: o Cada operación de lectura (read) da la posición en el archivo con la cual iniciar. o Una operación especial (seek) establece la posición de trabajo pudiendo luego leerse el archivo secuencialmente. Atributos de Archivo Cada archivo tiene: Su nombre y datos. Elementos adicionales llamados atributos, que varían considerablemente de sistema a sistema. Algunos de los posibles atributos de archivo son [23, Tanenbaum]: “Protección”: quién debe tener acceso y de qué forma. “Contraseña”: contraseña necesaria para acceder al archivo. “Creador”: identificador de la persona que creó el archivo. “Propietario”: propietario actual. “Bandera exclusivo - para - lectura”: 0 lectura / escritura, 1 para lectura exclusivamente. “Bandera de ocultamiento”: 0 normal, 1 para no exhibirse en listas. “Bandera de sistema”: 0 archivo normal, 1 archivo de sistema. “Bandera de biblioteca”: 0 ya se ha respaldado, 1 necesita respaldo. “Bandera ascii / binario”: 0 archivo en ascii, 1 archivo en binario. “Bandera de acceso aleatorio”: 0 solo acceso secuencial, 1 acceso aleatorio. “Bandera temporal”: 0 normal, 1 eliminar al salir del proceso. “Banderas de cerradura”: 0 no bloqueado, distinto de 0 bloqueado. “Longitud del registro”: número de bytes en un registro. “Posición de la llave”: ajuste de la llave dentro de cada registro. “Longitud de la llave”: número de bytes en el campo llave. “Tiempo de creación”: fecha y hora de creación del archivo. “Tiempo del último acceso”: fecha y hora del último acceso al archivo. “Tiempo de la última modificación”: fecha y hora de la última modificación al archivo. “Tamaño actual”: número de bytes en el archivo. “Tamaño máximo”: tamaño máximo al que puede crecer el archivo. Operaciones con Archivos Las llamadas más comunes al sistema relacionadas con los archivos son [23, Tanenbaum]: Create (crear): el archivo se crea sin datos. Delete (eliminar): si el archivo ya no es necesario debe eliminarse para liberar espacio en disco. Ciertos S. O. eliminan automáticamente un archivo no utilizado durante “n” días. Open (abrir): antes de utilizar un archivo, un proceso debe abrirlo. La finalidad es permitir que el sistema traslade los atributos y la lista de direcciones en disco a la memoria principal para un rápido acceso en llamadas posteriores. Close (cerrar): cuando concluyen los accesos, los atributos y direcciones del disco ya no son necesarios, por lo que el archivo debe cerrarse y liberar la tabla de espacio interno. Read (leer): los datos se leen del archivo; quien hace la llamada debe especificar la cantidad de datos necesarios y proporcionar un buffer para colocarlos. Write (escribir): los datos se escriben en el archivo, en la posición actual. El tamaño del archivo puede aumentar (agregado de registros) o no (actualización de registros). Append (añadir): es una forma restringida de “write”. Solo puede añadir datos al final del archivo. Seek (buscar): especifica el punto donde posicionarse. Cambia la posición del apuntador a la posición activa en cierto lugar del archivo. Get attributes (obtener atributos): permite a los procesos obtener los atributos del archivo. Set attributes (establecer atributos): algunos atributos pueden ser determinados por el usuario y modificados luego de la creación del archivo. La información relativa al modo de protección y la mayoría de las banderas son un ejemplo obvio. Rename (cambiar de nombre): permite modificar el nombre de un archivo ya existente. Archivos Mapeados a Memoria Algunos S. O. permiten asociar los archivos con un espacio de direcciones de un proceso en ejecución [23, Tanenbaum]. Se utilizan las llamadas al sistema “map” y “unmap”: “Map”: utiliza un nombre de archivo y una dirección virtual y hace que el S. O. asocie al archivo con la dirección virtual en el espacio de direcciones, por lo cual las lecturas o escrituras de las áreas de memoria asociadas al archivo se efectúan también sobre el archivo mapeado. “Unmap”: elimina los archivos del espacio de direcciones y concluye la operación de asociación. El mapeo de archivos elimina la necesidad de programar la e / s directamente, facilitando la programación. Los principales problemas relacionados son: Imposibilidad de conocer a priori la longitud del archivo de salida, el que podría superar a la memoria. Dificultad para compartir los archivos mapeados evitando inconsistencias, ya que las modificaciones hechas en las páginas no se verán reflejadas en el disco hasta que dichas páginas sean eliminadas de la memoria. http://exa.unne.edu.ar/depar/areas/informatica/SistemasOperativos/SO4.htm 5.11 Componentes de un sistema de archivos. COMPONENTE DE UN SISTEMA DE ARCHIVO EL SISTEMA DE ARCHIVOS DE UN SISTEMA OPERATIVO. Lo conforman todas aquellas rutinas encargadas de administrar todos los aspectos relacionados con el manejo de Archivos. COMPONENTES DEL SISTEMA DE ARCHIVOS. En general, un Sistema de Archivos está compuesto por: Métodos De Acceso, Administración De Archivos, Administración De Almacenamiento Secundario, Mecanismos De Integridad. Métodos De Acceso. Se ocupan de la manera en que se tendrá acceso a la información almacenada en el archivo. Ejemplo: Secuencial, Directo, indexado, etc. Administración De Archivos. Se ocupa de ofrecer los mecanismos para almacenar, compartir y asegurar archivos, así como para hacer referencia a ellos. Administración De Almacenamiento Secundario. Se ocupa de asignar espacio para los archivos en los dispositivos de almacenamiento secundario. Mecanismos De Integridad. Se ocupan de garantizar que no se corrompa la información de un archivo, de tal manera que solo la información que deba estar en el, se encuentre ahí. Componentes de un sistema de archivos. 1º 2º 3º 4º 5º 6º MECANISMOS DE ORGANIZACION LOGICA DIRECTORIO DE IDENTIFICADORES SISTEMAS TEORICOS DE ARCHIVOS MECANISMOS DE ORGANIZACION FISICA MECANISMOS DE E/S SCHEDULING E/S Reg. lógico Reg. físico Figura # 1. Componentes, niveles de un sistema de archivos. 1. Contiene las diferentes rutinas y comandos atravéz de los cuales el usuario podrá estructurar sus archivos virtuales. 2. Convierte los identificadores simbólicos de los archivos en identificadores internos, los cuales apuntarán a su descriptor o a una estructura que permite encontrar el archivo. 3. Su objetivo es el de activar y desactivar a través de las rutinas de abrir y cerrar archivos y verifica el modo de acceso. 4. Traslada las direcciones lógicas en direcciones físicas correspondientes a las estructuras de memoria secundaria y los buffers en memoria principal necesarios para la transferencia de datos. 5. Por cada petición de acceso al archivo real, este mecanismo genera la secuencia de operaciones elementales de entrada y salida que se necesita. 6. En este nivel es donde se tiene el número de peticiones pendientes así como de las que se están realizando y lleva el control y asignación de tiempo de CPU a las diferentes peticiones de E/S. http://eduadis.itlapiedad.edu.mx/~hocegueras/so2/so2_43.html 5.12 Organización lógica y física. ORGANIZACIÓN LOGICA Y FISICA ORGANIZACIÓN DE ARCHIVOS Se refiere a las diferentes maneras en las que puede ser organizada la información de los archivos, así como las diferentes maneras en que ésta puede ser accesada. Dado que hay 2 niveles de visión de los archivos (físico y lógico), se puede hablar también de 2 aspectos de organización de archivos: Organización de archivos lógicos y de archivos físicos. DE ARCHIVOS LOGICOS. Contempla la organización desde el punto de vista lógico. Por ejemplo, secuencial, directo, etc. DE ARCHIVOS FISICOS. Contempla la administración de archivos desde la perspectiva física, particularmente la organización del almacenamiento en disco a nivel de pistas y sectores. Este tipo de organización muestra a su vez, 2 aspectos importantes: Métodos De Asignación De Espacio Libre y Asignación De Espacio De Almacenamiento Del Archivo. Organización lógica y física. La organización de archivos es de dos tipos lógica y física. Organización lógica, existen tres organizaciones comunes de un archivo. La primera es una simple secuencia de bytes. Figura # 2. 1 Byte Los archivos de UNIX se estructuran de esta manera. La segunda es una sucesión de registros de tamaño fijo. 1 Registro Pueden leerse o escribirse registros arbitrarios, pero no pueden insertarse o suprimirse registros a la mitad de un archivo. La tercera organización es un árbol de bloques de disco, donde cada cavidad contiene n registros con clave. Los registros pueden cerrarse por clave y pueden insertarse otros en cualquier parte del árbol. Hormiga Zorra Cerdo Gato Vaca Perro Gallina Cabra León Búho Ibis Cordero Pony Rata Gusano Figura # 2. Organización de archivos Si se agrega un registro a un bloque que está repleto, éste se divide en su secuencia alfabética correcta. Este método se aplica en muchas macrocomputadoras, donde se llaman ISAM (método de acceso secuencia indizado). La organización física es llevada a cabo en un sistema por medio de Directorios. Para llevar el control de los archivos, el sistema de archivos proporciona directorios, los cuales en muchos sistemas, son archivos. Un directorio suele tener varias entradas, una por archivo. Figura # 3. Directorio Entrada Entrada Entrada Entrada Figura # 3. Información acerca de cada Nombre del archivo archivo Tipo de archivo Propietario Información de protección Conteo de uso Tiempo de creación Tiempo de la última modificación Lista de bloques del disco que se usan Un directorio puede tener varias entradas, donde cada un describe un archivo. Las entradas pueden contener cierta información acerca del archivo o bien apuntar a otras estructuras que la tengan. La manera más simple consiste en que el sistema conserve un solo directorio que contenga todos los archivos de todos los usuarios. Si hay muchos usuarios y éstos eligen los mismos nombres de archivos (por ejemplo, mail y games), habrá conflictos y la confusión volverán el sistema impracticable. Este modelo de sistema es utilizado solamente por los sistemas operativos de microcomputadoras más primitivos. Una mejora a la idea de tener un solo directorio para todos los archivos consiste en tener un directorio por usuario. Figura # 4. Directorio Raíz A A B A B Directorio del usuario C C C C Archivo Figura # 4. Un directorio por usuario. Este método elimina conflictos de nombre entre los usuarios, pero no es muy satisfactorio para usuarios con muchos archivos. Es necesaria una jerarquía general (o sea, un árbol de directorios). Con este método, cada usuario puede tener tantos directorios como se necesiten de manera que los archivos se puedan agrupar en formas naturales. Cuando el sistema de archivos se organiza como un árbol de directorios, se necesita contar con alguna manera de especificar nombres de archivos. Comúnmente se emplean dos métodos: Nombre de ruta absoluta. Que consta de la ruta que va del directorio raíz al archivo. Ejem: La ruta /usr/ast/mailbox el directorio raíz contiene un subdirectorio usr el cual contiene un subdirectorio ast, que contiene el archivo mailbox. Los nombres de ruta absoluta siempre comienzan en el directorio raíz y son únicos. Nombre de ruta relativa. Se utiliza junto con el concepto directorio de trabajo (ó directorio actual). Un usuario puede designar un directorio como el directorio de trabajo actual. En UNIX, todos los nombres de ruta que comienzan con una diagonal / son absolutos; todos los otros son relativos al directorio de trabajo actual del usuario. Si el directorio de trabajo actual es /usr/ast/mailbox puede referirse simplemente como mailbox. http://eduadis.itlapiedad.edu.mx/~hocegueras/so2/so2_44.html 5.13 Mecanismos de acceso a los archivos. Mecanismos de acceso a los archivos. Existen varios mecanismos para accesar los archivos: Directorios, descriptores de archivos, mecanismos de control de acceso y procedimientos para abrir y cerrar archivos. Descriptores de archivos. A cada uno de los archivos se le asigna un descriptor el cual contendrá toda la información que necesitará el sistema de archivos para ejecutar con él los comandos que se le soliciten. El descriptor se mantendrá en memoria principal desde que el archivo es abierto hasta que sea cerrado, y debe tener al menos la siguiente información, identificación del archivo, lugar de almacenamiento, información del modo de acceso. Identificación del archivo consiste de dos partes que es el nombre simbólico que es el que le da el usuario y un identificador interno que es asignado por el sistema operativo (número). Lugar de almacenamiento así como el tamaño del archivo. Modo de acceso. Se debe indicar en forma explícita quien puede accesar el archivo y conque derecho. El sistema de archivos es un componente importante de cualquier sistema operativo, en general contienen: Métodos de acceso: Se ocupan de la forma en que se obtiene acceso a los datos almacenados en archivos. Administración de archivo. Se ocupa de ofrecer los mecanismos para almacenar, compartir y asegurar archivos, y hacer referencia a ellos. Administración de almacenamiento secundario: Se ocupa de asignar espacio a los archivos en dispositivos de almacenamiento secundario. Mecanismos de integridad de los archivos: Se ocupan de garantizar que no se corrompa la información en un archivo. Cuando se asegura la integridad de los archivos, cualquier información que debe estar en un archivo estará ahí, la información que no deba estar en un archivo se mantiene fuera de él. http://eduadis.itlapiedad.edu.mx/~hocegueras/so2/so2_45.html 5.14 Manejo de espacio en memoria secundaria. Manejo del espacio de memoria secundaria. El sistema de archivos se ocupa primordialmente de administrar el espacio de almacenamiento secundario, sobre todo el espacio en disco. El manejo del espacio libre en disco se lleva a cabo de la siguiente manera: Vector de bits Lista ligada (lista libre) Por conteo (agrupación) Vector de bits. El espacio libre en disco es frecuentemente implementado como un mapa de bits, donde cada blokc es representado por un bit y si el bloc es libre el bit es cero de lo contrario está asignado. 11000111 Lista ligada. Una lista ligada de todos los blocks libres. Otra implantación se consigue guardando la dirección del primer block libre y el número de los blocks libres contiguos que le siguen. Cada entrada de la lista de espacio libre consiste de una dirección de disco y un contador (por conteo), ver figura # 5. Bloc libre de inicio Nº de block contiguos (2,2 y 4) 2 3 Figura # 5. Lista ligada. Por agrupación. Se almacena la dirección en n blocks libres en el primer block libre y el último contiene la dirección de otro block que contiene la dirección de otros blocks libres, ver figura # 6. Figura # 6. Agrupación. Para manejar los espacios en disco existen los siguientes métodos: Contiguos Ligados Indexados Contiguos. Esta asignación requiere que cada archivo ocupe un conjunto de direcciones contiguas en el disco, su asignación es definida por la dirección del primer bloc y la longitud del archivo. Asignación ligada. Cada archivo es una lista ligada de blocks y el directorio contiene un apuntador al primer bloc y al último. Figura # 7. Nombre A 1 Acceso 50 Inicio 1 Secuencial Sí Directo No Final 50 NOTA: - Lento - Evita la compactación Figura # 7. Asignación ligada. Asignación Indexada. Cada archivo tiene su propio bloc de índice el cual es un arreglo de direcciones de bloc En un sistema de cómputo, los elementos que se declaran para almacenamiento son los Fyle System. Cuándo existe una solicitud de almacenamiento o manejo de bloc libres en un file system surge una interrogante ¿cómo atenderlas? esto se lleva a cabo mediante una planificación de discos y para esto existen las siguientes políticas de planificación. a) FCFS b) SSTF b) SCAN c) SCAN de n-pasos d) C-SCAN f) Esquema Eschenbach http://eduadis.itlapiedad.edu.mx/~hocegueras/so2/so2_46.html 5.15 Modelo jerárquico. 5.16 Mecanismos de recuperación en caso de falla. Mecanismos de recuperación en caso de fallos. La perdida de la información es uno de los factores que se le debe de dar mayor importancia, por la sencilla razón de que al perder información se puede perder lo que no nos podemos imaginar en cuanto a la misma y ocasionar perdidas hasta hablar de una gran cantidad de dinero. Para solucionar este o estos problemas todo sistema operativo cuenta con al menos una herramienta de software que nos permite recuperar información perdida hasta cierta medida, esto obedece de acuerdo al daño causado o los daños. Si el sistema no cuenta con la herramienta necesaria, deberá adquirirse el software apropiado de algún fabricante especializado en el ramo, por ejemplo Norton. http://eduadis.itlapiedad.edu.mx/~hocegueras/so2/so2_48.html Unidad 6 Protección y seguridad. 6.1 Concepto y objetivos de protección. Proteccion.- Refiere a los mecanismo para controlar el acceso de programas, usuarios o proceso a los recursos definido en el sistema. Un sistema es un conjunto de recursos (CPU, memoria, impresoras, etc.) en donde cada objeto o recurso tiene un nombre único. Las operaciones que se pueden hacer sobre cada objeto dependen del objeto. Dominios de proteccion.- Cada proceso opera dentro de su dominio de protección, que indica las operaciones que el proceso puede hacer sobre un determinado conjunto de objetos. La habilidad de un proceso de ejecutar una operación sobre un objeto se denomina derecho (acces right). Un dominio es un conjunto de derechos cada uno de los cuales es un par ordenado <objeto, lista de derechos> Un dominio puede estar definido de varias formas: Un usuario es un dominio. El conjunto de objetos que pueden ser accedidos dependen de la identidad del usuario. Un proceso es un domino. El conjunto de objetos que pueden ser accedidos dependen de la identidad del proceso. Un procedimiento es un dominio. Protección La aparición de la multiprogramación introdujo en los computadores la posibilidad de compartir recursos entre varios usuarios. Entre los recursos compartidos están la CPU, la memoria, los dispositivos de entrada/salida, los programas y los datos. El hecho de poder compartir recursos es lo que introdujo la necesidad de protección. Existen varios motivos por lo que la protección es necesaria. El más obvio es la necesidad de prevenir intentos de violación de restricciones de acceso por parte de un usuario. El más importante es, sin embargo, la necesidad de asegurar que cada proceso use los recursos del sistema de forma consistente de acuerdo con las políticas establecidas para el uso de esos recursos. Este requisito es fundamental para que un sistema sea fiable. El papel de la protección en un sistema informático es proporcionar un conjunto de mecanismos que permita llevar a cabo las políticas que gobiernan el uso de los recursos. Estas políticas pueden ser fijas, establecidas en el diseño del sistema operativo, pueden ser formuladas por el administrador del sistema, o incluso puede ser establecidas por los usuarios. Un principio importante es la separación entre política y mecanismo. Los mecanismos determinan hacer cierta cosa, mientras que las políticas deciden es lo que hay que hacer. En el ámbito de la protección, la política define qué datos han de ser protegidos y el mecanismo la forma de llevar a cabo la política. Esta separación favorece la flexibilidad. Debido a que las políticas pueden cambiar con el tiempo o con el lugar, es deseable que el sistema operativo ofrezca un conjunto general de mecanismos por medio de los cuales se puedan establecer políticas diferentes. 3.4.1 Dominios de Protección. Un computador contiene un conjunto de objetos que han de ser protegidos. Estos objetos pueden ser tanto hardware (CPUs, segmentos de memoria, discos, impresoras, etc.) como software (procesos, ficheros, semáforos, etc.). Cada objeto tiene un identificador único en el sistema y un conjunto de operaciones que le pueden ser aplicadas. Las operaciones posibles dependen del objeto. Por ejemplo, los segmentos de memoria pueden ser leídos o escritos, mientras que un fichero puede ser creado, abierto, leído, escrito, cerrado y borrado. El mecanismo de protección ha de prohibir a los procesos el acceso a aquellos objetos. Para estudiar los diferentes mecanismos de protección se introduce el concepto de dominio de protección. Un dominio de protección es un conjunto de pares objeto-derechos, de forma que cada par especifica un objeto y algún subconjunto de operaciones que se pueden realizar sobre dicho objeto. Figura #. 7 Ejemplos de dominio de protección. En cada instante de tiempo, cada proceso se ejecuta dentro de un dominio concreto. Este dominio puede cambiar durante la vida del proceso. Un dominio puede ser varias cosas: Cada usuario puede ser un dominio, en cuyo caso el conjunto de objetos que puede ser accedido depende de la identidad del usuario. Los cambios de dominio ocurren cuando se cambia de usuario. Cada proceso puede ser un dominio, en cuyo caso el conjunto de objetos que puede ser accedido depende de la identidad del proceso. Los cambios de dominio se producen cuando un proceso envía un mensaje a otro y espera la respuesta. Cada procedimiento puede ser un dominio, en cuyo caso el conjunto de objetos que puede ser accedido se corresponde con las variables locales definidas dentro del procedimiento. Los cambios de dominio se producen cuando se realiza una llamada a procedimiento. En UNIX el dominio de un proceso lo determina su uid y su gid. Dado un par de estos dos identificadores, es posible obtener un lista de todos los objetos que puede utilizar, y si pueden ser accedidos para lectura, escritura y/o ejecución. Además, en UNIX cada proceso tiene dos partes, la parte de usuario y la parte de núcleo. Cuando un proceso invoca una llamada al sistema pasa a ejecutarse en modo núcleo. Este cambio de modo de ejecución da lugar a un cambio de dominio. Cuando un proceso UNIX realiza una llamada exec() sobre un fichero que tiene uno de los bits SETUID o SETGID a uno adquiere un nuevo uid o gid efectivo. Esto también provoca un cambio de dominio. El sistema operativo debe de conocer en todo momento los objetos que pertenecen a cada dominio. Una forma de llevar este control es tener una matriz de acceso, en la que las filas son los dominios y las columnas los objetos. Cada elemento de la matriz muestra los derechos de un dominio sobre un objeto. Figura #. 8 Ejemplo de matriz de acceso. Los cambios de dominio se pueden incluir fácilmente en la matriz de protección considerando que cada dominio es a su vez un objeto sobre el que existe una operación que permite entrar en él. Figura #. 9 Matriz de acceso con dominio. En la práctica no es viable almacenar la matriz de protección porque es grande y tiene muchos huecos (sparse matrix). La mayoría de los dominios no tiene acceso a la mayoría de los objetos, por lo que almacenar una gran matriz casi vacía desperdicia mucho espacio en disco. Dos soluciones prácticas consisten en almacenar la matriz, bien por filas, bien por columnas, y almacenar únicamente los elementos no vacíos. En el primer caso se habla de capacidades, y en el segundo, de listas de control de acceso. 3.4.2 Listas de Control de Acceso. Cuando la matriz se almacena por columnas, a cada objeto se le asocia una lista ordenada que contiene todos los dominios que pueden acceder al objeto y la forma de hacerlo. Esta lista se denomina lista de control de acceso (control access list o ACL). En UNIX esta lista está compuesta por tres grupos de tres bits, especificando cada grupo los permisos para el propietario, grupo y resto de usuarios, y los tres bits indican si existe permiso de lectura, escritura y/o ejecución. Sin embargo, un esquema basado en listas de control de acceso puede ser más general: El propietario de un objeto puede modificar la lista de control de acceso del mismo. El único problema es que los cambios pueden no afectar a los usuarios que ya estén usando el objeto. 3.4.3 Capacidades La otra forma de almacenar la matriz de protección es por filas. Con este método, cada proceso tiene una lista de los objetos a los que puede acceder así como una indicación de las operaciones que están permitidas sobre cada uno de ellos. Esta lista se denomina lista de capacidades (listas_C o C_lists), y cada elemento de la lista se llama capacidad. Cada objeto está representado por una capacidad. Cuando un proceso quiere ejecutar una operación sobre un objeto, ha de especificar la capacidad del objeto como parámetro. La simple posesión de la capacidad permite que se conceda el acceso (siempre que éste esté permitido sobre el objeto). Cada capacidad tiene un campo que indica el tipo del objeto, un campo de derechos de acceso, y un campo que identifica al objeto. Figura #. 10 Lista de capacidades para el dominio 2 de la figura 8. Las listas de capacidades se asocian a un dominio, pero los procesos que se ejecutan en ese dominio no deben de acceder a la lista de forma directa. Por el contrario, cada capacidad es un objeto protegido que debe ser gestionado por el sistema operativo y únicamente puede ser accedido de forma indirecta por parte de los procesos. Generalmente, suelen ser referenciadas por su posición dentro de la lista de capacidades. Las listas de capacidades son también objetos, por lo que pueden ser apuntadas desde otras listas, permitiendo el compartir subdominios. Para proporcionar protección, las capacidades se han de distinguir de otro tipos de objetos. Cada objeto tiene asociado una etiqueta que indica si se trata de un objeto o de una capacidad. Las etiquetas no deben ser accesibles directamente por los programas de aplicación. Una solución hardware consiste en añadir a cada palabra de memoria un bit adicional que indica si la palabra de memoria contiene una capacidad. Este bit sólo se puede ser modificado por el sistema operativo. Si se añaden más bits, el hardware podrá conocer los tipos de los objetos (si son enteros, reales). Dividir el espacio de direcciones de un programa en dos zonas. La primera es accesible al programa y contiene las instrucciones y los datos. La segunda contiene la lista de capacidades y es accesible únicamente por el sistema operativo. Mantener las capacidades en el espacio de usuario, pero encriptadas con una clave secreta desconocida para el usuario. Este método es empleado por el sistema operativo Amoeba. Se tienen acceso relativos a cada objeto, las capacidades tienen permisos genéricos que son aplicables a todos los objetos. Algunos de estos permisos son: Copiar capacidad: crear una nueva capacidad para el mismo objeto. Copiar objeto: Crear un objeto duplicado con una nueva capacidad. Eliminar capacidad: borrar de forma permanente una entrada de la lista_C, pero dejando inalterado al objeto. Eliminar objeto: eliminar de forma permanente un objeto y su capacidad. Los sistemas basados en capacidades se suelen organizar como una colección de módulos, siendo cada módulo un gestor para cada tipo de objeto. Por ejemplo, las operaciones sobre ficheros se envían al gestor de ficheros, mientras que las que tiene que ver con memoria se envían al gestor de memoria. Cada operación va acompañada de la capacidad correspondiente. Un problema que tiene este esquema basado en módulos gestores es que éstos son, a su vez, programas ordinarios. Pongámonos en el caso de un gestor de ficheros. Las capacidades asociadas a ficheros permiten a los programas las operaciones típicas sobre éstos (apertura, lectura, etc.). Sin embargo, el gestor de ficheros ha de ser capaz de acceder a la representación interna de los ficheros (en UNIX, por ejemplo, habría que acceder a los nodos índice). Por lo tanto, es esencial que los módulos gestores tengan más atribuciones de las que las capacidades permiten a los procesos ordinarios. Este problema se resuelve en el sistema Hydra mediante una técnica llamada amplificación de derechos, que consiste en que a los módulos gestores se les asigna una plantilla de permisos que les permiten obtener más derechos sobre los objetos de los que les permiten las capacidades. Un problema que se presentan en los sistemas basados en capacidades es que es difícil revocar los accesos a un objeto, ya que ello supone localizar todas las capacidades que hacen referencia al objeto, y éstas se encuentran en las listas de capacidades, que se encuentran repartidas por todo el disco. Una solución a este problema consiste en que una capacidad no apunte al objeto en sí, sino a un objeto indirecto que apunta al objeto. De esta forma, si se quiere prohibir los accesos, basta con romper el enlace entre el objeto indirecto y el objeto. Otra posibilidad consiste en asociar a cada objeto un número aleatorio, que también está presente en la capacidad. Cuando se presenta una capacidad al solicitar un acceso, los dos números son comparados y el acceso se permite si la comparación ha tenido éxito. La forma de revocar los accesos consiste en que el propietario del objeto puede solicitar que el número aleatorio del objeto sea cambiado, lo que automáticamente invalida el resto de las capacidades. http://eduadis.itlapiedad.edu.mx/~hocegueras/so2/so2_34.html 6.2 Funciones del sistema de protección. FUNCIONES DE UN SISTEMA DE PROTECCIÓN. Dado que los sistemas de computo se han venido haciendo cada vez más sofisticados en sus aplicaciones, la necesidad de proteger su integridad, también ha crecido. Los aspectos principales de protección en un Sistema Operativo son: 1. Protección de los procesos del sistema contra los procesos de usuario. 2. Protección de los procesos de usuario contra los de otros procesos de usuario. 3. Protección de Memoria. 4. Protección de los dispositivos. Funciones de un sistema de protección. Dado que los sistemas de cómputo se han venido haciendo cada vez más sofisticados en sus aplicaciones, la necesidad de proteger su integridad, también ha crecido. Los aspectos principales de protección en un Sistema Operativo son: 1. 2. 3. 4. Protección de los procesos del sistema contra los procesos de usuario. Protección de los procesos de usuario contra los de otros procesos de usuario. Protección de Memoria. Protección de los dispositivos. Protección = Control de empleo de la información + Recursos FUNCIONES: Las funciones de un sistema de protección son asegurar la independencia entre objetos que lógicamente son independientes y la de asegurar el control de acceso a la información y puede ser control asociado al tipo de información o puede ser el control asociado al usuario que solicita el acceso. Todos los mecanismos dirigidos a asegurar el sistema informático, siendo el propio sistema el que controla dichos mecanismos, se engloban en lo que podemos denominar seguridad interna. Seguridad del procesador Los mecanismos de protección de procesador son: Estados protegidos (kernel) o no protegidos (usuarios). Reloj hardware para evitar el bloqueo del procesador. Seguridad de la memoria Se trata de mecanismos para evitar que un usuario acceda la información. Entre ellos citaremos dos: Registros límites o frontera. Estado protegido y no protegido del procesador. Además se emplean para la memoria métodos como el de utilizar un bit de paridad o el checksum. Bit de paridad. Consiste en añadir un bit a cada octeto o palabra que se transmita para con él conseguir que la suma de unos sea par (paridad par) o impar (paridad impar). Con este método se detectan errores al variar un bit o un número impar de ellos sin que se detecten variaciones de un número par de bits. Si se prevé que los daños esperados en una transmisión no sean de un bit en un octeto o palabra, sino en una secuencia de ellos, se puede utilizar un algoritmo que permita realizar una suma denominada suma de chequeo (checksum) y aplicar el método denominado de redundancia cíclica durante la transmisión, de tal forma que al terminar éste se repite con el destino el mismo algoritmo de suma, comprobándose si el valor final de la suma es el mismo. Seguridad de los archivos La finalidad principal de las computadoras es el del tratamiento de la información que se almacena permanentemente en los archivos. La pérdida o alteración no deseada de la información causa trastornos irreparables en algunos casos. Por eso es necesario tomar medidas de seguridad que se deben enfocar desde dos aspectos diferentes: La disponibilidad y la privacidad de los archivos. 1) Disponibilidad de los archivos Un archivo debe tener la información prevista y estar disponible en el momento que un usuario la necesite. Se debe de tener presente la necesidad de asegurar las circunstancias y se deben realizar las siguientes acciones: .Copias de seguridad (Backup). Consiste en que cada cierto tiempo (hora, día, semana ...) se realice una copia del contenido de los archivos, de forma que si se destruyen éstos, es posible la recuperación de los datos a partir de la última de las copias. La operación de realizar las copias y la recuperación a partir de las mismas, se realizan por medio de programas de utilidad del sistema operativo. .Archivos log. Se usan en sistemas de tiempo compartido, con muchos usuarios trabajando simultáneamente, en estos sistemas se recurre a archivos auxiliares donde se registran todas las operaciones que realiza un usuario sobre sus archivos, almacenándose la nueva información o aquella que difiere de la ya existente. Estos archivos reciben el nombre de archivos log y son tratados por utilidades del sistema operativo conjuntamente con las copias de seguridad para los procesos de recuperación. Esta segunda técnica permite asegurar la consistencia del contenido de los archivos ante caídas inesperadas del sistema, evitando que una información se quede a medias de escribir. Para solucionar problemas de consistencia, algunos sistemas no dan la operación de escritura por realizada hasta que no se refleja en el log, y esto se hace una vez confirmada la escritura en el disco. Al volver a arrancar, el sistema inspecciona el log buscando operaciones iniciadas y no acabadas, finalizándolas antes de permitir de nuevo el trabajo de los usuarios. 2) Privacidad de los archivos Los archivos se deben proteger de posibles accesos no deseados, el sistema de protección debe permitir acceso de forma controlada, según reglas definidas y con las siguiente autorización: * Cada usuario, al comenzar la sesión en un sistema tras su identificación, tiene asignado por el sistema de protección un dominio compuesto de una serie de recursos y de operaciones permitidas, por ejemplo, una serie de archivos a los que acceden, no teniendo permitido el acceso al resto de archivos. En general, los sistemas operativos almacenan la información relativa a los dominios en los que se denomina matriz de dominios, cuyas filas indican los dominios existentes y las columnas los recursos. Cada elemento de la matriz indica el derecho a utilizar el recurso correspondiente en el dominio. Figura # 2. D1 D2 D3 A1 E A2 L A3 A4 L L,E A5 A6 I S E E E L L Figura # 2. Matriz de acceso. http://eduadis.itlapiedad.edu.mx/~hocegueras/so2/so2_32.html 6.3 Implantación de matrices de acceso. Matriz de Acceso.- El modelo de protección puede ser visto mediante una matriz de acceso. Las filas representan dominios y las columnas representan objetos. Las entradas de la matriz representan el conjunto de derechos para el objeto en cuestión, para determinado dominio. IMPLANTACION DE MATRICES CON DERECHOS DE ACCESO. Un modelo de protección puede ser visto abstractamente como una matriz, llamada matriz de derecho. Los renglones de la matriz representan dominios y las columnas representan objetos. Cada entrada en la matriz contiene un conjunto de derechos de acceso. Dado que los objetos son definidos explícitamente por la columna, se puede omitir el nombre del objeto en el derecho de acceso. La entrada "Matriz[i, j]" define el conjunto de operaciones que un proceso ejecutándose en el dominio "Dj" puede realizar sobre el objeto "Oj". Hay 4 dominios y 5 objetos: 3 Archivos ("A1", "A2", "A3") 1 Puerto Serial y 1 impresora. Cuando un proceso se ejecuta en O1, puede leer los archivos "A1" y "A3". Un proceso ejecutándose en el dominio "D4" tiene los mismos privilegios que en "D1", pero además puede escribir en los archivos. Nótese que en el puerto serial y la impresora solo se pueden ser ejecutados por procesos del dominio "D2". ESTRUCTURAS DE PROTECCIÓN DINAMICAS. Las matrices de acceso vistas hasta el momento, en las que no cambian los derechos en cada dominio durante su ejecución, son un ejemplo de Estructuras de Protección Estáticas. Con el fin de ofrecer flexibilidad y de implementar eficientemente la protección, un Sistema Operativo debe soportar cambios en los derechos de acceso. Para esto se requiere implementar alguna estructura de protección dinámica. En este caso continuaremos considerando las matrices de acceso, aunque en su versión dinámica. Básicamente se requieren cuatro nuevos derechos de acceso: Copia, Cambio, Propietario y Control. DERECHO DE ACCESO COPIA. Este derecho de acceso da la facultad a un proceso de copiar derechos existentes en un dominio hacia otro dominio para el objeto en cuestión. O sea, este derecho genera copias en columnas. En este caso estará indicado el derecho copia añadiendo el signo (+) al nombre de los derechos que pueden ser copiados. En la tabla se indica que un proceso ejecutándose en el dominio 1 podrá copiar hacia cualquier otro dominio, el derecho enviar sobre el objeto "COM1" y que un proceso ejecutándose en el dominio "D2" podrá copiar el derecho "Leer" hacia cualquier otro dominio sobre el objeto "Archivo2". De esta manera, en algún momento posterior, la situación de la tabla podría ser la siguiente: En la que se ha copiado el derecho "Enviar" del dominio "D1" al dominio "D4" sobre el objeto "COM1" y se ha copiado el derecho "Leer" del dominio "D2" al dominio "D1" sobre el objeto "Archivo 2". Puede observarse que los derechos "copiados" no contienen el signo (+), o sea, se ha realizado una copia limitada. En general se podría hablar de 3 variantes del derecho "copia": Copia Limitada, Copia Completa, Translación. COPIA LIMITADA. La copia no incluye el derecho "Copia", con lo que no se podrán hacer copias sucesivas del derecho. Se puede indicar con el signo (+). COPIA COMPLETA. La copia incluye el derecho "Copia", por lo que se pueden realizar copias sucesivas del derecho. Se puede indicar con el signo (*). TRANSLACIÓN. El derecho en cuestión junto con el derecho copia se eliminan del dominio original y se coloca en el nuevo dominio. Esta es una forma básica de retirar derechos de un dominio para asignarlo a otro. Se puede indicar con el signo DERECHO DE ACCESO CAMBIO. Este derecho de acceso indica la posibilidad de un proceso para cambiarse de un dominio a otro. La operación cambio actúa sobre dominios, o sea, en este caso los dominios son los objetos. Entonces, para considerar este derecho de acceso se deberán incluir los dominios como objetos adicionales en la matriz de acceso. Considérese la siguiente matriz de acceso: Esta tabla indica que un proceso ejecutándose en "D1" puede cambiarse al dominio "D4" (a); un proceso ejecutándose en "D2" puede cambiarse a "D3"(b) y un proceso ejecutándose en el dominio "D4" puede cambiarse a "D1"(c). 6.4 Protección basada en el lenguaje. 6.5 Concepto de seguridad. Introducción a la Seguridad de los Sistemas Operativos La evolución de la computación y de las comunicaciones en las últimas décadas [7, Deitel]: Ha hecho más accesibles a los sistemas informáticos. Ha incrementado los riesgos vinculados a la seguridad. La vulnerabilidad de las comunicaciones de datos es un aspecto clave de la seguridad de los sistemas informáticos; la importancia de este aspecto es cada vez mayor en función de la proliferación de las redes de computadoras. El nivel de criticidad y de confidencialidad de los datos administrados por los sistemas informáticos es cada vez mayor: Ej.: correo personal, transferencia de fondos, control de manufactura, control de sistemas de armas, control de tráfico aéreo, control de implantes médicos (marcapasos, etc.). Los sistemas deben funcionar ininterrumpidamente y sin problemas. El sistema operativo, como administrador de los recursos del sistema: Cumple una función muy importante en la instrumentación de la seguridad. No engloba a todos los aspectos de la seguridad. Debe ser complementado con medidas externas al S. O. La simple seguridad física resulta insuficiente ante la posibilidad de acceso mediante equipos remotos conectados. La tendencia es que los sistemas sean más asequibles y fáciles de usar, pero la favorabilidad hacia el usuario puede implicar un aumento de la vulnerabilidad. Se deben identificar las amenazas potenciales, que pueden proceder de fuentes maliciosas o no. El nivel de seguridad a proporcionar depende del valor de los recursos que hay que asegurar. Requisitos de Seguridad Los requisitos de seguridad de un sistema dado definen lo que significa la seguridad, para ese sistema [7, Deitel]. Los requisitos sirven de base para determinar si el sistema implementado es seguro: Sin una serie de requisitos precisos tiene poco sentido cuestionar la seguridad de un sistema. Si los requisitos están débilmente establecidos no dicen mucho sobre la verdadera seguridad del sistema. Algunos ejemplos de formulación de los requisitos de seguridad son los siguientes: Directiva DOD 5200.28 (EE. UU.): o Especifica cómo debe manipularse la información clasificada en sistemas de procesamiento de datos. Manual de Referencia de Tecnología de Seguridad de la Computadora (EE. UU.): o Especifica cómo evaluar la seguridad de los sistemas de computación de la Fuerza Aérea. Ley de Intimidad de 1974 (EE. UU.): o Requiere que las Agencias Federales aseguren la integridad y seguridad de la información acerca de los individuos, especialmente en el contexto del amplio uso de las computadoras. Un Tratamiento Total de la Seguridad Un tratamiento total incluye aspectos de la seguridad del computador distintos a los de la seguridad de los S. O. [7, Deitel]. La seguridad externa debe asegurar la instalación computacional contra intrusos y desastres como incendios e inundaciones: Concedido el acceso físico el S. O. debe identificar al usuario antes de permitirle el acceso a los recursos: seguridad de la interfaz del usuario. La seguridad interna trata de los controles incorporados al hardware y al S. O. para asegurar la confiabilidad, operabilidad y la integridad de los programas y datos. Seguridad Externa y Seguridad Operacional Seguridad Externa La seguridad externa consiste en [7, Deitel]: Seguridad física. Seguridad operacional. La seguridad física incluye: Protección contra desastres. Protección contra intrusos. En la seguridad física son importantes los mecanismos de detección, algunos ejemplos son: Detectores de humo. Sensores de calor. Detectores de movimiento. La protección contra desastres puede ser costosa y frecuentemente no se analiza en detalle; depende en gran medida de las consecuencias de la pérdida. La seguridad física trata especialmente de impedir la entrada de intrusos: Se utilizan sistemas de identificación física: o Tarjetas de identificación. o Sistemas de huellas digitales. o Identificación por medio de la voz. Seguridad Operacional Consiste en las diferentes políticas y procedimientos implementados por la administración de la instalación computacional [7, Deitel]. La autorización determina qué acceso se permite y a quién. La clasificación divide el problema en subproblemas: Los datos del sistema y los usuarios se dividen en clases: o A las clases se conceden diferentes derechos de acceso. Un aspecto crítico es la selección y asignación de personal: La pregunta es si se puede confiar en la gente. El tratamiento que generalmente se da al problema es la división de responsabilidades: o Se otorgan distintos conjuntos de responsabilidades. o No es necesario que se conozca la totalidad del sistema para cumplir con esas responsabilidades. o o o Para poder comprometer al sistema puede ser necesaria la cooperación entre muchas personas: Se reduce la probabilidad de violar la seguridad. Debe instrumentarse un gran número de verificaciones y balances en el sistema para ayudar a la detección de brechas en la seguridad. El personal debe estar al tanto de que el sistema dispone de controles, pero: Debe desconocer cuáles son esos controles: Se reduce la probabilidad de poder evitarlos. Debe producirse un efecto disuasivo respecto de posibles intentos de violar la seguridad. Para diseñar medidas efectivas de seguridad se debe primero: Enumerar y comprender las amenazas potenciales. Definir qué grado de seguridad se desea (y cuánto se está dispuesto a gastar en seguridad). Analizar las contramedidas disponibles. http://exa.unne.edu.ar/depar/areas/informatica/SistemasOperativos/SO14.htm#Intro 6.6 Clasificaciones de la seguridad. 6.7 Validación y amenazas al sistema. Tipos de Amenazas. Los tipos de amenazas a la seguridad de un sistema informático los podemos caracterizar teniendo en cuenta como esta información es suministrada por el sistema. En general, hay un flujo de información de una fuente a un destino: Figura #.3 Flujo normal. Teniendo esto en cuenta, podemos señalar cuatro categorías de amenazas: Interrupción: Un elemento del sistema es destruido o se hace inservible. Es una amenaza a la disponibilidad. Ejemplos son la destrucción de algún elemento hardware (discos, líneas de comunicación, etc.) y la desactivación del sistema de gestión de ficheros. Figura #. 4 Interrupción. * Intercepción: Una parte no autorizada obtiene acceso a un elemento relacionado con la seguridad. Es una amenaza a la privacidad. La parte no autorizada puede ser una persona, un programa o un computador. Ejemplos son la copia ilícita de programas y la visualización de ficheros que han de permanecer ocultos. Figura #. 5 Intercepción. * Modificación: Una parte no autorizada no sólo obtiene acceso sino que puede modificar un elemento relacionado con la seguridad. Es una amenaza a la integridad. Ejemplos son la alteración del contenido de un fichero y modificar un programa para que funcione de forma diferente. Figura #. 6 Modificación. * Fabricación: Una parte no autorizada inserta nuevos elementos en el sistema. Es una amenaza a la integridad. Ejemplos son adición de registros a un fichero y la inclusión de mensajes espúreos en una red. La mayoría de los métodos de autenticación se basan en identificar algo que el usuario tiene o conoce. El mecanismo más común de autenticación consiste en que todo usuario ha de introducir una , que es solicitada por el programa de conexión cuando el usuario introduce su nombre. El inconveniente de este método es que las contraseñas pueden ser fácilmente averiguables si el usuario utiliza su nombre, dirección, o similar como contraseña. Otra forma de averiguar una contraseña consiste en probar todas las combinaciones de letras, números y símbolos de puntuación hasta adivinar la contraseña. Existen variantes como que el sistema le añada a cada contraseña un número aleatorio, o asignarle a cada usuario un libro con una secuencia de contraseñas, de forma que cada vez que se conecta tiene que introducir la palabra de paso siguiente. Otros tipos de mecanismos de autenticación se pueden basar en objetos que únicamente cada usuario puede tener, como tarjetas con banda magnética, al estilo de los cajeros automáticos. Otra posibilidad es medir o comprobar ciertas características que están indisolublemente unidas a cada persona, como la voz, escritura, huellas dactilares, etc. En instalaciones en las que la seguridad es prioritaria, estas medidas se pueden complementar con restricciones de acceso a la habitación en la que se encuentran los terminales, asignar a cada usuario un terminal concreto, establecer un horario concreto de trabajo, etc. Amenazas de Origen Software Uno de las los tipos más sofisticados de amenazas tienen su origen en programas que explotan las debilidades de los sistemas. Estos programas se dividen en dos grupos: aquellos que necesitan un programa anfitrión y aquellos que son independientes. Los primeros son trozos de programas que no pueden existir de forma autónoma, mientras que los segundos son programas completos que pueden ser planificados y ejecutados por el sistema operativo. También hay que distinguir entre aquellos programas que no se replican y los que lo hacen. Estos últimos son programas o trozos de programas que cuando se ejecutan pueden generar una o más copias de ellos mismos, que serán posteriormente activadas en la computadora. Podemos distinguir seis tipos de amenazas de origen software: · Bomba Lógica: Es un código incrustado en un programa que comprueba si ciertas condiciones se cumplen, en cuyo caso ejecuta alguna acción no autorizada. Estas condiciones pueden ser la existencia de ciertos ficheros, una fecha particular, la ejecución de una aplicación concreta, etc. Una vez que la bomba explota, puede alterar o eliminar datos, parar el sistema, etc. Un ejemplo de uso de bomba lógica es el caso de un programador que vende un programa a una empresa. Si transcurrido un cierto tiempo la empresa no ha pagado, el programador revela la existencia de la bomba lógica con el fin de obtener su dinero. · Puerta Falsa (Trapdoor): Es un punto de entrada secreto en un programa, de forma que alguien que conozca la existencia de dicha puerta puede obtener permisos de acceso sin tener que pasar por los mecanismos normales de autentificación. La puerta falsa es un código que reconoce alguna secuencia de entrada especial o se dispara si es ejecutado por cierto usuario o por la ocurrencia de una secuencia determinada de sucesos. · Caballo de Troya (Trojan Horse): Es una rutina oculta en un programa de utilidad. Cuando el programa se ejecuta, se ejecuta la rutina y ésta realiza acciones no autorizadas y perniciosas. Estos programas permiten realizar de forma indirecta acciones que no puede realizar de forma directa. Por ejemplo, un programa caballo de troya puede ser un editor que cuando es ejecutado modifica los permisos de los ficheros que edita de forma que éstos puedan ser accedidos por cualquier usuario. El autor del programa suele inducir a su utilización colocándolo en un directorio común y dándole un nombre de forma que aparente ser un programa de utilidad. · Virus: Es código introducido en un programa que puede infectar otros programas mediante la copia de sí mismo en dichos programas. Además de propagarse, un virus realiza alguna función no permitida. · Bacteria: Programa que consume recursos del sistema replicándose asimismo, pero no daña explícitamente ningún fichero. Se suele reproducir exponencialmente, por lo que puede acaparar recursos como CPU, memoria y disco. · Gusano (Worm): Es un programa que usa las redes de computadores para pasar de unos sistemas a otros. Una vez que llega a un sistema, el gusano se puede comportar como un virus o una bacteria, puede implantar programas caballo de troya, o puede realizar acciones no autorizadas. Para replicarse, los gusanos emplean algunos programas que proporcionan servicios de red, como correo electrónico, ejecución remota de programas y conexión a sistemas remotos. http://eduadis.itlapiedad.edu.mx/~hocegueras/so2/so2_33.html Ataques Genéricos a Sistemas Operativos Los principales ataques genéricos a los S. O. son los siguientes [7, Deitel]: Asincronismo: Se tienen procesos múltiples que progresan asincrónicamente. Un proceso podría modificar los parámetros ya validados por otro proceso pero aún no utilizados. Un proceso podría pasar valores malos a otro aún cuando el segundo realice una verificación extensa. Rastreo: Un usuario revisa el sistema intentando localizar información privilegiada. Entre líneas: Se utiliza una línea de comunicaciones mantenida por un usuario habilitado que está inactivo. Código clandestino: Se modifica el S. O. bajo una presunta depuración pero se incorpora código que permite ingresos no autorizados. Prohibición de acceso: Un usuario escribe un programa que bloquea el acceso o servicio a los usuarios legítimos mediante: o Caídas del sistema, ciclos infinitos, monopolio de recursos, etc. Procesos sincronizados interactivos: Se utilizan las primitivas de sincronización del sistema para compartir y pasarse información entre sí. Desconexión de línea: El intruso intenta acceder al trabajo de un usuario desconectado: o Luego de una desconexión de línea. o Antes de que el sistema reconozca la desconexión. Disfraz: El intruso asume la identidad de un usuario legítimo luego de haber obtenido la identificación apropiada por medios clandestinos. Ataque “nak”: Si el S. O. permite a un usuario: o Interrumpir un proceso en ejecución mediante una “tecla” de “reconocimiento negativo”. o Realizar otra operación. o Reanudar el proceso interrumpido. Un intruso podría “encontrar” al sistema en un estado no protegido y hacerse con el control. Engaño al operador: Con un engaño se hace realizar al operador una acción que comprometa la seguridad del sistema. Parásito: Mediante equipamiento especial el intruso: o Intercepta los mensajes entre un usuario habilitado y el procesador. o Los modifica o reemplaza totalmente. Caballo de Troya: El intruso coloca un código dentro del sistema que luego le permita accesos no autorizados. Puede permanecer en el sistema. Puede borrar todo rastro de sí mismo luego de la penetración. Parámetros inesperados: El intruso suministra valores inesperados a una llamada al núcleo. Intenta aprovechar una debilidad de los mecanismos de verificación de la legalidad del S. O. http://exa.unne.edu.ar/depar/areas/informatica/SistemasOperativos/SO14.htm#Crip 6.8 Cifrado. Criptografía El uso creciente de las redes de computadoras y la importancia del trafico cursado hace necesario proteger a los datos [7, Deitel]. La Oficina Nacional de Estándares de EE. UU. (NBS) ha adoptado la norma de cifrado de datos (DES) para la transmisión de información federal delicada. La criptografía es el uso de la transformación de datos para hacerlos incomprensibles a todos, excepto a los usuarios a quienes están destinados. El problema de la intimidad trata de cómo evitar la obtención no autorizada de información de un canal de comunicaciones. El problema de la autentificación trata sobre cómo evitar que un oponente: Modifique una transmisión. Le introduzca datos falsos. El problema de la disputa trata sobre cómo proporcionar al receptor de un mensaje pruebas legales de la identidad del remitente, que serían el equivalente electrónico de una firma escrita. Un Sistema de Intimidad Criptográfica El remitente desea transmitir cierto mensaje no cifrado (texto simple) a un receptor legítimo: La transmisión se producirá a través de un canal inseguro: o Se supone que podrá ser verificado o conectado mediante un espía. El remitente pasa el texto simple a una unidad de codificación que lo transforma en un texto cifrado o criptograma: No es comprensible para el espía. Se transmite en forma segura por un canal inseguro. El receptor pasa el texto cifrado por una unidad de descifrado para regenerar el texto simple. Criptoanálisis Es el proceso de intentar regenerar el texto simple a partir del texto cifrado, pero desconociendo la clave de ciframiento: Es la tarea del espía o criptoanalista: o Si no lo logra, el sistema criptográfico es seguro. Sistemas de Clave Pública La distribución de claves de un sistema criptográfico debe hacerse por canales muy seguros. Los sistemas de clave pública rodean el problema de distribución de claves: Las funciones de cifrado y descifrado están separadas y utilizan distintas claves. No es computacionalmente posible (en un tiempo “razonable”) determinar la clave de desciframiento “D” a partir de la clave de ciframiento “C”. “C” puede hacerse pública sin comprometer la seguridad de “D”, que permanece privada: o Se simplifica el problema de la distribución de claves. Firmas Digitales Para que una firma digital sea aceptada como sustituta de una firma escrita debe ser: Fácil de autentificar (reconocer) por cualquiera. Producible únicamente por su autor. En los criptosistemas de clave pública el procedimiento es: El remitente usa la clave privada para crear un mensaje firmado. El receptor: o Usa la clave pública del remitente para descifrar el mensaje. o Guarda el mensaje firmado para usarlo en caso de disputas. Para mayor seguridad se podría actuar como sigue: El remitente puede codificar el mensaje ya cifrado utilizando la clave pública del receptor. La clave privada del receptor permite recuperar el mensaje cifrado firmado. La clave pública del remitente permite recuperar el texto simple original. Aplicaciones La criptografía es especialmente útil en los sistemas multiusuario y en las redes de computadoras. Se debe utilizar para proteger a las contraseñas, almacenándolas cifradas. Se puede utilizar también para proteger todos los datos almacenados en un sistema de computación; se debe considerar el tiempo de cifrado / descifrado. También es aplicable en los protocolos de redes de capas, que ofrecen varios niveles de cifrado. En el cifrado de enlace la red asume la responsabilidad de cifrado / descifrado de cada nodo: Los datos se transmiten cifrados entre los nodos. En cada nodo se descifran, se determina a dónde transmitirlos y se los vuelve a cifrar. En el cifrado punto a punto un mensaje se cifra en su fuente y se descifra solo una vez, en su destino: Existen ciertas limitaciones tales como la legibilidad de la dirección de destino en cada nodo: o Debe ser legible para el encaminamiento del mensaje. o Ej.: sistemas de conmutación de paquetes de almacenamiento y reenvío con cifrado punto a punto; en este caso la dirección de destino asociada a un paquete no puede ser cifrada. http://exa.unne.edu.ar/depar/areas/informatica/SistemasOperativos/SO14.htm#Cri p http://www.monografias.com/trabajos6/hiso/hiso.shtml http://www.monografias.com/trabajos4/sistemas/sistemas.shtml http://www.monografias.com/trabajos11/oper/oper.shtml http://www.monografias.com/trabajos14/administ-procesos/administ-procesos.shtml http://www.monografias.com/trabajos12/hisis/hisis.shtml http://www.monografias.com/trabajos14/sistemas-operativos/sistemas-operativos.shtml http://www.monografias.com/trabajos/so2/so2.shtml