Fundamentos de Sistemas Operativos Release 1.0 Editor: Armando Arce April 29, 2015 Contents 1 Introducción 3 2 Estructuras del sistema 5 3 Procesos 3.1 Gestión de Procesos . . . . . . . . . . . . . . . 3.2 Analizando los Procesos . . . . . . . . . . . . . 3.3 Información de un proceso . . . . . . . . . . . . 3.4 Estados de un proceso . . . . . . . . . . . . . . 3.5 Procesos Ligeros . . . . . . . . . . . . . . . . . 3.6 Procesos e Hilos . . . . . . . . . . . . . . . . . 3.7 Multihilos . . . . . . . . . . . . . . . . . . . . 3.8 Hilos de Nivel de Usuario y de Nivel de Núcleo . 3.9 Modelos Multihilos . . . . . . . . . . . . . . . 3.10 Hilos . . . . . . . . . . . . . . . . . . . . . . . 3.11 POSIX . . . . . . . . . . . . . . . . . . . . . . 3.12 Hilos Java . . . . . . . . . . . . . . . . . . . . . 3.13 Hilos Windows . . . . . . . . . . . . . . . . . . 3.14 POSIX vs Windows . . . . . . . . . . . . . . . 3.15 Glosario . . . . . . . . . . . . . . . . . . . . . 3.16 Notas bibliográficas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 7 9 11 13 15 18 19 21 22 26 28 31 32 34 35 36 i 4 5 6 ii Administración de memoria 4.1 Fundamentos . . . . . . . . . . . 4.2 Intercambio . . . . . . . . . . . . 4.3 Asignación de memoria contigua 4.4 Mapeo de memoria y protección . 4.5 Asignación de memoria . . . . . 4.6 Segmentación . . . . . . . . . . 4.7 Glosario . . . . . . . . . . . . . 4.8 Referencias . . . . . . . . . . . . 4.9 Bibliografía . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 39 47 49 49 51 56 59 61 62 Memoria virtual 5.1 Fundamentos . . . . . . . . . . . . . . 5.2 Paginación bajo demanda . . . . . . . 5.3 Fallos de página . . . . . . . . . . . . 5.4 Copia durante escritura . . . . . . . . . 5.5 Sustitución de páginas . . . . . . . . . 5.6 Mecanismos de sustitución de páginas: 5.7 Asignación de Marcos . . . . . . . . . 5.8 Sobrepaginación o Hiperpaginación . . 5.9 Asignación de Memoria del Kernel . . 5.10 Glosario . . . . . . . . . . . . . . . . 5.11 Notas Bibliográficas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 65 68 72 74 75 76 82 87 89 92 93 Sistemas de archivos 6.1 Diseño de sistemas de almacenamiento 6.2 Tipos de sistemas de archivo . . . . . . 6.3 Localización de bloques . . . . . . . . 6.4 Métodos de localización . . . . . . . . 6.5 Directorios . . . . . . . . . . . . . . . 6.6 Concepto de directorio . . . . . . . . . 6.7 Visión lógica de los directorios . . . . 6.8 Estructura de los directorios . . . . . . 6.9 Implementación de Directorios . . . . 6.10 Administración del Espacio en Disco . 6.11 Rendimiento del Sistema de Archivos . 6.12 Organización del directorio . . . . . . 6.13 Estructura física del directorio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95 95 96 98 99 105 106 107 107 108 109 109 110 110 . . . . . . . . . . . . . . . . . . 6.14 6.15 6.16 6.17 6.18 Funcionamiento del directorio . . Permisos de archivos y directorios Rutas de Directorios . . . . . . . Glosario . . . . . . . . . . . . . Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110 112 113 115 117 iii iv Fundamentos de Sistemas Operativos, Release 1.0 Este documento consiste de la recopilación de distintas conceptos fundamentales relacionados con los sistemas operativos El mismo ha sido realizado por los estudiantes del curso de “Principios de Sistemas Operativos” que se impartió en la Escuela de Computación del Tecnológico de Costa Rica (Cartago, Costa Rica), durante el primer semestre del 2015. El esquema base inicial para este trabajo ha sido el libro “Fundamentos de Sistemas Operativos” de Silberschatz, Galvin y Gagne publicado por la editorial Mc Graw Hill en 2005. La edición de las diferentes recopilaciones de los estudiantes estuvo a cargo del profesor Armando Arce. Contents 1 Fundamentos de Sistemas Operativos, Release 1.0 2 Contents CHAPTER 1 Introducción 3 Fundamentos de Sistemas Operativos, Release 1.0 4 Chapter 1. Introducción CHAPTER 2 Estructuras del sistema 5 Fundamentos de Sistemas Operativos, Release 1.0 6 Chapter 2. Estructuras del sistema CHAPTER 3 Procesos Recopilado por: 3.1 Gestión de Procesos 3.1.1 Conceptos Generales Un “programa” se define como un compuesto secuencial de órdenes que puede interpretar un mecanismo. Un “proceso” se define como una agrupación de acciones aplicadas a una entidad para modificarla, en nuestro caso lo analizaremos como un programa en ejecución que sufre varias modificaciones. El elemento esencial de un sistema operativo es el que se ocupa de administrar los procesos, dado que pueden surgir diferentes escenarios como por ejemplo que distintos procesos deban iniciar el envío de un correo electrónico a través de la misma aplicación de Outlook de Microsoft 7 Fundamentos de Sistemas Operativos, Release 1.0 3.1.2 Elementos de un proceso Durante la ejecución de un programa, un proceso constantemente cambia los valores de los diferentes elementos involucrados, tanto así que el sistema operativo almacena diferentes datos sobre un momento dado en que se encuentra un proceso. El encargado de esta acción es el bloque de control de proceso. En la imagen de memoria se encuentran el código y los datos de un proceso. 3.1.3 Clasificación de sistema operativos según los procesos Los sistemas operativos se pueden clasificar según el número de procesos y usuarios: - Monotarea ó Monoproceso: existe un sólo proceso en un determinado momento. - Multitarea ó Multiproceso: existen varios procesos en un determinado momento. - Monousuario: permite un sólo usuario a la vez. - Multiusuario ó Tiempo Compartido: 8 Chapter 3. Procesos Fundamentos de Sistemas Operativos, Release 1.0 permite varios usuarios simultáneos ejecutando múltiples tareas. 3.1.4 Manipulación sobre un proceso El sistema operativo nos permite manejar a los procesos por medio de las siguientes esenciales operaciones: • Crear un proceso: derivado de un proceso padre (ej. UNIX) o de la acción de abrir un archivo ejecutable (ej. WINDOS). • Ejecutar un proceso: existen dos maneras de ejecución. Batch no está asociado a una estación y su entrada y salida de datos son proporcionados por un archivo. La otra manera Interactiva está asociado a una estación y su entrada depende un usuario y salida es desplegada a éste. • Terminar un proceso: un proceso puede finalizar por tres causas posibles. Un programa ha llegado a su final; se generó un error de ejecución; otro proceso o el usuario finalizó el proceso. 3.2 Analizando los Procesos 3.2.1 Dependencia entre los procesos Ciertos sistemas operativos mantienen un orden de dependencia entre procesos como lo es el caso de UNIX, donde se encuentran diferentes rangos como Padre, Hijo, Hermano o Abuelo. Además es posible reunir a varios procesos bajo un esquema de grupos y un entorno específico, para así poder realizar una manipulación más amplia sobre varios de estos. 3.2.2 Sistemas multiproceso Por ser este el sistema más complejo, ahondaremos en sus características principales, que son: paralelismo real entre procesador y fun- 3.2. Analizando los Procesos 9 Fundamentos de Sistemas Operativos, Release 1.0 ciones de entrada y salida; memoria principal apta para guardar varios procesos; y la capacidad de cambiar entre las funciones de entrada y salida y el procesamiento. 3.2.3 Procesos Nulos El procesador nunca se detiene de realizar acciones. Pero realmente tienen que existir momentos donde el procesador no realiza ningún trabajo provechoso, de aquí que nacen los procesos nulos, que sirven para distraer al procesador cuando no existe otro trabajo por realizar. 3.2.4 Ventajas de los sistemas multiproceso Entre las ventajas de la utilización de estos sistemas, tenemos: • Modularidad. Fracciona la ejecución de una aplicación en varios procesos y así favorece la programación. • Brinda una útil asistencia de la manera más eficaz, interactiva y concurrente a la necesidad de varios usuarios. • Explota los períodos de tiempo de procesos nulos para terminar la realización de peticiones de funciones de entrada y salida. • Incrementa la utilización del CPU puesto que emplea el tiempo muerto cuando los procesos están obstruidos. 3.2.5 Grado de multiprogramación Se entiende por grado de multiprogramación a la cantidad de procesos vivos que ampara un sistema. Lo que se busca es que a mayor grado de multiprogramación el sistema realize menos procesos nulos, pero esto conlleva a que el sistema posee mayores requerimientos de memoria. Entonces a mayor cantidad de procesos, mayor será el grado de multiprogramación. 10 Chapter 3. Procesos Fundamentos de Sistemas Operativos, Release 1.0 3.3 Información de un proceso Para estudiar un proceso detenidamente, dividiremos las partes de un proceso en cuatro componentes principales. 3.3.1 Estado de un procesador El estado de un procesador es conformado y almacenado por todos los registros de su procesador y el BCP. Cuando un proceso se encuentra en ejecución, los registros son constantemente actualizados con nuevos valores para no tener que recurrir a la memoria principal, debido a que la velocidad de respuesta es cuantiosamente más lenta, pero el BCP no es actualizado. Es hasta que un proceso se ve interrumpido debido a las tres causas posibles que delimitamos anteriormente, que entonces el sistema operativo estable con nuevos datos al BCP, en este caso con los datos del estado del procesador actual. 3.3.2 Imagen de memoria del proceso El sistema operativo delimita los campos de memoria que pueden conformar la imagen de memoria de un proceso. Entre las características más distinguidas se encuentran las siguientes: • La imagen de memoria es el lugar exclusivo para almacenar información del proceso, no puede se guardar en direcciones no asignadas, por lo que eventualmente se debería de levantar una excepción tras ser detectada por el hardware de protección. Y finalmente el sistema operativo debería interrumpir dicho proceso. • La imagen de memoria apunta a memoria virtual o memoria física, según el computador. • La imagen de memoria aumenta o disminuye según la asignación dinámica de memoria que requieren los procesos. 3.3. Información de un proceso 11 Fundamentos de Sistemas Operativos, Release 1.0 3.3.3 Información del BCP En este elemento se encuentra la información elemental de un proceso, como lo son: la información de identificación del proceso y del usuario; el estado del procesador con los valores originales o los valores en el momento en que fue interrumpido un proceso. Y finalmente la información de control del proceso, que contiene el estado del proceso, prioridad del proceso, información de planificación, evento que está interrumpiendo este proceso, archivos abiertos, puertos de comunicación asignados, punteros sobre otros procesos y descripción de la sección de memoria concedida a un proceso 3.3.4 Tablas del sistema operativo Es imperativo mantener tablas con información que detalla recursos del sistemas y a los procesos, pero solo cierta información se introduce en el BCP según la exigencia de compartir la información y la eficiencia. Por eficiencia, la tabla de procesos es conformada como un esqueleto estático para que todos los BCPs contengan el mismo tamaño. Y por otro lado, cuando una información se debe compartir entre distintos procesos, lo mejor es no incluirla en el BCP, por lo que solamente se almacenarán punteros hacia esa información. 3.3.5 Formación de un proceso Para inicializar un proceso se debe rellenar toda la información que comprende un proceso, para esto el sistema operativo realiza las siguientes operaciones: • Fijar un espacio de memoria virtual conformado por una serie de secciones, para alojar la imagen de memoria. • Escoger un BCP disponible de la tabla de la procesos. • Completar el BCP con toda la información requerida antes mencionada como la información de identificación de proceso, 12 Chapter 3. Procesos Fundamentos de Sistemas Operativos, Release 1.0 con los detalles de la memoria concedida, con los valores originales de los registros, etc. • Introducir las rutinas de sistema y el código en el segmento de texto • Introducir los datos preliminares del fichero objeto en el segmento de datos • Designar la nueva pila a ser utilizada por el proceso con los valores del entorno y los parámetros requeridos por el programa. • Finalmente, el estado del este proceso pasa a ser preparado para ejecutar. 3.4 Estados de un proceso Los procesos vivos de un sistema multiproceso se pueden encontrar en cinco fases distintas, de las cuales, las tres siguientes tres primeros 3.4. Estados de un proceso 13 Fundamentos de Sistemas Operativos, Release 1.0 son las elementales. 3.4.1 Ejecución En esta fase, el proceso se encuentra en una etapa de procesamiento, está siendo realizado por el procesador. El estado del proceso habita en los registros del procesador. 3.4.2 Bloqueado En esta fase, el proceso se encuentra interrumpido, a la espera de que suceda un evento por lo tanto no puede proseguir hasta que este ocurra. Un ejemplo típico de esta fase es la espera a una petición de la función de entrada y salida. El estado del proceso habita en el BCP. 14 Chapter 3. Procesos Fundamentos de Sistemas Operativos, Release 1.0 3.4.3 Listo En esta fase, el proceso se encuentra preparado para ejecutar su procesamiento. El sistema operativo es el encargado de indicar cuál proceso es el siguiente a pasar a la fase de ejecución en caso de existir más de un proceso en fase de listo. El estado del proceso habita en el BCP. 3.4.4 Suspendido Existen otras dos fases, de un proceso. Fase de espera y fase de suspendido. Es muy usual que exista un repertorio de procesos en espera para ser consumados a la mayor brevedad. Para reducir el grado de multiprogramación el sistema operativo recurre a suspender ciertos procesos, esto con el fin primordial de liberar la adecuada cantidad de memoria para los procesos que no se encuentran suspendidos. Mas es de reconocer que esta opción de suspender procesos no se encuentra disponible en todos los sistemas operativos como el caso de un sistema monoproceso. 3.4.5 Cambio de contexto Se denomina cambio de contexto a la acción de, primero, guardar el estado de un proceso en su debido BCP y, segundo, a proceder a realizar la rutina que procesa una interrupción del sistema operativo. Estas dos acciones pueden posiblemente incurrir en cambiar valores del estado de otros procesos. 3.5 Procesos Ligeros 3.5.1 Conceptos Generales Se entiende por un proceso ligero a un programa que se encuentra en una corriente de ejecución y que comparte cierta información y su 3.5. Procesos Ligeros 15 Fundamentos de Sistemas Operativos, Release 1.0 imagen de memoria junto a otros procesos ligeros. Un proceso puede contener una única corriente de ejecución normal o varias corrientes de ejecución ligeras que ocurren en paralelo simultáneamente. Un proceso ligero contiene elementos propios a si mismo como lo son los siguientes principales: el contador de programa, registros, estado del proceso y pila. Mas, estos procesos ligeros comparten cierta información en común dado que proviene de un proceso principal. Entre ellos se encuentran: temporizadores, archivos abiertos, variables globales, espacio de memoria asignada. 3.5.2 Estados de un proceso ligero Un proceso ligero también puede encontrarse en los tres estados típicos de en ejecución, preparado y bloqueado. Con la única diferencia de que el estado general del proceso en si, depende de la composición de todos sus estados ligeros, al aplicar la función lógica de AND u OR dependiendo de la fase en que se encuentre. 16 Chapter 3. Procesos Fundamentos de Sistemas Operativos, Release 1.0 3.5.3 Paralelismo Los procesos ligeros permiten cierto grado de paralelismo al habilitar que todos ellos se ejecuten de forma simultánea. 3.5.4 Diseño con procesos ligeros La utilización de procesos ligeros proporciona ciertas ventajas como lo son: la división de tareas y así asignar cada tarea a un proceso ligero único; permite la modularidad al separar una operaciones en suboperaciones e incrementa la velocidad de realización de una tarea en general. 3.5. Procesos Ligeros 17 Fundamentos de Sistemas Operativos, Release 1.0 3.6 Procesos e Hilos Uno de los principales conceptos relacionados al sistema operativos son los procesos. No obstante, este está muy relacionado con otro el cual se conoce como hilo, de ahí la importancia de distinguir la funcionalidad dentro del sistema operativo de cada uno. Los procesos en general se pueden definir como programas en ejecución, los cuales se caracterizan por poseer los siguientes dos puntos mencionados a continuación: • Propiedad de recursos: los procesos están compuestos de espacio de direcciones virtuales para manejar la imagen de estos, la cual hace referencia al conjunto de programa, datos, pila y atributos que se han definido en el bloque de control de proceso, de tal forma que se le pueden asignar control o propiedad de recursos como memoria principal, canales de entrada y salida , dispositivos de entrada y salida y archivos. Dado que existe la posibilidad de interferencias entre los recursos y los procesos el sistema operativos es asignado a proteger y evitar dicho inconveniente. • Planificación y ejecución: por medio de una o más programas es que se lleva a cabo la ejecución de un proceso que sigue una determinada ruta. En cuanto a lo anterior cabe mencionar que se puede llevar a cabo la intercalación de varios procesos, de manera tal que el proceso posee un estado de ejecución y una prioridad de activación que es planificada y activada por el sistema operativo. Dadas las características mencionadas anteriormente, es como se conforma en esencia un proceso en los sistemas operativos tradicionales, no obstante en los sistemas operativos modernos tales características son vistas y tratadas independiente. Tal es el punto que para distinguir entre una y otra características se le denomina hilo o proceso ligero(“thread”) a la unidad que se activa, y proceso o tarea a la unidad de propiedad de recursos. Por tanto, se pueden definir los hilos como la unidad básica de utilización del CPU, el cual contiene su propio “program counter”, conjunto de registros, espacio para el stack y pri- 18 Chapter 3. Procesos Fundamentos de Sistemas Operativos, Release 1.0 oridad, compartiendo el código, los datos y los recursos con los hilos pares. 3.7 Multihilos Además de lo mencionado previamente, el sistema operativo se encarga de brindar soporte a múltiples hilos de ejecución en un solo proceso, modelo al cual se le denomina multihilos, contrario al enfoque tradicional conocido como monohilo, en el cual existe un solo hilo por proceso. Por un lado, el modelo monohilo está compuesto por un bloque de control de proceso, espacio de direcciones de usuario, pilas de usuario y un núcleo para administrar las diversas llamadas o retornos en la ejecución de los procesos, y por otro lado el modelo multihilo está compuesto de igual forma de un bloque de control de proceso y un espacio de direcciones de usuario asociados al proceso, pero diferenciándose del modelo monohilo en que posee pilas separadas para cada hilo y un bloque de control para cada hilo manteniendo datos como los valores de los registros, la prioridad y el estado de los mismos. Es decir, todos los hilos de un proceso comparten el estado y los recursos de este, residiendo en el mismo espacio de direcciones y teniendo acceso a los mismos datos. 3.7.1 Beneficios Algunos de los beneficios de implementar y utilizar hilos en los sistemas operativos son los siguientes: • El tiempo invertido en crear un hilo en un proceso existente es mucho menor que el utilizado para crear un proceso nuevo. Según estudios realizados por los creadores de Mach crear un hilo es dies veces más rápido que crear un proceso en UNIX. • Finalizar un proceso es más rápido que finalizar un proceso. 3.7. Multihilos 19 Fundamentos de Sistemas Operativos, Release 1.0 • Cambiar entre dos hilos dentro del mismo proceso utiliza menos tiempo. • La eficiencia de la comunicación entre diferentes programas en ejecución se ven mejorados, ya que la comuncación entre procesos requiere del núcleo para que este gestione la protección y la comunicación adecuada, mientras que en este enfoque el núcleo no es necesario invocarlo debido a que los hilos están dentro del mismo proceso compartiendo recursos. La siguiente imagen muestra las diferencias en la composición de un modelo monohilo, contrario al modelo multihilo: 20 Chapter 3. Procesos Fundamentos de Sistemas Operativos, Release 1.0 3.8 Hilos de Nivel de Usuario y de Nivel de Núcleo Una vez definidos y mostrados conceptos esenciales con respecto a los procesos e hilos en los sistemas operativos, se presenta la distinción de hilos nivel kernel en comparación con los hilos nivel de usuario, para un mayor entendimiento posteriormente en la presentación de los modelos multihilos. 3.8.1 Hilos Nivel de Usuario En este tipo de entorno(ULT) la aplicación se encarga de todo el trabajo de los hilos, de manera tal que el núcleo no tiene conocimiento de la existencia de los mismos. La biblioteca de subprocesos contiene el código necesario para la creación y destrucción de hilos, la comunicación entre estos por medio del paso de mensajes y datos, la planificación de la ejecución de los mismos, y el almacenamiento y restauración del contexto del hilo programado. Por defecto, una aplicación inicia con un solo hilo, de tal manera que se ejecuta en este. Toda la actividad que se lleva a cabo tendrá efecto en el espacio de usuario y dentro de un solo proceso, de manera tal que el núcleo planifica el proceso como una unidad, asignándole un único estado al no estar consciente de esto. 3.8.2 Hilos Nivel de Núcleo En este ambiente (KLT) el núcleo administra todo el trabajo concerniente a los hilos, de forma tal que la aplicación no posee código para gestionar los hilos, solamente existe una interfaz de programación de aplicación conocida como API , para acceder a las diferentes funcionalidades de los hilos del núcleo. Cualquier aplicación puede implementarse haciendo uso de los multihilos. Todos los hilos de una aplicación se alojan en un único proceso, de forma tal que se mantiene información del contexto del mismo y de los hilos individuales de este, llevándose a cabo la planificación a nivel de hilo. 3.8. Hilos de Nivel de Usuario y de Nivel de Núcleo 21 Fundamentos de Sistemas Operativos, Release 1.0 3.8.3 Hilos a Nivel de Usuario vrs a Nivel de Núcleo Algunas ventajas presentes al utilizar hilos a nivel de usuario en lugar de hilos a nivel de núcleo son las siguientes: • No se requiere de privilegios de modo núcleo para cambiar hilos, debido a que toda la estructura de datos de administración de hilos están en el espacio de direcciones de usuario de un solo proceso, es decir el proceso no se cambia a modo núcleo para administrar los hilos, ahorrando sobrecargas con esto. • Las aplicaciones pueden encargarsen de establecer la planificación, de acuerdo a la necesidades que posean. • Pueden ejecutarse en cualquier sistema operativo. 3.8.4 Desventajas del Nivel de Usuario en comparación al Nivel de Núcleo Las siguientes son algunas de las desventajas presentes al usar el nivel de usuario en lugar del nivel de núcleo: • Las llamadas al sistema son bloqueantes en muchos sistemas operativos tradicionales, de forma tal que si un hilo se bloquea, se bloquean también todos los hilos del proceso. • En un enfoque de nivel de usuario, una aplicación multihilo no puede aprovechar la ventaja del multiprocesamiento. 3.9 Modelos Multihilos Los siguientes modelos hacen referencia a las diferentes formas en que se pueden presentar la implementación de los hilos: 22 Chapter 3. Procesos Fundamentos de Sistemas Operativos, Release 1.0 3.9.1 Modelo de uno a uno En este tipo de modelo se asigna un hilo de usuario a un hilo de núcleo. Es decir, cada hilo de ejecución es un único proceso con su propio espacio de direccionesy recursos. Mediante este modelo la concurrencia es mayor, ya que si un hilo realiza una llamada bloqueante los demás hilos siguen ejecutándose. De esta forma se permite la ejecución de múltiples hilos en paralelo sobre varios procesadores. La desventaja del uso de este modelo radica en que la creación de cada hilo de usuario necesita la correspondiente creación de un hilo de núcleo. La implementación de este modelo se ve limitado en el número de hilos soportados en el sistema, debido a la carga que puede significar la creación de estos en la eficiencia del mismo. Algunos ejemplos de sistemas operativos que implementan este tipo de modelo son las implementaciones UNIX tradicionales, así como Windows (desde Windows95/98 hasta Windows 2000/XP). 3.9. Modelos Multihilos 23 Fundamentos de Sistemas Operativos, Release 1.0 3.9.2 Modelo de Muchos a Uno Este enfoque de modelo asigna múltiples hilos de nivel de usuario a un hilo de nivel de núcleo. La administración concerniente de los hilos se lleva a cabo mediante la biblioteca de hilos en el espacio de usuario. El espacio de direcciones, así como la pertenencia dinámica de recursos es definida por un proceso, de modo tal que se pueden crear y ejecutar varios hilos en este. No obstante, solo un hilo a la vez puede acceder al núcleo, de forma tal que no se pueden ejecutar paralelamente varios hilos. El proceso completo se bloquea si un hilo que pertenece a este realiza una llamada bloqueante al sistema. Algunos de los sistemas operativos que hacen uso de este tipo de en modelo son Windows NT, OS/390, Solaris, Linux, OS/2 y MACH. 3.9.3 Modelo de Uno a Muchos La migración de un entorno de proceso a otro se lleva a cabo mediante este tipo de modelo, permitiendo con ello a los hilos moverse 24 Chapter 3. Procesos Fundamentos de Sistemas Operativos, Release 1.0 fácilmente entre los diferentes sistemas. Este tipo de entorno es de interés en los sistemas operativos distribuidos por la visualización de hilo como una entidad que puede movilizarse entre diferentes espacios de direcciones. Desde el punto de vista de usuario el hilo es una unidad de actividad y el proceso es un espacio de direcciones virtuales con el bloque de control de proceso asociado debidamente. Los hilos pueden movilizarse de un espacio de direcciones a otro, incluso de un computador a otro, para ello debe mantener consigo información tal como el control de terminal, parámetros globales y las guías de planificación. Algunos de los sistemas operativos que utilizan este tipo de modelo son Ra (Clouds), Emerald. 3.9.4 Modelo de Muchos a Muchos Combinación de los modelos de Muchos a Uno y Uno a Muchos. Con este enfoque se multiplexan varios hilos de nivel de usuario de sobre un número de hilos, el cual es menor o igual a la cantidad de hilos de kernel. La cantidad de hilos de núcleo puede ser específica de un 3.9. Modelos Multihilos 25 Fundamentos de Sistemas Operativos, Release 1.0 equipo o aplicación determinada. Este modelo permite la creación de hilos, siendo la cantidad de esta ilimitada ya que va de acuerdo a las necesidades existentes. Si se produce una llamada bloqueante al sistema por parte de un hilo, el núcleo puede planificar otro hilo para su ejecución. Con esto es posible ejecutar una actividad de un usuario o aplicación en múltiples dominios. Un ejemplo de sistema operativo que utiliza este enfoque es TRIX. 3.10 Hilos Los hilos en computación, son los que permiten que un programa realize acciones secuenciales. Los programas que solo poseen un hilo de ejecución son programas secuenciales, ya que las acciones que realizan se ejecutan de manera secuencial, una detrás de otra. El “The Open Journal Proyect” define los hilos como: ”...un único flujo secuencial de control dentro de un programa.”, que hace una referencial 26 Chapter 3. Procesos Fundamentos de Sistemas Operativos, Release 1.0 secuencialidad de los flujos de datos, que estos posee un principio, una ejecución y un final, todos ejecutados de manera secuencial. Durante la ejecución de un programa pequeño, la apreciación de los hilos es mínima ya que un programa que ejecute un “Hola Mundo!”, no necesita mas que un hilo de ejecución, pero el mismo programa puede imprimir mas de una vez un “Hola Mundo!”, utilizando dos o mas hilos de ejecución, de esta manera se pueden crear diversas impresiones del “Hola Mundo!” realizadas por diferentes hilos de ejecución. No solo en programas sencillos como un “Hola Mundo!”, se ve los hilos. Un ejemplo común son los navegadores web, en un navegador se pueden tener multiples pestañas abiertas, una con un video musical en Youtube, otra con la pagina de la red social, y otras tres con la investigación de la tarea. Este es un claro ejemplo de como los hilos muestran las posibilidades de sus usos. La implementación de los hilos se observa de manera diferente según el ambiente, mas adelante se profundizara en cada uno de ellos, el ambiente windows utiliza su API Win32 con la funciones para la 3.10. Hilos 27 Fundamentos de Sistemas Operativos, Release 1.0 creación, manipulación y ejecución de hilos; por otro lado UNIX tiene el POSIX del acrónimo de Portable Operating System Interface, donde la X es de UNIX, donde de igual manera tiene sus funciones predefinidas para los los hilos. Java utiliza la clase Thread que forma parte de su maquina virtual donde se define la especificación del manejo de los hilos, esta en particular suele ser la mas utilizada para la enseñanza de los hilos. 3.11 POSIX Posix es una librería con la definición de las funciones del manejo de los hilos para UNIX, como se vio anteriormente POSIX significa Portable Operating System Interface, donde la X es de UNIX. La librería POSIX contiene los estándares de manejo de hilos, esta API esta para C/C++, la “Carnegie MellonUniversity” dice: “Es más eficaz en sistemas de varios procesadores o varios núcleos donde el flujo de proceso puede ser programado para funcionar en otro procesador así 28 Chapter 3. Procesos Fundamentos de Sistemas Operativos, Release 1.0 ganando velocidad a través de procesamiento distribuido o paralelo”. Es claro que los hilos de ejecución que aprovechen la velocidad de procesamiento de los diferentes núcleo de los procesadores aumente de manera considera el rendimiento del program, un puede ser una operación aritmética, donde cada parte de la operación se resuelva con hilo de ejecución, y cada hilo asignado a un núcleo de procesamiento , claramente puede lograr un mayor rendimiento, aunque el proceso de programación ser un poco tedioso los resultados pueden ser sorprendentes. Una de las ventajas de la programación en multiprocesadores según la CMU(Carnegie MellonUniversity), es la latencia o la espera, esta se de cuando un hilo se tiene que ejecutar mientras otro hilo se ejecuta y este espera una entrada o salida, la latencia no solo se da a nivel de hilos si también a nivel de entrada y salida. Este tipo de espera es común en los procesadores de un solo núcleo, de ahi una gran diferencia con los procesadores multinúcleo ya que la entrada o salida puede venir de otro núcleo del procesadores reduciendo la latencia a 0. 3.11. POSIX 29 Fundamentos de Sistemas Operativos, Release 1.0 En la librería de POSIX encontramos diferentes funciones esta son una mencionadas por Carnegie MellonUniversity:, cabe rescatar que la librería tiene muchas funciones y se recomienda revisar la documentación de la API de POSIX, estos son solo algunos ejemplos: • pthread_create: Esta es la función para la creación de los hilos (Pthreads). • pthread_detach: Cambia el estado de un hila a detached (separado). • pthread_equal: Comparar los identificadores de 2 hilos. • pthread_exit: Termina la llamada a un hilo. • pthread_getspecific: Gestiona los datos de un hilo en especifico. • pthread_join: Espera la terminación de otro hilo. • pthread_key_create: Gestiona los datos de un hilo en especifico. 30 Chapter 3. Procesos Fundamentos de Sistemas Operativos, Release 1.0 • pthread_kill_other_threads_np: Termina todos los hilos en ejecución excepto la llamada al hilo, • pthread_kill [ pthread_sigmask ]: Maneja las señales a los hilos. 3.12 Hilos Java Los hilos de ejecución en java provienen de la clase Thread, para la creación de los hilos en java es necesario crear un nuevo objeto de tipo Thread. La clase Thread viene en la librería de la Maquina Virtual de Java (JVM). Cuando se crean hilos en java estos pueden tener un alto o bajo nivel de prioridad, los hilos de alta prioridad se ejecutan con preferencia sobre los de baja prioridad. La prioridad de los hilos es definida cuando se crean, y esta es heredada de su hilo creador, y es un hilo daemon si y sólo si el hilo creador es un daemon. Los hilos tipo daemon o hilos de utilidad son hilos que proveen servicios a otros hilos. La vida de los hilos tipo daemon dependen de la de los hilos de usuarios, cuando mueren todos los hilos de usuarios los hilos daemon tambien mueren, esta es la definición de segun JavaTpoint. Al inicio de la maquina virtual de java, se crea un único hilo nodaemon, que típicamente llama el método main de alguna clase. La máquina virtual de java solo detiene los hilos de ejecución cuando ocurre alguna de las siguientes acciones: • Cuando el método exit es llama de la clase Runtime y el manejador de seguridad permite que la operación exit pueda ser ejecutada. • Cuando todos los hilos de tipo no-daemon mueren, por una devolución de la llama del método de ejecución o por el lanzamiento de un excepción que vaya mas allá del método de ejecución. De igual forma existen 2 métodos para la creación de hilos en Java: • Declarando una clase como subclase de la clase Thread. Esta subclase debe anular el método run de la clase Thread. Se ubica 3.12. Hilos Java 31 Fundamentos de Sistemas Operativos, Release 1.0 una instancia de la subclase para iniciar un hilo. • La otra forma es declarando una clase que implemente la interfaz Runnable. Posteriormente dicha clase implementará el método run. Se instanciará la clase asignando los argumentos cuando se cree el hilo y se indica. La pagina de Oracle nos proporciona un ejemplo de la creación de hilos, con una clase PrimeThread que hereda de la clase Thread: class PrimeThread extends Thread { long minPrime; PrimeThread(long minPrime) { this.minPrime = minPrime; } public void run() { // compute primes larger than minPrime . . . } } Posteriormente para crear el hilo se crea la instancias a PrimeThread: PrimeThread p = new PrimeThread(143); p.start(); 3.13 Hilos Windows Los hilos de Windows utilizan la API Win32, esta API de Windows utiliza la función de CreateThread para la creación de hilos, esta función recibe una serie de parámetro como atributos de seguridad, tamaño, rutina de inicio, entre otros. Una vez creado el hilo la función devolverá el manejador del nuevo hilo, en caso de error la devolución de la función CreateThread seria NULL. The Computer Science Department at RPI nos facilita una pequeña guía para la creacion de hilos en Windows. 32 Chapter 3. Procesos Fundamentos de Sistemas Operativos, Release 1.0 HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes,// este puntero señala l DWORD dwStackSize,// Tamaño inicial del tamaño de la pila del h LPTHREAD_START_ROUTINE lpStartAddress,// puntero a la funcion d LPVOID lpParameter,// Argumentos del nuevo hilo DWORD dwCreationFlags, // Creacion de banderas LPDWORD lpThreadId // Puntero que recive el ID del hilo ); Entre las limitaciones presentes en los hilos de Windows, esta la cantidad de hilo que puede crear un proceso, ya que estos estarán limitados por la cantidad de memoria virtual que se encuentre disponible. La cantidad pre-establecida es de un megabyte de espacio en la pila. Los que nos muestra que la cantidad maxima de hilos son 2048 por defecto,esta cantidad puede aumentar, si se reduce la cantidad de espacio de pila para cada hilo. Una recomendación para el buen funcionamiento de una aplicación es crear un hilo de ejecución por proceso y también crear una cola de solicitudes, de esta manera se puede mantener el contexto de la información. La de controlador de un hilo se puede arreglar con el derecho de THREADALL_ACCESS_, este llama un descriptor de seguridad este se crear para el nuevo hilo, utilizando un token primario para le proceso. Cuando se llama el OpenThreat el token evalúa los derechos, para darle o no permiso de acceso al hilos de ejecución. Para terminar los hilos en windows se utiliza la función ExitThread, esta función utiliza el parámetro de lpStartAddress que se define al crear el hilos, para solicitar este ato se utiliza la función GetExitCodeThread, la cual nos proporciona la DWORD, que se utilizar como parámetro de ExitThread. Cuando el hilos es terminado este cambia su estado a Señalado, el cual avisa a los otros hilos en espera por el objeto. 3.13. Hilos Windows 33 Fundamentos de Sistemas Operativos, Release 1.0 3.14 POSIX vs Windows La comparación entre ambos se da por el uso del mismo lenguaje de programación C/C++, gracias a la utilización del mismo lenguaje se puede apreciar los diferentes métodos de programación para resolver problemas similares.. Intel nos proporciona algunas comparaciones entre las dos librerías, en su pagina de internet. En general se aprecia que el un mejor modelo en el API de Windows, pero se mostraran diferentes características de comparación: • Simplicidad de los tipos de datos: Los hilos de POSIX y Windows discrepan muchos en sus tipo por un lado los hilos en POSIX permiten diversos tipos de datos pthread_t, pthread_mutex_t, pthread_cond_t, entre otros; por otro lado, los hilos de Windows tienen un único tipo de hilo HANDLE. Uno los problemas que se pueden apreciar es la dificultad de lectura para los usuarios nuevos en POSIX, esto se debe a que cada tipo de hilo posee diferentes tipos de de parámetros, utilidades y funciones. Los hilos de Windows al ser todos de un mismo tipo pueden provocar largos tiempo de espera, como cuando algún objeto como una lista es compartida por 2 hilos diferentes. en POSIX este caso no se de por la diferencia de los tipos de hilos. • Persistencia a Señales: Uno de lo problemas mas comunes en el ambiente POSIX, es cuando un hilo señala un estado variable y ningún otro hilo lo esta señalando, el problema recae en que la señal se pierde si no hay ningún hilo en espera de la condición variable. La Win32 da a un hilo un estado, y este estado se mantiene, y su estado no cambia hasta que algún otro hilo lo mande. Esta situación se da gracias al hecho que Windows establece que todo cambio de estado se debe realizar manualmente, para evitar estos tipos de conflictos. 34 Chapter 3. Procesos Fundamentos de Sistemas Operativos, Release 1.0 3.15 Glosario • Hilo: Subproceso, que ejecuta diversas acciones. • Latencia: Tiempo de espera entre hilos. • POSIX: Del ingles Operating System Interface uniX, interfaz del sistema operativo UNIX. • Pthread: Nominación a los hilos de la librería POSIX. • API: Por sus siglas en inglés se define como Application Programming Interface, el cual hace referencia al conjunto de subrutinas, funciones y procedimientos (o métodos, en la programación orientada a objetos) que ofrece cierta biblioteca para ser utilizado por otro software como una capa de abstracción. • Dominio: Entidad estática, que consiste en un espacio de direcciones y puertos a través de los cuales se pueden enviar y recibir mensajes. • Hilo: Ruta de ejecución, con una pila de ejecución, estado del procesador e información de planificación. • KLT: Por sus siglas en inglés se define como Kernel-Level Threads, el cual hace referencia a los hilos de nivel de núcleo . • ULT: Por sus siglas en inglés se define como User-Level Threads, el cual hace referencia a los hilos de nivel de usuario. • BCP: bloque de control de proceso, guarda información sobre el estado de los registros. • Grado de multiprogramación: variable que mide la cantidad de procesos activos. • Imagen de memoria: contiene el código y los datos de un proceso. • Proceso: programa en ejecución. • Proceso Ligero: thread ó hilo. • Proceso Nulo: bucle infinito sin ningún fin práctico. 3.15. Glosario 35 Fundamentos de Sistemas Operativos, Release 1.0 • Programa: órdenes que ejecuta una máquina. 3.16 Notas bibliográficas • Perez, J. C. (2001). Sistemas operativos - una vision aplicada. Mcgraw Hill. • Silverschatz, A. (2006). Fundamentos de sistemas operativos. McGraw Hill. • López, M. (2012). Sistemas operativos. Andavira Editora. • Tanenbaum, A. (2009). Sistemas operativos modernos. Prentice Hill. • Burgess,M. (2001). A short introduction to operating systems • WordReference.com. (2015). Abril 2015. http://www.wordreference.com/sinonimos/ Sitio web: • El gran libro del PC interno (2007). : Alfaomega Grupo Editor, S.A. • Modelos de multihebras (2015, 12 de Marzo). Recuperado el 12 de Marzo del 2015, de http://wiki.inf.utfsm.cl/index.php?title=Modelos_de_multihebras • Motivación y ventajas de las hebras (2015, 12 de Marzo). Recuperado el 12 de Marzo del 2015, de http://wiki.inf.utfsm.cl/index.php?title=Motivacion_y_ventajas_de_las_hebras • Operating System Multi-threading (2015, 12 de Marzo). Recuperado el 12 de Marzo del 2015, de http://www.tutorialspoint.com/operating_system/os_multi_threading.htm • Sistemas Operativos (2015, 12 de Marzo). Recuperado el 12 de Marzo del 2015, de http://www.wikiteka.com/apuntes/sistemas-operativos-36/ • Stall, W. (2005). Sistemas operativos Aspectos internos y principios de diseño (5a Edición ed.) Madrid: Pearson Educación. 36 Chapter 3. Procesos Fundamentos de Sistemas Operativos, Release 1.0 • Tanenbaum, A. (1996). Sistemas Operativos Distribuidos (1a Edición ed.) México: Prentice Hall. • The Open Journal Project (s. f.). What Is a Thread? Recuperado el 23 de Abril del 2015, de http://journals.ecs.soton.ac.uk/java/tutorial/java/threads/definition.html • Ippolito, G. (s. f.). Linux Tutorial: POSIX Threads Carnegie Mellon University School of Computer Science, 1. Recuperado el 23 de Abril del 2015, de http://www.cs.cmu.edu/afs/cs/academic/class/15492f07/www/pthreads.html • Reliable Software (2006). Windows API Tutorial: Using Threads Recuperado el 23 de Abril del 2015, de https://www.relisoft.com/win32/active.html • JavaTpoint (s. f.). Daemon Thread in Java - javatpoint JavaTpoint, 1. Recuperado el 23 de Abril del 2015, de http://www.javatpoint.com/daemon-thread • RPI Computer Science (s. f.). Win32 APIs for Threads Recuperado el 23 de Abril del 2015, de http://www.cs.rpi.edu/courses/netprog/WindowsThreads.html • Windows (s. f.). CreateThread function (Windows) Recuperado el 23 de Abril del 2015, de https://msdn.microsoft.com/enus/library/windows/desktop/ms682453(v=vs.85).aspx • Breshears, . (2006, 06 de Octubre). Why Windows Threads Are Better Than POSIX Threads | Intel® Developer Zone Recuperado el 23 de Abril del 2015, de https://software.intel.com/enus/blogs/2006/10/19/why-windows-threads-are-better-thanposix-threads • Butenhof, D. (1997, 26 de Mayo). Programming with POSIX Threads. 3.16. Notas bibliográficas 37 Fundamentos de Sistemas Operativos, Release 1.0 38 Chapter 3. Procesos CHAPTER 4 Administración de memoria Recopilado por: Carolina Gonzalez Vargas, Rubén Mora Meneses y Esteban Ramírez Quirós. 4.1 Fundamentos La memoria o memoria principal puede ser considerada como una matriz de bytes, cada uno con una dirección. El administrador de memoria es parte del sistema operativo que regula el uso o liberación de la memoria. Una instrucción es una orden que se le da a la computadora para que ejecute una operación. Un proceso es una secuencia de instrucciones que forman parte de un programa en ejecución. La memoria es un recurso necesario en todo sistema informático y por eso debe ser gestionado con cuidado, esta operación la ejecuta el administrador de memoria o Memory Manager. El administrador de memoria está encargado de asignar la memoria que necesita un proceso, así como liberarla cuando el proceso la haya desocupado. También debe estar al pendiente de qué secciones de la memoria se están utilizando y cuáles no, así como debe tener control sobre cuáles procesos están utilizando la memoria. Para poder administrar la memoria es necesario poder acceder a ella 39 Fundamentos de Sistemas Operativos, Release 1.0 ya sea para leerla, guardar datos o simplemente reservarla, los bytes de la memoria pueden accederse por medio de direcciones, las cuales pueden ser representadas de diferentes maneras. En un programa fuente se utilizan direcciones simbólicas, que más adelante representan direcciones concretas en un programa ejecutable. En una computadora la memoria principal es un recurso vital para su funcionamiento ya que no solo los programas pueden modificarla, sino que también los dispositivos de entrada y salida pueden tener acceso a ella y modificarla. El procesador de la computadora es el que debe regular los accesos a a memoria y la velocidad de este para accederla y modificarla (ya sea para escribir o borrar datos) dependerá de la eficiencia del computador. 4.1.1 Hardware básico El direccionamiento de memoria se refiere a cualquier intento de acceder a la memoria ya sea para leerla, escribir en ella o borrar su contenido, por medio de una dirección. 40 Chapter 4. Administración de memoria Fundamentos de Sistemas Operativos, Release 1.0 Los registros del procesador son espacios pequeños de memoria en el procesador que se utilizan, entre otras cosas, para que las instrucciones del procesador tomen de ahí los datos que necesitan para procesarlos. Al desarrollar el hardware de una computadora, se debe definir la forma en que se va a direccionar la memoria. El máximo direccionamiento que puede tolerar una computadora se define según la cantidad de bits que posean las direcciones a generar, si se toma ése número de bits como exponente de 2 se puede obtener el máximo direccionamiento posible, lo que quiere decir que aunque el computador disponga de más memoria, será imposible accederla, por ejemplo, si se tienen direcciones de 8 bits, solo se podrá acceder hasta 256 bits de memoria. Cuando se define el hardware, también se especifica la menor unidad de memoria direccionable, es decir se escoge una cantidad mínima de bits a direccionar, lo que implica que las siguientes posiciones en memoria tendrán ese tamaño. Por otra parte, la memoria principal y los registros del procesador son las únicas secciones que pueden ser accesadas directamente, e incluso muchas de las instrucciones de la máquina toman como parámetro el contenido de los registros ya mencionados, pero no hay instrucciones que acepten direcciones de la memoria en disco, lo que implica que si se necesitan datos de la memoria en disco, deben copiarse en los registros o en memoria principal para poder ser utilizados. Es decir que, para poder ejecutar un proceso, es necesario asegurarse de que este posea un espacio en memoria exclusivo para su uso y el rango legal de direcciones de memoria disponibles, esto se hace por medio del almacenamiento de un registro base y un registro límite. El registro base guarda la primera dirección en memoria que corresponde a ese proceso, mientras que el registro límite muestra el rango máximo de memoria que necesita el proceso, por ejemplo, si el registro base equivale a la posición 2000 en memoria y el registro límite tiene un valor de 500, el proceso ocupa un espacio en memoria desde la dirección 2000 hasta la 2500. Es posible proteger el espacio en memoria para cada proceso, esto se logra haciendo que el CPU compare las direcciones generadas en modo usuario con el contenido de los registros a los que se desea 4.1. Fundamentos 41 Fundamentos de Sistemas Operativos, Release 1.0 acceder y en cualquier intento de acceder a direcciones que no le correspondan, generar un error fatal. 4.1.2 Reasignación de direcciones La memoria usualmente aloja varios procesos al mismo tiempo y, de hecho, se busca maximizar el uso del procesador teniendo una reserva de procesos a ejecutar, esta lista se llama cola de procesos. Como el programador no sabe cuáles otros procesos van a estar en memoria al mismo tiempo que el proceso que desea ejecutar, es necesario mover el programa a otra área de memoria en caso de ser necesario, es decir, si se necesita el espacio de memoria que está utilizando ese proceso, el sistema operativo debe ser capaz de mover el proceso, ejecutar otro y volver a cargar el proceso anterior justo en la instrucción en que había quedado antes de que fuera interrumpido. Habitualmente se selecciona uno de los procesos de la cola de procesos, este se carga en memoria y luego es ejecutado, cuando este 42 Chapter 4. Administración de memoria Fundamentos de Sistemas Operativos, Release 1.0 termina, el espacio de memoria en el que fue cargado, se declara libre para ser utilizado por otro proceso. Para hacer esto, el editor de montaje o cargador se encarga de asignar las nuevas direcciones del proceso que se está cargando en memoria y una vez asignadas las nuevas direcciones, poder ejecutar el proceso. La reasignación de instrucciones y datos en memoria puede hacerse en cualquiera de las siguientes etapas: • Tiempo de compilación: solamente si se sabe con certeza en dónde va a ser almacenado el programa cuando este sea compilado, se pueden generar direcciones absolutas ya que no va a haber ningún inconveniente con el acceso a la memoria. • Tiempo de carga: si no se sabe a dónde se alojará el proceso cuando este sea compilado, las direcciones deben ser reubicables, de modo que la asignación de direcciones se retrasa hasta cuando el proceso necesita ser cargado en memoria. • Tiempo de ejecución:Si no hubiese problema con retrasar la 4.1. Fundamentos 43 Fundamentos de Sistemas Operativos, Release 1.0 reasignación de direcciones hasta el tiempo de ejecución, es recomendable hacerlo, pero para esto se necesita de un hardware especial, sin embargo, la mayoría de sistemas operativos de propósito general utilizan este método. 4.1.3 Espacios de direcciones lógico y físico Una dirección lógica o dirección virtual es una dirección generada por el CPU, mientras que una dirección física es una dirección de la unidad de memoria. Las direcciones lógicas que son generadas por un programa son llamadas, como conjunto, espacio de direcciones lógicas, estas generan también el espacio de direcciones físicas, el cual el conjunto de las direcciones físicas homólogas a las direcciones lógicas. Se tienen también la unidad de gestión de memoria (MMU o memorymanagement unit)la cual es una parte del hardware que hace la equivalencia entre las direcciones virtuales y físicas en tiempo de ejecución. 44 Chapter 4. Administración de memoria Fundamentos de Sistemas Operativos, Release 1.0 También se cuenta con el registro de ubicación, el cual es un sinónimo para el registro base, el cual suma todas las direcciones generadas por un proceso de usuario cuando se está cargando el proceso en memoria. La memoria de una computadora se organiza en por lo menos dos niveles: principal y secundaria. La memoria principal proporciona un acceso rápido a esta pero el costo es elevado, también es volátil, es decir, su almacenamiento de información no es permanente. Por otra parte, la memoria secundaria, se organiza de una manera similar a la memoria principal sin embargo es lenta, barata y no volátil, lo que permite almacenar información por mucho tiempo, ya sean programas, datos o ambos. Si el sistema operativo puede administrar de forma correcta y efectiva las memorias disponibles, es capaz de proveer las siguientes ventajas: • Los módulos pueden compilarse y escribirse de forma independiente. • Se puede dar varios grados de protección de datos. • Los procesos podrían compartir módulos. 4.1.4 Carga dinámica La carga dinámica consiste en cargar las rutinas hasta que sean invocadas, es decir, no se cargan hasta que se necesitan y todas las rutinas se mantienen en un disco en un formato reubicable y también se aplaza el cálculo de direcciones. Cuando una rutina en un proceso necesita convocar a otra, primero revisa si ya está cargada, de lo contrario la busca y la carga en memoria para su uso con el cargador de memoria, esto implica la actualización de las tablas de direcciones del programa para dar evidencia del cambio generado al cargar la rutina. Esto proporciona como ventaja que si una rutina no se necesita en tiempo de ejecución, nunca será cargada en memoria, por lo tanto ahorrará memoria y resulta útil si se necesita disponer de mucho código para administrar casos poco frecuentes. 4.1. Fundamentos 45 Fundamentos de Sistemas Operativos, Release 1.0 4.1.5 Montaje dinámico y bibliotecas compartidas Para poder comprender el montaje dinámico es importante definir el montaje estático y montaje binario. El montaje estático se da cuando las bibliotecas del lenguaje utilizado en el sistema son tomadas como un módulo y son integradas en el programa. Por otra parte el montaje binario se da cuando se pospone hasta el tiempo de ejecución el montaje del programa. Sin embargo el montaje dinámico ocurre cuando en el fragmento de código se incluye un stud, una pieza de código que indica cómo encontrar o agregar la rutina deseada en la imagen binaria. Es decir, el montaje dinámico retrasa el montaje de los módulos externos hasta que el módulo de carga haya terminado de crearse. Algunos sistemas operativos no permiten el montaje dinámico, sino que solamente el estático. 46 Chapter 4. Administración de memoria Fundamentos de Sistemas Operativos, Release 1.0 4.2 Intercambio Normalmente en los sistemas actuales, tener recursos ociosos o sin utilizar, es considerado un desperdicio de ellos, esto incluye a la memoria, los sistemas de la actualidad suele mantener ocupada un gran porcentaje de ella, esto puede ocasionar situaciones donde no haya suficiente memoria disponible para un proceso que requiere ser ejecutado. Una de las soluciones ante este problema es el intercambio de procesos, esto consiste en intercambiar temporalmente un proceso que esta en memoria con uno que se encuentre en la cola de procesos, guardando en un almacén de respaldo el proceso que se encuentra en memoria, y volviéndolo a llevar luego a memoria para continuar su ejecución.[1] Para poder realizar esto, es necesario una cola de procesos, como se mencionó anteriormente. Por ello, el sistema mantiene esta cola de procesos donde se encuentran todos los procesos que estén listos para 4.2. Intercambio 47 Fundamentos de Sistemas Operativos, Release 1.0 ser ejecutados, tanto los que se encuentran en el almacén de respaldo como los que se van a ejecutar por primera vez.[1] Este proceso de intercambio tiene un costo de tiempo relativamente alto, del cual la mayor parte del tiempo es tiempo de transferencia, el cual es directamente proporcional a la cantidad de memoria intercambiada. Por ello la duración de este proceso de intercambio es proporcional al tamaño del proceso a intercambiar. Para esta operación sea realmente útil, el tiempo de ejecución del proceso que ingresa en memoria debe ser lo suficientemente grande en relación con el costo del tiempo de intercambio, para que este pueda realizar una cantidad de cálculos lo suficientemente grande entre una operación de intercambio y la siguiente. Normalmente cuando un proceso almacenado, vuelve a ser cargado, este se volverá a cargar en el mismo espacio de memoria que ocupó anteriormente. Esta restricción es impuesta por el método de reasignación de las direcciones. [1] Pero este proceso de intercambio, no se puede realizar con cualquier proceso que se encuentre en memoria, para poder realizar esto, los procesos deben estar completamente inactivos. por ejemplo si el proceso no podrá ser intercambiado si se está accediendo a donde residen los buffers de E/S en la memoria. ya que aunque el proceso parezca inactivo, realmente no lo está. Existen ciertas mejoras que se le pueden realizar a este mecanismo, como la utilización de un doble buffer que permita cargar o descargar un proceso mientras otro se encuentra en ejecución; o combinar la técnica con el uso de registros base y límite, para mantener varios procesos simultáneamente en memoria. También este mecanismo se puede implementar en conjunto con algoritmos de planificación con prioridad. Esto consiste es que si llega un proceso de mayor prioridad y este necesita ser ejecutado, el administrador de memoria puede intercambiarlo por un proceso inactivo de menor prioridad. Cuando el proceso de mayor prioridad haya terminado, puede intercambiarse de nuevo por el proceso de menor prioridad.[1] 48 Chapter 4. Administración de memoria Fundamentos de Sistemas Operativos, Release 1.0 En la actualidad, aunque en muchas versiones de UNIX se utiliza una variante de este sistema, el intercambio está normalmente desactivado, por ello en realidad estos mecanismos de intercambio se utilizan en pocos sistemas, ya que en general requieren el costo en tiempo de este mecanismo es muy alto y no logran proporcionar tiempos de ejecución suficientemente largos como para realizar una compensación favorable y que haga de esto una solución razonable de gestión de memoria. 4.3 Asignación de memoria contigua Como todo proceso que necesite ser ejecutado estar albergado en memoria, esta debe albergar tanto el sistema operativo como los diversos procesos que ejecute el usuario. Normalmente ambos, el sistema operativo como el espacio del usuario, no comparten el mismo espacio por eso usualmente la memoria esta dividida en 2 particiones, una para el sistema operativo y otra para los procesos que desee ejecutar el usuario. [1] 4.4 Mapeo de memoria y protección Como los sistemas no utilizan direcciones predefinidas como puede ser direcciones físicas de memoria, sino que utilizan las direcciones absolutas de un programa, las cuales son imposibles de calcular en tiempo de compilación porque no se conoce la ubicación del programa, por lo que no se puede asegurar una protección a la memoria. [2] El registro de ubicación, o bien el registro base ilustra la posición inicial del programa, mientras que el registro límite guarda la cantidad de memoria que necesita el programa, por lo que el registro límite no corresponde a una dirección de memoria como tal, sino a un desplazamiento desde el registro de reubicación. [1] 4.3. Asignación de memoria contigua 49 Fundamentos de Sistemas Operativos, Release 1.0 Una dirección lógica señala una posición en memoria que no depende de la asignación de memoria que se le ha dado al proceso. Toda dirección lógica tiene que ser menor que el valor que contiene el registro límite, se convertirá la dirección lógica dinámicamente con la MMU, esto se logra sumando el valor del registro base, esta nueva dirección es la que se envía a memoria. Una dirección relativa se representa como un desplazamiento desde una posición en memoria conocida, usualmente es del inicio del programa, pero bien podría ser una dirección posterior. Las direcciones relativas necesitan pasar por dos etapas en las cuales el procesador las manipula. La primera agrega el valor del registro base a la dirección relativa de modo que se obtiene una dirección absoluta para el programa. Seguidamente, la nueva dirección es comparada con el valor del registro límite, si esta se encuentra dentro de los límites, se procesa ejecutando la instrucción correspondiente, pero si no, se interrumpe el sistema generando un error.[2] Para asegurar la integridad, seguridad y protección del sistema las 50 Chapter 4. Administración de memoria Fundamentos de Sistemas Operativos, Release 1.0 referencias a memoria que son hechas con un proceso deben ser validadas para estar seguros de que solamente referencian el espacio de memoria que está reservado para el proceso. Un proceso que es seleccionado por el planificador del CPU para ser ejecutado, los valores correctos de los registros de límite y reubicación son cargados por el despachador como parte de un cambio de contexto. Este mecanismo protege el sistema ya que las direcciones generadas por el CPU se comparan con los registros con ello se asegura que no se accedan a regiones de memorias no correspondientes al proceso.[1] 4.5 Asignación de memoria Las estructuras de datos son necesarias para que el sistema operativo sea capaz de administrar apropiadamente las particiones en memoria, por ejemplo, una tabla de descripción de particiones en la que se registre cuáles procesos están alojados en cada partición, así como dónde comienza y dónde termina. Los huecos en memoria que queden libres serán usados para administrar el espacio disponible.[3] Al dividir la memoria en particiones de tamaño fijo, se logra un método simple para asignar la memoria. Cada sección solamente puede contener un proceso porque la multiprogramación está limitada por la cantidad de particiones que no alojan ningún proceso. Aparte de esto, las particiones fijas también fuerzan al sistema a mantener una tabla que indique qué partes de la memoria están libres para que otros procesos la utilicen y cuáles están ocupadas. Actualmente los sistemas operativos modernos no utilizan el esquema de particiones fijas, sin embargo, los sistemas operativos de los grandes computadores de IBM, el OS/MFT, o bien Multiprogramación con un número fijo de tareas, es un buen ejemplo de un sistema operativo eficiente que utiliza este esquema. [2] Las particiones múltiples funcionan cuando una partición está libre, seguidamente se escoge un proceso de la cola de entrada y es cargado 4.5. Asignación de memoria 51 Fundamentos de Sistemas Operativos, Release 1.0 en esa partición. Al terminar el proceso, la sección queda disponible para ser ocupada por otro proceso. El hecho de distribuir la memoria disponible en particiones de tamaños distintos de memoria, aumenta la flexibilidad de la repartición de memoria. Además de esto, la partición dinámica provee un esquema por medio del cual el número y longitud de las particiones son variables. Al traer un proceso a la memoria principal, este esquema ayuda a que se le asigne únicamente el espacio en memoria que necesita, ni más, ni menos. [2] La fragmentación externa se da cuando la memoria externa se fragmenta cada vez más. Cuando un proceso necesita memoria, se busca un espacio tan grande como para poder alojarlo y si se encuentra, se le asigna y se mantiene la demás memoria libre para las solicitudes de los procesos que entrarán en el futuro. [1] Con forme los procesos entran al sistema, también se ingresan a una cola. Esta cola de entrada se ordena por el sistema operativo según el algoritmo de planificación que este posea. Se le asigna memoria a los procesos hasta que los requisitos del siguiente proceso ya no puedan satisfacerse. El sistema operativo considera la memoria necesaria para cada proceso y lo compara con la cantidad de memoria libre para ser utilizada, de este modo se puede determinar a cuáles procesos se les va a asignar memoria. El agujero es un modo de llamar a toda la memoria disponible para los procesos de usuario cuando esta se considera como un bloque único que contiene toda la memoria libre para ser utilizada por los procesos entrantes. En algún momento durante la ejecución de los procesos se va a tener un conjunto de huecos de memoria de muchos tamaños distribuidos por toda la memoria y cuando llega un proceso nuevo para ser ejecutado y este solicita memoria, el sistema operativo busca entre todos esos espacios libres alguno que sea lo suficientemente grande como para poder alojarlo. [1] Si el agujero es muy grande, se divide en dos partes, una para el proceso y la otra se agrega al conjunto de espacios de memoria disponibles. Caso contrario ocurre si hay agujeros de memoria adyacentes, estos se fusionan para obtener un espacio en memoria más 52 Chapter 4. Administración de memoria Fundamentos de Sistemas Operativos, Release 1.0 grande en lugar de dos pequeños. El proceso, al terminar, libera la memoria que había utilizado para poder ejecutarse y esta memoria se volverá a considerar como libre y se agrega al conjunto de agujeros de memoria.[1] La asignación dinámica de espacio busca satisfacer las solicitudes de memoria según la lista de espacios disponibles. El primer ajuste, se conoce como el método de asignar el primer agujero en memoria que se encuentre que sea lo suficientemente grande como para alojar el proceso entrante, la exploración de memoria puede hacerse desde el inicio de la memoria o bien donde terminó la exploración anterior y la exploración se detiene en cuanto se encuentre un hueco de memoria con la cantidad de memoria igual o superior al espacio requerido por el proceso. [1] Como se puede observar en la imagen, el mejor ajuste es un método de asignación de memoria en que se busca el bloque de memoria disponible más pequeño pero que tenga espacio suficiente para el pro- 4.5. Asignación de memoria 53 Fundamentos de Sistemas Operativos, Release 1.0 ceso, pero este método puede generar un agujero de memoria más pequeño que en los demás métodos. [1] El peor ajuste asigna el agujero de memoria de mayor tamaño que encuentre durante la exploración, esto genera un agujero de mayor tamaño luego de haber asignado el proceso, lo que puede generar un agujero muy útil. [1] Los métodos del primer ajuste y mejor ajuste son mejores que el del peor ajuste en matices como el tiempo necesario y utilización eficiente del espacio. Aunque es indefinido si la estrategia del primer ajuste o mejor ajuste es mejor en cuestión de utilización del espacio de almacenamiento, pero la del primer ajuste es más rápida. [1] Existen otras políticas que generan menos fragmentación de memoria y de hecho son muy utilizados en los sistemas operativos, por ejemplo la política de los gemelos (buddies). [3] En este sistema, el asignador nada más provee de bloques de memoria de tamaños determinados y tiene muchas listas libres, una para cada 54 Chapter 4. Administración de memoria Fundamentos de Sistemas Operativos, Release 1.0 tamaño que sea capaz de asignar. Los espacios habitualmente se calculan como potencias de dos o según la secuencia de Fibonacci. Si el repartidor recibe una solicitud de memoria, el tamaño es redondeado hasta que el tamaño solicitado lo permita y se le asigna el primer bloque libre con este tamaño. [4] El reciclaje de bloques implica hacer un intento por mezclar los bloques de memoria adyacentes en un bloque más grande, para simplificar el trabajo, las listas pueden almacenarse en orden de dirección. Este enfoque provee una ventaja: la coalición es barata porque todo bloque libre se calcula desde su dirección. [4] El sistema buddy puede trabajar muy bien, pero también puede trabajar muy mal según sean los tamaños seleccionados para interactuar con las solicitudes de memoria y según sea el patrón de los bloques. Redondear implica una cantidad de memoria significativa que se desperdicia, a lo que se le llama fragmentación interna, la cual se puede reducir haciendo que el tamaño de los bloques sea similar. [4] 4.5. Asignación de memoria 55 Fundamentos de Sistemas Operativos, Release 1.0 4.6 Segmentación La segmentación se puede definir como una técnica en la cual las tareas y procesos pueden acceder a ellas unitariamente para poder administrar mejor la memoria contigua, facilita la comprensión visual del programador, es la estructura clave para las pilas, datos y código para un programa. Están conformados por un tamaño predefinido, un identificador y un desplazamiento para acceder a los datos dentro de él, cada dirección lógica se expresará mediante dos valores, el número de segmento (s) y desplazamiento dentro del segmento (d), estas características se les asigna en el proceso de compilación y para accederlos se debe tener en cuenta que la memoria física se accede literalmente, cada dirección lógica (que proviene del procesador) habrá que convertirla en una dirección real, que la memoria RAM podrá leer, este cambio lo realiza un aparato de hardware alojado generalmente en las tarjetas de memoria principal llamado unidad de gestión de memoria, ya que posee algunos implementos como la tabla donde vienen numeradas cada segmento. Además el procesador cuenta con otra tabla que describe: • Base: Dirección en donde comienza el segmento (contando la dirección) • Límite: Dirección en donde finaliza (sin contar la dirección) • Desplazamiento: Lo que hay que sumar a una dirección para obtener su dirección real, se calcula como la dirección de comienzo del segmento en la memoria real menos la dirección virtual de inicio del segmento • Atributos del segmento: como lectura/escritura para la seguridad de que otros procesos interfieran en “segmentos ajenos”. Para seguridad del manejo de segmentos hay 2 “heaps”, uno para los segmentos en sí y otro para administración de estructuras de datos, como colas y pilas, en el primero como hay muchos segmentos a través de la línea del tiempo de los procesos, segmentos son asignados a una parte de la memoria y otros liberados, y esto fragmenta mucho 56 Chapter 4. Administración de memoria Fundamentos de Sistemas Operativos, Release 1.0 la memoria produciendo desperdicio y múltiples pedazos de memoria tan pequeños que no se pueden utilizar, afortunadamente hay métodos y algoritmos para reducir el impacto de desperdicio que producen la fragmentación: • First-fit: consiste en recorrer la lista secuencialmente hasta hallar el primer fragmento donde quepa la memoria solicitada, el trozo encontrado se parte en dos para entregar sólo lo que se necesita • Best-fit: Consiste en recorrer la lista secuencial y completamente hasta hallar el fragmento donde quepa la memoria solicitada y se desperdicie el menor espacio posible, el trozo encontrado se parte en dos para entregar sólo lo que se necesita • Worst-fit: consiste en recorrer la lista secuencialmente hasta hallar el primer fragmento donde quepa la memoria solicitada y sobre la mayor cantidad de memoria posible, el trozo encontrado se parte en dos para entregar sólo lo que se necesita De las anteriores la segunda es la menos efectiva ya que llena la memoria de pequeños trozos de memoria inútiles y el proceso para reunificarlos y reciclarlos es sumamente caro en procesamiento en función a la cantidad, mientras que la mejor solución es la de firstfit, debido que estadísticamente desperdicia menos, lo ideal es implementar siempre este método aunque resulta ineficiente en parte, ya que siempre comienza desde el inicio aun cuando no se le ha notificado que se ha liberado un espacio para que se devuelva y verifique si cabe el proceso, en lugar de dejar un puntero donde quedo para que a partir de ahí siga buscando sin necesidad de que se devuelva a buscar espacios que por redundancia se sabe que no son suficientemente grandes. Algunas características positivas que aporta la segmentación son la modularidad, cada segmento es independiente uno del otro, se puede afectar uno sin que el otro tenga represalias, entre otras como protección, compartición, estructuras de datos largas, enlace dinámico entre segmentos. En conclusión el esquema de la segmentación presenta algunas ven- 4.6. Segmentación 57 Fundamentos de Sistemas Operativos, Release 1.0 tajas como las siguientes: conocimiento de las partes lógicas del programa de parte del programador, los segmentos se pueden tratar como módulos separados y cada uno se puede compilar por aparte (en la compilación es donde se crean las uniones entre segmentos), como son separados unos de otros son fáciles de modificar uno por uno sin afectar a los otros, la manera de compartir los módulos es sencillo, pueden crecer en caliente o en tiempo de ejecución según las necesidades del programa, es posible crear segmentos aun cuando no existan o cuando ni siquiera se le han asignado espacio (por ejemplo cuando no se sabe el tamaño de un vector hasta que sea tiempo de ejecución para asignarle el que necesita). Algunas desventajas de la segmentación: incremento en los costos de hardware y de software para llevar a cabo la implantación y su consumo en recursos, producen mucha fragmentación externa, en la memoria virtual podría representar un problema ya que estos funcionan con bloques fijos y los segmentos varían su tamaño y a su vez está requiere una reubicación, o sea, más procesamiento consumido, la compartición entre segmentos es útil pero se necesita mecanismos de hardware y software adicionales para llevarlo a cabo, la implementación de la instrucción fork() es ineficiente, todas estas desventajas tratan de ser minimizadas por la siguiente técnica, la segmentación paginada. 4.6.1 Segmentación paginada La segmentación no suple al 100% con la necesidad de aprovechamiento de la memoria, la paginación es otra técnica que compite con ésta para el mejor rendimiento, aunque tampoco lo logra, se ha creado un método más efectivo que aprovecha las ventajas de ambas llamado Segmentación paginada, lo que sucede es que hay una administración segmentada pero el contenido usado para memoria contigua de cada segmento de página, el segmento tendría que tener su propia tabla de páginas con 3 variables de dirección como lo son S, P, D; la S es por el número de segmento, la P para el número de página, y el D para el desplazamiento a partir de ahí, además de SMT que es la tabla de mapas de segmentos que a su vez tiene en 58 Chapter 4. Administración de memoria Fundamentos de Sistemas Operativos, Release 1.0 cada entrada un PMT que es la tabla de mapas de página por cada segmento. Ventajas de la segmentación paginada: junta las ventajas de la paginación y la segmentación, se simplifican mucho las formas de almacenamiento, se elimina casi por completo la fragmentación externa y la necesidad de usar ese costoso algoritmo de compactación. Desventajas de la segmentación paginada: la incorporación de los controles necesarios para el sistema incrementa en cuanto a procesamiento y uso de memoria, no logra eliminar la fragmentación interna, la paginación pura siempre se desperdicia la última página, pero en este método se desperdiciaran en función a los segmentos seleccionados 4.6.2 Fragmentación Todos estos métodos intentan eliminar a un enemigo en común llamado “Fragmentación”, pero ¿Qué es la fragmentación?, es la incapacidad de poder tratar la memoria como asignamiento secuencial para abastecer los procesos sin dejar desperdicios, la manera de eliminarla sería hacer que los procesos caigan en gravedad para dejar todos los trozos libres en la parte superior y poder fusionarlos pero eso sería demasiado ineficiente. Hay dos tipos de fragmentación, la interna y la externa, la interna es cuando la memoria contigua se fragmenta y la externa también pero cuando la memoria que se fragmenta no es contigua, cuando una memoria no es contigua o parte de ella no lo es, significa que no está destinada a asignación de procesos aunque sí para satisfacer requerimientos. 4.7 Glosario • Cola de procesos: Son los procesos que estén esperando a ser cargados en memoria para su ejecución por parte del sistema. 4.7. Glosario 59 Fundamentos de Sistemas Operativos, Release 1.0 • Dirección base: Es la dirección física inicial del lugar donde el segmento reside dentro de la memoria. • Dirección límite: Es la dirección que especifica la longitud de un segmento específico. • Espacio de direcciones lógicas: Es el conjunto de todas las direcciones lógicas. • Mejor ajuste: Asigna el espacio más pequeño que tenga el tamaño suficiente. Tiene como ventaja que genera el espacio más pequeño posible restante. • Memoria: Es dispositivo basado en circuitos que posibilitan el almacenamiento limitado de información y su posterior recuperación. • Peor ajuste: Es una posible solución para el problema de asignación dinámica de espacios de almacenamiento, el cual asigna el mayor espacio de tamaño disponible. • Primer ajuste: Es una posible solución para el problema de asignación dinámica de espacios de almacenamiento, el cual asigna el primer espacio de memoria que sea lo suficientemente grande. • Registro de reubicación: Es el registro base, el valor contenido en este registro suma todas las direcciones generadas por un proceso de usuario en el momento de enviarlas en memoria. • Tabla de segmentos: Es una implementación para manejar las direcciones bidimensionales definidas por el programa sobre las direcciones físicas unidimensionales. • Unidad de gestión de memoria (MMU, memorymanagement unit): Es un dispositivo de hardware que establece la correspondencia entre direcciones virtuales y físicas en tiempo de ejecución. • Crecer en caliente: por lo general la expresión que acompaña a “en caliente” se refiere a que no se necesita reiniciar el proceso 60 Chapter 4. Administración de memoria Fundamentos de Sistemas Operativos, Release 1.0 o apagar el proceso realizar el cambio y volverlo a ejecutar, si no que se puedan hacer cambios durante su ejecución. • Instrucción fork(): función del lenguaje C/C++ exclusivo en Unix el cual permite formar nuevos procesos en paralelo. • STM: mapa que usa la segmentación paginada para controlar los segmentos (Segment table map) • PMT: mapa que usa la segmentación paginada para controlar las páginas (Page Map Table) • Carga dinámica: consiste en cargar rutinas en memoria cuando es convocada por el programa, no antes. • Dirección física: dirección generada por un programa. • Dirección lógica o virtual: dirección generada por el CPU. • Montaje binario: se pospone hasta el tiempo de ejecución la carga del programa. • Montaje dinámico: incluir un stud en la imagen binaria para encontrar y cargar una rutina cuando esta sea convocada. • Montaje estático: incluir el código de las bibliotecas en la imagen binaria del programa. 4.8 Referencias Martínez y Díaz, en su libro Sistemas Operativos: Teoría y práctica (Consultar fuente [1]) plantean una introducción a los conceptos de memoria y el administrador o gestor de memoria involucrados en el desarrollo de un sistema operativo y explica con detalle la forma en que se maneja la memoria disponible entre los procesos que están siendo ejecutados. Tanenbaum, en su libro Sistemas Operativos Modernos (Consultar fuente [2]) detalla el concepto de memoria, su jerarquía y administración, también explica los conceptos de carga dinámica y de montaje 4.8. Referencias 61 Fundamentos de Sistemas Operativos, Release 1.0 dinámico así como sus bibliotecas compartidas. Este libro también hace referencia a la asignación de direcciones. Morera y Pérez-Campanero, en su libro Conceptos de sistemas operativos (Consultar fuente [3]) ofrecen no solamente una definición de memoria sino que le dan una dimensión de recurso central, lo que los lleva a explicar las formas de accesar las jerarquías de memoria y por lo tanto, también explica cómo se integra la memoria al hardware de la computadora y la asignación de direcciones. Stallings, en su libro Sistemas Operativos (Consultar fuente [4]) da una definición de memoria y su administrador, pero también explica el comportamiento de la memoria en sistemas monoprogramados y multiprogramados. Este libro es más detallado con respecto a la reasignación de direcciones ya que explica qué sucede cuando la memoria es compartida por varios procesos, así como la carga y descarga de procesos. También de detalla la diferencia entre la memoria principal y la memoria secundaria, sus características y las ventajas de un buen sistema de gestión y acceso de memoria. Además explica con detalle la definición de carga dinámica y los diferentes tipos de montajes. Silberschatz, Baer y Gagne, en su libro Fundamentos de Sistemas Operativos (Consultar fuente [5]) explican los términos de registro base y límite, así como los detalles del hardware necesario para que un sistema operativo pueda manejar apropiadamente la memoria, también explica la forma en que se puede asegurar el espacio de un programa en memoria. También detalla la reasignación de direcciones y las condiciones que deben cumplirse para poder realizar una reasignación en las diferentes etapas de creación del software. Provee, además definiciones claras para las direcciones lógicas y físicas y de la utilización apropiada de la memoria en un sistema con carga dinámica, así como el montaje dinámico. 4.9 Bibliografía [1] Martínez, P., Díaz, J. (1996). Sistemas Operativos: Teoría y práctica. NS: Ediciones Díaz de Santos. 62 Chapter 4. Administración de memoria Fundamentos de Sistemas Operativos, Release 1.0 [2] Tanenbaum, A. (2003). Sistemas operativos modernos. NS: Pearson Educación. [3] Morera, J., Pérez-Campanero, P. (2002). Conceptos de sistemas operativos. NS: Universidad Pontifica Comillas. [4] Stallings, W. (1997). Sistemas Operativos. Madrid: Prentice Hall. [5] Silberschatz, A., Baer P., Gagne, G. (2005). Fundamentos de Sistemas Operativos. España: Cofás S.A. 4.9. Bibliografía 63 Fundamentos de Sistemas Operativos, Release 1.0 64 Chapter 4. Administración de memoria CHAPTER 5 Memoria virtual Recopilado por: Julio Castro Bonilla, Carlos Fallas Victor y Walter Román Quirós. El término memoria virtual suele asociarse, con la capacidad que tienen algunos sistemas, para acceder a direcciones, situadas en un espacio de almacenamiento virtual, mucho mayor, que el disponible en el almacenamiento real de un sistema informático determinado. La memoria virtual es una técnica de gestión que, realizando una combinación entre componentes de hardware y de software, en este caso el sistema operativo, permite cargar programas parcialmente en la memoria real. Esto hace parecer que la máquina tiene más memoria que la memoria física que posee y de la que se sabe con anticipación. 5.1 Fundamentos Los métodos más comunes para gestionar la memoria de los sistemas, que permiten la existencia de un almacenamiento virtual, son la paginación y la segmentación y en algunos sistemas, se puede utilizar una combinación de los dos métodos. En los sistemas de almacenamiento real, para que un proceso se pudiera ejecutar, era necesario que el proceso completo, estuviese cargado en el almacenamiento real, sin 65 Fundamentos de Sistemas Operativos, Release 1.0 embargo, los sistemas de memoria virtual se caracterizan, muy especialmente, porque las direcciones utilizadas por los programas en ejecución, no necesitan estar todas ellas en el almacenamiento real. 5.1.1 Espacio de direcciones virtual El espacio de direcciones virtual de un proceso, se refiere a la vista lógica (o virtual) de cómo un proceso se almacena en la memoria. Por lo general, este punto de vista es que un proceso comienza en una dirección determinada y a su vez existe en la memoria contigua. 5.1.2 Independencia física Este concepto se refiere a que al poseer la memoria virtual, ésta será independiente de la memoria física, por lo cual, el sistema no estará restringido solamente al espacio de la memoria física, si no que la memoria virtual le dará un espacio adicional utilizable con las mismas 66 Chapter 5. Memoria virtual Fundamentos de Sistemas Operativos, Release 1.0 funciones que la memoria física. Esto da una ventaja adicional, y es que se pueden ejecutar más programas al mismo tiempo, sin reducir el tiempo de respuesta ni el de ejecución. 5.1.3 Biblioteca compartida Los procesos que se encuentran alojados en la memoria virtual, tienen la propiedad de compartir las bibliotecas del sistema, utilizando un espacio de direcciones, el cual, como se menciona anteriormente es compartido. 5.1.4 Compartimiento de memoria La memoria virtual permite que los procesos puedan compartir el espacio de memoria, se crea una región destinada para este fin, que será el espacio de direcciones virtual de cada proceso que la comparte. 5.1. Fundamentos 67 Fundamentos de Sistemas Operativos, Release 1.0 5.1.5 Carga simplificada del programa Una función importante de la memoria virtual es la “reubicación” que permite que el programa también se ejecute en cualquier lugar de la memoria física. 5.1.6 Cantidad máxima de memoria Se puede aparentar más memoria de la que se tiene físicamente, pero, dependiendo de las características del procesador, facilitándole al programador el tener que preocuparse por mover los datos en memoria. 5.2 Paginación bajo demanda Cuando se carga la memoria, todo el código ejecutable es cargado aunque éste no vaya a ser utilizado por completo. La memoria virtual 68 Chapter 5. Memoria virtual Fundamentos de Sistemas Operativos, Release 1.0 ofrece una característica muy importante, que es la de administrar solamente el código ejecutable con el que se trabajará, esto quiere decir, que durante la ejecución del programa, sólo se cargarán las páginas en memoria que el programa necesite y sean necesarias para que la ejecución ocurra correctamente, las páginas que no sean utilizadas durante la ejecución del programa no llegarán a cargarse en la memoria física. Cuando se va a cargar un proceso, se realiza una estimación del espacio que se utilizará en el proceso, entonces, no se cargan la totalidad de las páginas, sino, solamente las necesarias; lo que reduce el tiempo de carga y la cantidad de memoria física utilizada. 5.2.1 Intercambiador perezoso El intercambiador perezoso es el componente que solamente realiza un cambio de página cuando es estrictamente necesario. Para este caso en específico de memoria virtual, se le llamará localizador, puesto que, solamente carga las páginas necesarias y no todo el proceso, que provocaría un gasto de memoria. Un intercambiador perezoso nunca reincorpora una página a memoria a menos que se necesite. Como, desde este punto de vista, un proceso se considera una secuencia de páginas en vez de un gran espacio contiguo de direcciones, el término intercambio es técnicamente incorrecto. Un intercambiador manipula procesos enteros, mientras que un paginador trata con las páginas individualmente de un proceso. 5.2.2 Paginación bajo demanda pura Bajo un esquema de paginación bajo demanda pura, el sistema nunca traerá una página a la memoria hasta que se dé la petición de ésta. Se trata de realizar paginación con intercambio, el bit de valídez de la tabla de páginas indica si la página está o no en memoria. 5.2. Paginación bajo demanda 69 Fundamentos de Sistemas Operativos, Release 1.0 5.2.3 Localidad de referencia Cuando el procesador solicita al hardware cierta dirección de memoria, el hardware transfiere a la memoria caché el byte o palabra solicitada y además transferirá un bloque o página completa. La localidad de referencia involucra varios conceptos, entre ellos: • Localidad temporal: Cuando un recurso es empleado, es muy probable que vuelva a ser utilizado en poco tiempo. • Localidad espacial: Es mas probable que un recurso que no sea requerido sea accesado que un recurso cercano. • Localidad secuencial: Un recurso, y muy particularmente la memoria, tiende a ser requerido de forma secuencial. 70 Chapter 5. Memoria virtual Fundamentos de Sistemas Operativos, Release 1.0 5.2.4 Tabla de páginas La tabla de página permite traducir direcciones virtuales a direcciones físicas. Se encuentra indexada por el número de página virtual y contiene la dirección física de la página. Se requiere un bit de válido para indicar que la entrada contiene un página física válida, es decir que esta se encuentra en memoria principal y no producirá fallo de página. El tamaño de la tabla de páginas es inversamente proporcional al tamaño de página. Las tablas de páginas son habitualmente tan grandes que se almacenan en memoria principal y, con frecuencia, paginadas ellas mismas: se requiere un acceso a memoria para obtener la dirección física y otro para obtener el dato. Posee bits de control: válido, uso, sucio, permiso lectura y permiso escritura además de una optimización en: jerarquía de tablas de página, técnicas hashing (tablas de páginas invertidas) y buffer de traducción anticipada (TLB). 5.2. Paginación bajo demanda 71 Fundamentos de Sistemas Operativos, Release 1.0 5.2.5 Memoria Secundaria Esta memoria contiene las páginas que no se conservan en la memoria principal. La memoria secundaria casi siempre es un disco de alta velocidad. 5.2.6 Espacio de intercambio El espacio de intercambio es utilizado como áreas de almacenamiento de memoria virtual cuando el sistema no tiene suficiente memoria física para manejar los procesos actuales. El sistema de memoria virtual asigna copias físicas de archivos en disco a el sistema operativo puede buscar un proceso poco activo, y moverlo al área de intercambio (el disco duro) y de esa forma liberar la memoria principal para cargar otros procesos. Mientras no haga falta, el proceso extraído de memoria puede quedarse en el disco, ya que ahí no utiliza memoria física. Cuando sea necesario, el sistema vuelve a hacer un intercambio, pasándolo del disco a memoria RAM. 5.3 Fallos de página Un fallo de página es cuando un programa intenta acceder a un espacio de sus direcciones, pero éste espacio no se encuentra cargado en la memoria física del sistema. Cuando se da un fallo de página, el sistema operativo debe responder cargando en memoria los datos que se quieren acceder, permitiendo que el programa continúe con su ejecución normal. El manejador de fallos de página determina cómo debe reaccionar el sistema operativo ante un fallo de página. Puede determinar las siguientes acciones: • Encontrar donde se encuentra la página en disco y leerla. • Cuando la página ya está en la RAM, reconfigura la Unidad de Manejo de Memoria (MMU) para que apunte a dicha página. 72 Chapter 5. Memoria virtual Fundamentos de Sistemas Operativos, Release 1.0 • Apunta a una página que sólo ceros y si el proceso va a realizar una escritura, se le asigna una nueva página. • Obtener la página deseada desde otro lugar. 5.3.1 Ventajas Ejecutar un programa en la memoria virtual, permite una serie de características positivas que se mencionan a continuación: • Permite que los programas que se ejecutarán en el sistema sean más grandes que la memoria física instalada. • Permite aumentar el grado de multiprogramación. • Sea necesaria menos e/s para intercambiar programas. -* Se implementa generalmente mediante la paginación bajo demanda. 5.3.2 Desventajas Así como las características positivas, se encuentran también varios aspectos negativos que hay que considerar cuando se trabaja con memoria virtual, los cuales son: • La paginación bajo demanda puede afectar significativamente al rendimiento de un sistema informático. Ya que ralentiza el proceso. • Carece de una zona de almacenamiento secundario donde almacenar las páginas. • Hacerlo en un archivo es más flexible, pero hay que sufrir las indirecciones del sistema de archivos. • Hacerlo en una partición o en un disco dedicado es más rápido, pero se pierde flexibilidad. 5.3. Fallos de página 73 Fundamentos de Sistemas Operativos, Release 1.0 • Se pueden ejecutar programas más grandes que la memoria física pero afectando negativamente la velocidad de ejecución del programa. • Dado que a menudo hay que traer páginas a memoria, surge el problema de cuáles reemplazar. 5.4 Copia durante escritura Esta función es muy importante durante la ejecución de los procesos en memoria virtual, porque permite que los procesos padre e hijo puedan compartir las mismas páginas, éstas páginas son marcadas como “copia durante escritura”, esto permite que cualquiera de los dos procesos que se encuentran compartiendo las páginas escriba en alguna de ellas, inmediatamente se realiza una copia de la misma, para que la información escrita pueda estar disponible solamente para el proceso que la escribió en ese momento. Las páginas no modificadas por los procesos seguirán siendo compartidas; además solamente podrán ser marcadas las páginas que puedan ser modificas, por ejemplo, las que no sean las que contienen el código ejecutable. Esta característica ofrecida por la memoria virtual, mejora la eficiencia de la memoria física, ya que es manejada de igual forma por la misma memoria virtual. Así, cuando dos procesos necesiten tener copias diferentes del mismo objeto, entonces la Unidad de Manejo de Memoria (MMU) se encarga de realizar una copia compartida en la memoria virtual y además de marcar ésta como página de “copia durante escritura” en esa región de memoria. 5.4.1 Ventajas y desventajas de la utilización de la memoria virtual Ejecutar un programa en la memoria virtual, permite una serie de características positivas que se mencionan a continuación: Permite que los programas que se ejecutarán en el sistema sean más grandes que 74 Chapter 5. Memoria virtual Fundamentos de Sistemas Operativos, Release 1.0 la memoria física instalada. Permite aumentar el grado de multiprogramación. Sea necesaria menos e/s para intercambiar programas. Se implementa generalmente mediante la paginación bajo demanda. Así como las características positivas, se encuentran también varios aspectos negativos que hay que considerar cuando se trabaja con memoria virtual, los cuales son: La paginación bajo demanda puede afectar significativamente al rendimiento de un sistema informático. Ya que ralentiza el proceso. Carece de una zona de almacenamiento secundario donde almacenar las páginas. Hacerlo en un archivo es más flexible, pero hay que sufrir las indirecciones del sistema de archivos. Hacerlo en una partición o en un disco dedicado es más rápido, pero se pierde flexibilidad. Se pueden ejecutar programas más grandes que la memoria física pero afectando negativamente la velocidad de ejecución del programa. Dado que a menudo hay que traer páginas a memoria, surge el problema de cuáles reemplazar. 5.5 Sustitución de páginas La memoria de una máquina debe compartirse entre los muchos procesos que están siendo ejecutados en la máquina y que solicitan espacios para realizar tareas en memoria, y además entre las demandas de los dispositivos de entrada y salida, como resultado tenemos muchos mecanismos que pretenden hacer una asignación válida y funcional de la memoria con la que cuenta el sistema. Cuando un proceso intenta acceder a una página de memoria que se encuentra ocupada o cuando un proceso solicita memoria y no se encuentra ninguna página disponible se produce lo que conocemos como un fallo de página; si un proceso provoca un fallo de página el sistema lo intentara solucionar haciendo sobreasignación de memoria, el cual es un término para describir los métodos que utiliza el sistema operativo para liberar memoria poder asignar al proceso que provoque un fallo de página. Entre los distintos mecanismos que utilizan los sistemas operativos están: terminar un proceso, o descargarlo de memoria para poder asig- 5.5. Sustitución de páginas 75 Fundamentos de Sistemas Operativos, Release 1.0 narla a nuevos procesos pero el método mas común, y con mejores resultados es la sustitución de páginas, la cual cuenta con varios mecanismos que serán explicados a continuación. 5.6 Mecanismos de sustitución de páginas: 5.6.1 Sustitución Básica La sustitución clásica o básica consiste en un mecanismo muy sencillo, en el cual al producirse un fallo de página al no haber marcos disponibles para un proceso el sistema operativo toma un marco sin ningún criterio para escogerlo, y transcribe su información al espacio de intercambio de la memoria para luego liberar el marco en el que se encontraba dicha información, luego indica el cambio en la tabla de páginas de la memoria. Estos cambios pueden resultar muy costosos en tiempo y rendimiento de la ejecución, debido a que es probable que para poder asignar la memoria correctamente se deba repetir el proceso al menos dos veces, esto debido a la mecánica del procedimiento que podría dejar sin 76 Chapter 5. Memoria virtual Fundamentos de Sistemas Operativos, Release 1.0 espacio a un proceso que ya se estaba ejecutando y éste volvería a solicitar memoria al sistema operativo, para solucionar este problema se utiliza un mecanismo conocido como Bit Sucio o Bit de Modificación, el cual consiste en asociar a cada marco de memoria un bit específico en la memoria, el cual se enciende si el marco es accedido por algún proceso durante el último ciclo de reloj de la máquina, esto facilita escoger si el marco se utiliza o no para sustitución, si fue accedido no se sustituirá ya que es probable que vuelva a ser utilizado en el siguiente ciclo de reloj. 5.6.2 Sustitución de Páginas FIFO El término FIFO es la abreviatura de first in first out qué quiere decir primero en entrar primero en salir y es así precisamente como funciona este algoritmo de sustitución de páginas. El mecanismo funciona de una manera muy sencilla, el administrador de memoria marca o identifica cada página en el orden en que estas fueron cagadas a la memoria, la primera en ser cargada, la segunda en ser cargada y así sucesivamente, dichas marcas sirven para identificar cual pagina sera sustituida, al ocurrir un fallo de pagina la primera de estas que fue cargada a la memoria será la escogida para ser sustitu- 5.6. Mecanismos de sustitución de páginas: 77 Fundamentos de Sistemas Operativos, Release 1.0 ida, luego se cambian las marcas de las demás páginas haciéndolas avanzar un lugar en el orden de entrada y marcando la pagina que recién fue liberada como la última en cargarse. El sistema FIFO es muy sencillo de implementar pero tiene una gran desventaja, una falla en su funcionamiento conocida como la Anomalía de Belady. 5.6.3 Anomalía de Belady La anomalía de Belady, descubierta en 1969 por el científico y computólogo húngaro Laszlo Belady, consiste en un error en el funcionamiento de los algoritmos de sustitución y que, particularmente, es mucho más común cuando se utiliza el método FIFO, consiste en un incremento de los fallos de página según se incrementa el tamaño de la memoria, es decir, cuantos más marcos de memoria tenga el sistema mayor incidencia de fallos de página ocurrirá, esto debido a el funcionamiento del algoritmo. Debido a esta característica el mecanismo de sustitución FIFO es inadmisible para su uso en la administración de memoria actualmente. 78 Chapter 5. Memoria virtual Fundamentos de Sistemas Operativos, Release 1.0 5.6.4 Sustitución Óptima Este mecanismo de sustitución de páginas, como su nombre lo indica, describe la forma mas óptima y acertada para reducir los fallos de página y para asignar los marcos de memoria, de ser esta posible. El algoritmo describe un mecanismo en el cual se asignan para sustitución las páginas que vayan a ser accedidas la menor cantidad de veces en el mayor período de tiempo, es decir, las que se utilicen menos en los próximos X segundos, donde X es un número cualquiera. EL problema con este algoritmo es que, es muy difícil o casi imposible tener una proyección acertada del comportamiento de la memoria, de los accesos, lecturas, cargas y escrituras que se den en las distintas páginas y marcos, ya que esto es sumamente variable, depende de los procesos que se ejecuten y de la interacción que el usuario tenga con la computadora, por lo tanto su implementación real es muy poco realista; este mecanismo se utiliza en mayor parte como comparación de rendimiento con otros algoritmos de sustitución. 5.6.5 Algoritmo LRU El término LRU o por sus siglas en inglés Least Recently Used significa el menos usado recientemente, lo cual hace referencia a como 5.6. Mecanismos de sustitución de páginas: 79 Fundamentos de Sistemas Operativos, Release 1.0 se escogen las paginas para ser sustituidas. El algoritmo funciona monitoreando los bits de referencia o bits sucios de cada una de las páginas de la memoria, y lleva un registro de cómo se han comportado en un determinado lapso de tiempo, al ocurrir un fallo de página el administrador de memoria consulta ese registro de actividad y escoge para la sustitución las páginas que no fueron accedidas del todo recientemente o bien las que fueron menos accedidas, produciendo así un rendimiento muy cercano al del algoritmo óptimo de sustitución. La desventaja de este mecanismo es el elevado costo de implementación y recursos que el algoritmo genera al tener que monitorear y guardar registro de todas el comportamiento de cada página en memoria, lo cual lo vuelve muy inaccesible para la mayoría de los equipos y sistemas. Existen otros métodos muy parecidos a el LRU, como el NRU Not Recently Used o no usado recientemente la diferencia radica en el el NRU solo monitorea el bit de referencia de las páginas, sin tener registro, por lo que sustituye las páginas que no se usaron en el último ciclo de reloj, por lo que podría llegar a descartar páginas que se estén utilizando frecuentemente; además existen otras variaciones que buscan un resultado similar o cercano en rendimiento pero inferior en 80 Chapter 5. Memoria virtual Fundamentos de Sistemas Operativos, Release 1.0 costo y recursos. 5.6.6 Aproximación LRU Una de las variaciones del LRU es el algoritmo de aproximación LRU, el cual busca un resultado semejante reduciendo los costos en procesamiento mediante la implantación de bits físicos o de hardware relacionados con las páginas de memoria,y funcionan como los bits de referencia, con algunos cambios en el funcionamiento del algoritmo que reducen sus costos pero también reducen su rendimiento. 5.6.7 Algoritmo de la Segunda oportunidad EL algoritmo de la segunda oportunidad es una variación del algoritmo FIFO, ya que cuenta con su misma lógica de entrada y manejo de referencia sobre el orden en que ingresaron las páginas, y al igual que el algoritmo FIFO este tomará para la sustitución la primera página que ingreso a la memoria y por ende la más antigua, pero con la diferencia de que, al seleccionar la página mas antigua el algoritmo verifica el bit de referencia, si éste está encendido significa que la página fue accedida en el último ciclo de reloj, y por ende es posible que vuelva a ser necesitada, así que el algoritmo toma la página, apaga su bit de referencia y lo coloca de primero en la cola de páginas, como si fuese la página mas reciente en ingresar, re acomoda toda la cola y vuelve a ejecutarse hasta que encuentre una página con su bit de referencia en 0, al encontrarla es ésta la que es borrada y se ingresa la nueva página en la cola. 5.6.8 Algoritmo de Sustitución por Contador El algoritmo de sustitución por contador, como su nombre lo indica, funciona mediante la asignación de contadores para cada una de las páginas de memoria, los cuales incrementan cada vez que alguna de estas es accedida por un proceso, durante un lapso determinado de 5.6. Mecanismos de sustitución de páginas: 81 Fundamentos de Sistemas Operativos, Release 1.0 tiempo; cuando se produce un fallo de página, el algoritmo puede decidir la sustitución mediante dos enfoques: LFU y MFU. • LFU : siglas de least frequently used que significa menos frecuentemente usada; en este enfoque se sustituye la página con contador menor, ya que, se asume que como no se ha usado recientemente la página ya no se necesitara y se descarta. • MFU: siglas de most frequently used que significa más frecuentemente usada; en este enfoque se sustituye la página con el mayor contador, ya que, se asume que la página con mayor cantidad ya ha sido accedida muchas veces y que por ende ya no se necesite más, se asume también, que las páginas con menor contador son las mas nuevas y que por ende apenas comienzan a utilizarse y deben ser conservadas en la memoria. 5.7 Asignación de Marcos Memoria paginada, es una técnica que permite a los procesos cargar en memoria solamente partes del programa, llamadas páginas de memoria, que son necesarias para su ejecución. El objetivo principal de esta técnica, es el poder ejecutar programas que requieran más memoria que la memoria principal disponible. Los marcos son los espacios donde se alojan las páginas de memoria en la memoria principal. Cada proceso tiene una cantidad de marcos definida. Cuando los procesos agotan los marcos libres y necesitan una página nueva se produce un fallo de página, para liberar un marco de memoria (la página que estaba en ese marco se pasa a memoria secundaria) y se carga la nueva página que se necesita. Aquí surge la pregunta ¿Cuántos marcos se le deben asignar a cada proceso? Para dar respuesta a esta pregunta existen varias técnicas, que se discutirán luego, pero siempre se debe considerar que el mínimo de páginas que se deben asignar a los procesos depende de la arquitectura del sistema, ya que esta dicta el tamaño de las instrucciones y si el proceso no tiene suficiente memoria para ejecutar una instrucción, se producirán fallos de página, constantemente, con el fin 82 Chapter 5. Memoria virtual Fundamentos de Sistemas Operativos, Release 1.0 de poder ejecutar la instrucción, lo cual hará la ejecución del proceso sea más lenta. Por otro lado la cantidad máxima de marcos está dada por la cantidad de memoria primaria disponible; así si se poseen 100kbs de memoria primaria divididos en 10 marcos de 10kbs cada uno, y solamente se tienen disponibles 20kbs, entonces solo se puede asignar como máximo dos marcos a un proceso. 5.7.1 Algoritmos de Asignación de Marcos Los algoritmos de asignación corresponden a los mecanismos utilizados para asignar la cantidad de marcos de página correspondientes a cada proceso. Se distinguen dos algoritmos, Asignación Equitativa, que corresponde a dividir la memoria disponible equitativamente y dar a cada proceso la misma cantidad, y Asignación proporcional, aquí se le asignara más memoria a los procesos que así la requieran con el fin de acelerar su ejecución. Hay que notar que a pesar de que la Asignación equitativa es más fácil 5.7. Asignación de Marcos 83 Fundamentos de Sistemas Operativos, Release 1.0 de entender y de implementar, tiene la desventaja de que todos procesos van a recibir la misma cantidad de memoria independientemente de si la necesitan o no. Por ejemplo los procesos A, B y C van a ser ejecutados en un sistema que utiliza asignación equitativa, por lo que ambos procesos reciben 42kbs de memoria cada uno, pero el proceso A necesita más de 42kbs por lo que su taza de fallos de página se incrementa y su ejecución se ralentiza, mientras que los procesos B y C solamente necesitan 10kbs y 30kbs, respectivamente, por lo que se están desperdiciando 44kbs de memoria que podría utilizar el proceso A para reducir su taza de fallos de página y así acelerar su ejecución. La Asignación Proporcional solventa el problema de la asignación equitativa, al asignar la memoria de acuerdo a las necesidades de los procesos. Pero ambos mecanismos, tanto la asignación equitativa como proporcional, tienen la desventaja de que todos los procesos son tratados igual, así procesos de alta prioridad pero que requieran poca memoria van a recibir poca memoria, y su ejecución podría ralentizarse. Para solventar este problema se puede utilizar un mecanismo de asignación proporcional, pero en lugar de basarse en el tamaño del proceso se debe basar en la prioridad del mismo. De esta manera procesos de alta prioridad reciben más memoria, haciendo que se ejecuten más rápido. 5.7.2 Asignación Local y Asignación Global Otro factor importante es la forma en que estos marcos de página son asignados a entre todos los procesos ejecutables. Se distinguen dos formas Asignación Local, donde todos los procesos reciben una fracción fija de la memoria, y la Asignación Global, donde los procesos reciben marcos de memoria de forma dinámica durante su ejecución, es decir, la cantidad de marcos asignada a un proceso puede cambiar durante su ejecución. También se debe considerar el concepto de sobrepaginación, este fenómeno ocurre cuando un proceso no tiene suficientes marcos de memoria para llevar a cabo sus tareas, esto provoca que aumente la 84 Chapter 5. Memoria virtual Fundamentos de Sistemas Operativos, Release 1.0 taza de fallos de página por lo que la ejecución del proceso se ralentiza. La Asignación Local de Marcos, como ya se mencionó anteriormente, asigna una fracción fija de la memoria disponible. Debido a esto se los procesos pueden entrar en sobrepaginación a pesar de que pueden existir marcos de memoria libres, debido a que los procesos no pueden recibir más memoria durante la su ejecución. En cambio la Asignación Global de Marcos, asigna una fracción de la memoria disponible al proceso, cuando inicia su ejecución, pero esta cantidad puede cambiar durante el tiempo de ejecución del proceso. De esta manera si los procesos entran en sobre paginación pueden solicitar marcos de memoria extra, ya sea de memoria libre o de otro proceso en ejecución, como se muestra en la imagen anterior, donde el proceso Y entra en sobrepaginación y se le es asignada memoria del proceso X y del Proceso Z, representadas con líneas punteadas Aquí se debe tener cuidado debido a que si un proceso entro en sobre paginación, y solicita más marcos de memoria, pero no hay marcos 5.7. Asignación de Marcos 85 Fundamentos de Sistemas Operativos, Release 1.0 libres, entonces se va a proceder a quitarle marcos a otros procesos lo cual puede producir que estos procesos, a su vez entren en sobrepaginacion. Para solventar el problema anterior se utilizan una cota inferior, para indicarnos la cantidad mínima de marcos que puede tener un proceso, de forma que no entre en sobrepaginación. Es importante mencionar que el modelo más utilizado es el de Asignación Global con Asignación proporcional puesto a que se incrementa la taza de procesamiento del sistema. 5.7.3 Tamaño de los Marcos El concepto de tamaño de los marcos hace referencia al tamaño que deben tener los marcos de página, nótese que los marcos y las paginas tienen el mismo tamaño. La fragmentación interna se refiere a la cantidad de memoria dentro de una página que no es utilizada. Por ejemplo, si un sistema tiene páginas de memoria de 10kbs cada una y un proceso X necesita 6kbs de memoria, el sistema le asignara una página de memoria la proceso, aquí ocurre una fragmentación interna puesto a que se están desperdiciando 4kbs de los 10kbs que recibió el proceso. Generalmente, una vez definido el tamaño de las páginas de memoria en el diseño de un sistema no se puede cambiar. Por lo que se debe tomar la decisión de que si se va a utilizar un tamaño grande o pequeño para los marcos. El utilizar un tamaño pequeño tiene la ventaja de que se reduce la fragmentación interna de la memoria, y se aprovecha mejor la memoria, pero se producirán más fallos de página. Esto debido a que la información necesaria para la ejecución del proceso estará distribuida entre más páginas. Por otro lado el utilizar un tamaño grande para las paginas tiene la ventaja de que se reducen los fallos de página, y se reducen los tiempos de E/S, ya que las paginas pueden almacenar fragmentos más grandes de los archivos por lo que el tiempo de E/S se reduce, pero 86 Chapter 5. Memoria virtual Fundamentos de Sistemas Operativos, Release 1.0 como ya se mencionó anteriormente la fragmentación interna se aumenta. 5.8 Sobrepaginación o Hiperpaginación Como ya se mencionó anteriormente la Sobrepaginación o Hiperpaginación es un fenómeno que ocurre cuando un proceso sufre de muchos fallos de página continuamente, provocando que la mayor parte del tiempo de ejecución del mismo sea consumido por el proceso de trata de fallos de página Este problema es no es tan grave si se utiliza la Asignación Local, ya que si un proceso se sobrepágina, no afecta a los demás procesos en ejecución. Pero también existe la posibilidad de que el si el proceso no se sobrepágina se pueda estar desperdiciando memoria, ya que puede no necesitar toda la memoria asignada. En cambio cuando se utiliza la Asignación Global, el problema de la sobrepaginación es más grave, ya que como se mencionó anteriormente si un proceso se sobrepágina es posible que se terminen sobrepaginando otros procesos. Para clarificar esto considere el siguiente ejemplo, en un sistema actualmente están corriendo tres procesos X, Y y Z, de los cuales X necesita más memoria y termina sobrepaginándose, como no hay memoria libre para poder asignarle el Sistema Operativo le quita memoria a los procesos Y y Z para asignársela al proceso X, pero aun así el proceso X necesita más memoria y continua sobrepaginado. Al reducir la memoria de los procesos Y y Z provoca que se sobrepaginen, en consecuencia la taza de procesamiento del sistema disminuye, por lo que la ejecución de los procesos se ralentiza considerablemente. 5.8.1 Control de Carga Esta es una técnica para lidiar con la sobrepaginación de procesos en los sistemas con Asignación Global. La idea principal de este algoritmo es que cuando haya una sobrepaginación de procesos, y no 5.8. Sobrepaginación o Hiperpaginación 87 Fundamentos de Sistemas Operativos, Release 1.0 exista memoria libre, así como tampoco se le puede quitar memoria a otros procesos, se debe pausar la ejecución de un proceso de baja prioridad y descargarlo de memoria principal, para liberar la memoria que tenía asignada y poder utilizarla para acelerar la ejecución de los demás procesos. Normalmente el proceso seleccionado para ser pausado se copia a la región de swap de la memoria secundaria, y la memoria primaria que tenía ocupada se le asigna a los demás procesos para que continúen su ejecución, como se muestra en la imagen anterior, donde el proceso C es descargado a la region de swap y su memoria es asignada a los procesos A y B. Cuando el sistema detecta que ya no hay procesos sobrepaginados y la taza de procesamiento del sistema es baja se toma proceso, que se descargó a la región de swap, y se restaura en memoria primaria para que continúe con su ejecución. 88 Chapter 5. Memoria virtual Fundamentos de Sistemas Operativos, Release 1.0 5.9 Asignación de Memoria del Kernel Para la asignación de memoria del kernel se debe tener en cuenta de que el Kernel debe mantener estructuras de datos de tamaños variables, por lo que hay que tener cuidado con la fragmentación interna, en miras de no desperdiciar memoria. Además es posible que ciertos dispositivos de hardware interactúen directamente con la memoria sin utilizar la interfaz de memoria virtual, por lo que no se puede asignar memoria de forma paginada, y se debe asignar memoria contigua. Los mecanismos de los que se discutirán en las siguientes secciones tienen el objetivo de asignar memoria continua al kernel de forma que se minimice la fragmentación interna y no afecte a los dispositivos de hardware que interactúan directamente con la memoria. 5.9.1 Asignación de Slaps Como ya se mencionó anteriormente, este es un mecanismo para asignar memoria al kernel. Utiliza slaps o franjas, que están compuestas por una o más páginas de memoria físicamente continuas, y una cache formada por una o más franjas. La idea principal de este sistema es asignarle a cada cache un tipo de estructura de datos, por ejemplo hay una cache para los descriptores de procesos, otra para los objetos de archivos, otra para los semáforos y así sucesivamente. Cada una de estas caches solamente podrá almacenar instancias del tipo es estructura de datos asignada a esa cache, así la cache de semáforos solamente podrá almacenar objetos del tipo semáforo y así sucesivamente, tal y como se ve en la imagen anterior. Inicialmente cuando una cache se crea se le asigna el tipo de estructura a almacenar y la cantidad máxima de instancias que puede contener, esta cantidad depende de la cantidad y el tamaño de las franjas asignadas a la cache. Cuando se necesite crear un nuevo objeto el asignador toma un espacio libre de la cache se la asigna al nuevo objeto. 5.9. Asignación de Memoria del Kernel 89 Fundamentos de Sistemas Operativos, Release 1.0 De igual manera cuando un objeto se necesita eliminar, el asignador marca el espacio, asignado al objeto, en la cache como libre y este se puede volver a asignar a otro nuevo objeto. Con este sistema la fragmentación no es problema, ya que cuando el sistema solicita memoria para un objeto el asignador devuelve la cantidad exacta de memoria requerida para ese objeto. Además las solicitudes de memoria se satisfacen más rápidamente debido a que la asignación de slaps o franjas es particularmente efectivo en aquellas situaciones en la asignación y desasignación de memoria ocurre frecuentemente. 5.9.2 Buddy System Este mecanismo, al igual que el anterior, tiene el propósito de asignar memoria al kernel. Este se diferencia al anterior en que en lugar de tener un conjunto de caches compuestas por segmentos de memoria continua, cuenta con un segmento de memoria continúa del tamaño 90 Chapter 5. Memoria virtual Fundamentos de Sistemas Operativos, Release 1.0 de una potencia de 2. Este segmento se divide en 2, generando dos subsegmentos cuyo tamaño es una potencia de 2 y a su vez cada subsegmento se divide en 2 hasta que se encuentre con un subsegmento del tamaño exacto a la cantidad de memoria solicitada por el kernel. Dado el caso de que la cantidad solicitada por el kernel no sea potencia de 2 se le asigna un subsegmento cuyo tamaño sea igual a la próxima potencia de dos del tamaño solicitado por el kernel. Para clarificar considere la imagen anterior, suponga que el kernel solicita 10 kbs de memoria para almacenar una estructura. Entonces el asignador parte del segmento de memoria continua más grande que tiene, en este caso de 128 kbs, y lo divide en dos generando dos bloques de 64 kbs cada uno. El asignador comprueba que todavía el segmento de 64 kbs se puede dividir y la estructura puede caber en alguno de los subsegmentos resultantes, por lo que se divide uno de los segmentos de 64 kbs y se generan dos subsegmentos de 32 kbs, uno de estos segmentos a su vez se divide en dos generando dos subsegmentos de 16 kbs. En este punto el asignador nota que no puede 5.9. Asignación de Memoria del Kernel 91 Fundamentos de Sistemas Operativos, Release 1.0 seguir dividiendo los segmentos, puestos a que la estructura no cabría, por lo que el asignador almacena la estructura en uno de los bloques de 16 kbs. Así la fragmentación interna se reduce y este sistema tiene la ventaja de que tanto la división como la fusión de segmentos es muy rápida, por lo tanto puede satisfacer rápidamente las solicitudes de memoria. Este sistema es utilizado en los Sistemas Operativos Linux. 5.10 Glosario • Asignación Equitativa: Es un mecanismo de asignación de memoria para los procesos donde la memoria principal disponible se divide de forma equitativa entre todos los procesos. • Asignación Global: Es una forma de asignar memoria paginada a los procesos, donde los procesos tiene un cantidad inicial de memoria, pero que puede cambiar durante su ejecución dependiendo de sus necesidades. • Asignación Local: Es un forma de asignar memoria paginada a los procesos, donde cada proceso tiene una cantidad de fija de memoria que no puede cambiar durante la su ejecución. • Asignación Proporcional: Es un mecanismo de asignación de memoria para los procesos, aquí la memoria principal disponible se divide entre todos los procesos dependiendo de las necesidades de cada proceso. De forma que un proceso más grande reciba más memoria. • Buddy System: Sistema para la asignación de memoria continua para estructuras del kernel, utilizado por los Sistemas Operativos Linux • Fragmentación interna: Fragmentación de memoria que ocurre dentro de una página de memoria de un proceso, es decir porción de memoria desperdiciada por el proceso. 92 Chapter 5. Memoria virtual Fundamentos de Sistemas Operativos, Release 1.0 • Marco de Página: Campo en memoria principal donde se puede alojar una página de memoria. • Memoria virtual: Técnica que permite la ejecución de procesos que no se encuentran completamente en memoria, además permite la compartición de archivos y de bibliotecas entre los diferentes procesos • Página de Memoria: Segmento de memoria de un proceso, que se carga en memoria solamente cuando es necesario para que procesos ejecute un tarea. • Slap: Franja formada por una o varias paginas de memoria contiguas, que solamente puede almacenar estructuras de un tipo definido. 5.11 Notas Bibliográficas • Silberschatz, A., Galvin, P. & Gagne, G. (2013). Operating System Concepts (Novena ed.) Denver: John Wiley & Sons, Inc. • Carretero pérez, J., García carballeira, F., Miguel anasagasti, P. & Pérez costoya, F. (2001). Sistemas Operativos Una visión aplicada (Primera ed.) Madrid: McGRAWHILL/INTERAMERICANA DE ESPAÑA, S.A.U.. • Wolf, G. (s. f.). Administración de Memoria: Memoria Virtual Recuperado de http://sistop.gwolf.org/laminas/12memoria-virtual.pdf • Silberschatz, A. (2013). Fundamentos de Sistemas Operativos. • Wolf, G. (2013). Sistemas Operativos - Administración de Memoria. En G. Wolf, Sistemas Operativos - Administración de Memoria. • Oracle. (2014). Gestión de sistemas de archivos. Obtenido de http://docs.oracle.com/cd/E56339_01/html/E53910/fsswap89187.html 5.11. Notas Bibliográficas 93 Fundamentos de Sistemas Operativos, Release 1.0 • Carretero Pérez J., García Caballeira F., Anasagasti P., Pérez Costoya F. (2001).Sistemas operativos: Una visión aplicada (1st ed.). Madrid: McGraw-Hill. • Tanenbaum A. S., Romero Elizondo A. V. (2009). Sistemas operativos modernos. México: Pearson Education. • Tanenbaum, A. S., & Palmas Velasco, O. A. (1996). Sistemas operativos distribuidos. México: Prentice Hall Hispanoamericana. • Silverchatz A., Galvin Baer P., Gagne G. (2006). Fundamentos de Sistemas Operativos. Madrid: McGraw-Hill. • Buddy System|Memory allocation|Operating Systems. (n.d.). Retrieved April 24, 2015, from http://dysphoria.net/OperatingSystems1/4_allocation_buddy_system.html 94 Chapter 5. Memoria virtual CHAPTER 6 Sistemas de archivos Recopilado por: Juan Guevara Jiménez y Marco Navarro Navarro. El objetivo principal de una computadora es crear, manipular, almacenar y retornar datos. El sistema de archivos es uno de los actores que provee la funcionalidad necesaria para dar soporte a esas tareas. Desde un punto de vista general un sistema de archivos se encarga de organizar, almacenar, retornar y manejar información en un dispositivo de almacenamiento permanente como un disco. Los sistemas de archivos forman parte integral de cualquier sistema operativo. 6.1 Diseño de sistemas de almacenamiento Existen varias estrategias para realizar la gestión de almacenamiento permanente. Por un lado están los sistemas de archivos que imponen restricciones suficientes para incomodar a los usuarios, provocando que su uso sea difícil. En el otro extremo están los sistemas de almacenamiento de objetos persistentes y bases de datos orientadas a objetos, que abstraen la noción completa de almacenamiento permanente de manera que ni el usuario ni el programador necesiten percatarse de ello. 95 Fundamentos de Sistemas Operativos, Release 1.0 El problema de almacenar, retornar y manipular información en una computadora es de una naturaleza tan general que hay muchas maneras de resolverlo. No hay una forma “correcta” de escribir un sistema de archivos. Al decidir qué tipo de sistema de archivo es apropiado para un sistema operativo en particular, debemos sopesar las necesidades del problema con las otras restricciones del proyecto. Por ejemplo, una tarjeta flash-ROM tal como se usa en algunas consolas de videojuegos tiene poca necesidad de una interfaz avanzada de búsqueda o soporte para atributos. La confiabilidad de que los datos sean escritos al dispositivo, no obstante, es crítica, entonces un sistema de archivos que soporte “journaling” (registro por diario) puede ser un requisito. De igual forma, un sistema de archivos para una computadora de alta gama (mainframe) requiere de un rendimiento extremadamente rápido en muchas áreas, pero poco en características amigables con el usuario, entonces técnicas que habilitan mas transacciones por segundo ganarían peso sobre aquella que hacen mas fácil para el usuario localizar archivos obscuros. Es importante tener en mente la meta abstracta de lo que un sistema de archivos debe lograr: almacenar, retornar, localizar y manipular información. Mantener la meta declarada en términos generales nos libera para pensar en implementaciones alternativas y posibilidades que de otro modo, no surgirían si tuviéramos que pensar en un sistema de archivos como una estructura típica, estrictamente jerárquica, basada en disco. 6.2 Tipos de sistemas de archivo En la actualidad podemos encontrar muchos ejemplos de sistemas de archivos. Sin embargo estos sistemas podrían potencialmente ubicarse en alguno de los siguientes tipos, dependiendo de la estrategia de implementación de los desarrolladores. 96 Chapter 6. Sistemas de archivos Fundamentos de Sistemas Operativos, Release 1.0 6.2.1 Sistemas de archivos estructurados por registro Los avances en el aspecto tecnológico están ejerciendo presión sobre los sistemas de archivos actuales. La aparición de procesadores más veloces, discos más grandes y de menor costo (pero no mucho mas rápidos) y las memorias aumentando su tamaño de manera exponencial; con estos factores en juego, el único parámetro que no está teniendo grandes avances es el tiempo de búsqueda en disco. Un cuello de botella de funcionamiento está creciendo en muchos sistemas de archivos. Los investigadores en Berkeley trataron de aliviar este problema al diseñar un tipo de sistema de archivos completamente nuevo llamado LFS (Log-structured File System, sistema de archivos estructurado por registro). Dicho sistema es una re-implementación de UNIX. La idea que dio lugar al diseño de este sistema de archivo, es que a medida que los procesadores y las memorias RAM aumentan su capacidad, las cachés de disco crecen también. Producto de ello, ahora es posible satisfacer una fracción considerable de todas las peticiones de lectura desde la caché, sin requerir acceso directo al disco. Se toma el disco como una unidad completa, estructurándole como un registro. Este sistema coloca todas las escrituras en un búffer en memoria y periódicamente se escriben en el disco en un solo segmento al final del registro. Dado que un disco es de tamaño limitado puede darse el problema de que este se llene, para lidiar con ello, este tipo de sistema de archivos tiene implementado un hilo limpiador que explora el registro para compactarlo. Su función es buscar segmentos en el registro de archivos que hayan sido borrados o sobre-escritos de manera que no estén siendo apuntados por nodos-i (nodos índice). 6.2.2 Sistemas de archivos por bitácora La idea básica de tener una bitácora es llevar un registro de lo que va a realizar el sistema de archivos antes de hacerlo, de manera que si ocurre una falla antes de que pueda realizar las tareas planeadas, 6.2. Tipos de sistemas de archivo 97 Fundamentos de Sistemas Operativos, Release 1.0 posteriormente al momento de reiniciar el sistema pueda buscar en el registro para ver lo que estaba ocurriendo al momento de la falla y proceder a ejecutar las tareas pendientes. Ejemplos típicos son el sistema de archivos NTFS de Microsoft, así como los sistemas ext3 y ReiserFs de Linux. Al utilizar una bitácora, la recuperación de errores puede ser rápida y segura. Este sistema está fundamentado en el concepto de bases de datos conocido como transacción atómica. Así, se pueden agrupar varias operaciones entre un principio y fin de transacción. De esta forma el sistema de archivos sabe que debe completar todas las operaciones agrupadas o ninguna de ellas. 6.2.3 Sistemas de archivos virtuales El fundamento básico es abstraer la parte del sistema de archivos que es común para todos los sistemas de archivos y poner ese código en una capa separada que sirva de interfaz entre el sistema operativo y el sistema de archivos para administrar los datos. Todas las llamadas al sistema operativo relacionadas con archivos pasan primero por el sistema de archivos virtual para ser procesados. Estas llamadas, son las llamadas de POSIX estándar, tales como open, read, write, lseek, etc. Posteriormente una vez procesadas, se llama a la rutina correspondiente en el sistema operativo. La implementación de este tipo de sistema de archivo, permite que existan varios sistemas de archivos integrados como una sola estructura, es decir, que desde la perspectiva del usuario solo existe una jerarquía de sistemas de archivos. 6.3 Localización de bloques Un sistema de archivos debe dar seguimiento de cuáles bloques pertenecen a cada archivo; deben además dar seguimiento también a los bloques que están disponibles. Cuando se crea un nuevo archivo, el sistema de archivos localiza un bloque disponible y lo asigna. 98 Chapter 6. Sistemas de archivos Fundamentos de Sistemas Operativos, Release 1.0 Cuando un archivo es borrado el sistema de archivos pone los bloques como disponibles para asignarlos posteriormente. Las metas para lograr un buen sistema de asignación son: • Velocidad: Asignar y liberar bloques debería ser una tarea rápida. • Uso mínimo del espacio: Las estructuras de datos usadas por el asignador deberían ser pequeñas, dejando tanto espacio como sea posible para guardar datos. • Fragmentación mínima: Si algunos bloques son dejados sin usar, o algunos son solamente utilizados de manera parcial, al espacio que no se utiliza se le llama fragmentación. Si se diera el caso el sistema asignador debiera ser capaz de usar dichos espacios o reducirlos al mínimo posible. • Contiguidad Máxima: Aquellos datos que son utilizados al mismo tiempo, deberían estar ubicados físicamente contiguos en disco de ser posible para mejorar el rendimiento. Diseñar un sistema de archivos que cumpla estos objetivos es una tarea difícil, pues el rendimiento del mismo está ligado a las características de carga de trabajo que vaya a tener, por ejemplo el tamaño de archivo, patrones de acceso, etc. Un sistema que ha sido diseñado para cumplir con los requerimientos de una carga de trabajo podría no desempeñarse bien para un carga diferente. 6.4 Métodos de localización La naturaleza del acceso directo a los discos nos da flexibilidad en la implementación de archivos. En la mayoría de los casos los archivos son almacenados en el mismo disco. El problema que queda por solventar es como asignar el espacio a estos archivos de manera que el espacio del disco sea aprovechado eficientemente y los archivos puedan ser accesados rápidamente. A continuación se enumeran las tres estrategias para localización de bloques. 6.4. Métodos de localización 99 Fundamentos de Sistemas Operativos, Release 1.0 6.4.1 Asignación Contigua Este método consiste en asignarle a un archivo un conjunto de bloques contiguos en el disco. Las direcciones (identificador inequívoco de cada bloque en disco) definen un orden lineal en el disco, es decir las direcciones están en orden ascendente. De esta forma, asumiendo que solamente una tarea está utilizando el disco, accesar el bloque b + 1 después de un bloque b no requiere movimiento de la cabeza lectora. Cuando se requiere movimiento de la cabeza (esto es pasar del último sector de un cilindro al primer sector del siguiente cilindro), la cabeza necesita solamente moverse una posición al siguiente cilindro. Así, el número de búsquedas en el disco para acceder a los archivos asignados contiguamente es mínimo, así como el tiempo para su lectura. El problema inherente a la asignación contigua es la dificultad para encontrar espacio para ubicar un nuevo archivo. Si bien no ocurre cuando el disco está vacío, cuando ya hay datos suficientes será difícil encontrar un espacio contiguo completo para ubicar archivos de gran tamaño. Como respuesta a este problema, se han utilizado las técnicas best fit y first fit para asignar el espacio. Otros sistemas utilizan un sistema de asignación contigua modificado. Inicialmente se localiza y asigna un trozo de espacio contiguo, luego, si el espacio no es lo suficientemente grande, otro trozo de espacio contiguo, conocido como extensión es añadido. 6.4.2 Asignación Enlazada La asignación enlazada vino a solventar los problemas de la asignación contigua. Con este método el archivo se visualiza como una lista enlazada de bloques en el disco duro sin importar si estos son contiguos o no. El directorio es quién contiene el puntero al primer y último bloque del archivo. Para crear un nuevo archivo, simplemente se crea una nueva entrada en el directorio y se actualiza el puntero final si se requiere. Al representar los archivos como bloques dispersos, este método es únicamente eficiente para archivos de acceso secuencial, es decir 100 Chapter 6. Sistemas de archivos Fundamentos de Sistemas Operativos, Release 1.0 archivos que requieran ser accesados completos de inicio a fin. Por ejemplo, si requerimos accesar un bloque específico del archivo, tendremos que recorrer la lista enlazada para localizar este bloque, lo cual es lento pues en cada accceso a un bloque se requiere una lectura de disco y en ocasiones una búsqueda. Otro inconveniente es el espacio que se requiere para almacenar los punteros. Si un puntero necesita 4 bytes de un bloque de tamaño de 512 bytes, entonces el 0.78% del disco será utilizado por punteros de bloques de archivo, en lugar de información. Para resolver este inconveniente, se juntan los bloques en múltiplos, llamados clúster y en lugar de asignarle un bloque a un archivo se le asignan grupos de cluster. La definición del tamaño de un cluster queda a decisión del desarrollador y de la capacidad del sistema operativo para manejarlo. De esta forma, los punteros usan un porcentaje mas pequeño del espacio del disco. Otra estrategia utilizada ha sido la creación de una tabla de localización de archivos o FAT, que es un conjunto específico de bloques en disco, utilizado para almacenar todos los índices. Esta estrategia 6.4. Métodos de localización 101 Fundamentos de Sistemas Operativos, Release 1.0 permite facilitar el acceso directo a los archivos pues las direcciones se buscan en la FAT que por lo general estará cargada en memoria, de esta forma no se requiere acceso a disco para la búsqueda del bloques de archivo. Sin embargo, un problema que esto conlleva es que a mayor tamaño de disco, mayor tamaño requerirá la FAT lo que implica que la carga en memoria será mas grande también. 6.4.3 Asignación Indexada Dados los problemas con el método de asignación enlazada, la solución fue mantener la lista de bloques para cada archivo de manera separada. Así, cada archivo tiene sus bloques índice que incluyen apuntadores a los bloques de archivos en disco. La ventaja que genera manejar la asignación de esta forma, es que basta con traer el bloque de índices del archivo a memoria. Así podemos encontrar rápidamente el puntero al bloque b de un archivo y accederlo sin necesidad de ir bloque por bloque como en la asignación 102 Chapter 6. Sistemas de archivos Fundamentos de Sistemas Operativos, Release 1.0 enlazada. Aún con las ventajas descritas el costo a pagar por ello es el espacio extra requerido para los bloques de índices. Este problema fue resuelto posteriormente en UNIX BSD con un sistema de índices multinivel, el cuál es el utilizado actualmente en las distribuciones de Unix y Linux. Esta idea permitió almacenar archivos pequeños sin necesidad de crear un bloque de índices. Otras alternativas desarolladas han sido la asignación indexada enlazada y la asignación indexada conbinada. En la primera, el nodo índice no solamente puede referenciar a bloques sino también a datos. La asignación combinada es la combinación de la multinivel y la enlazada. 6.4. Métodos de localización 103 Fundamentos de Sistemas Operativos, Release 1.0 104 Chapter 6. Sistemas de archivos Fundamentos de Sistemas Operativos, Release 1.0 6.5 Directorios Un archivo no es más que un conjunto de bytes relacionados que están en disco u otro medio, a los que se les asigna un nombre que se utilizara para referirse a este archivo. Un directorio no es más que un archivo común a los que se les ha impuesto una estructura particular. Los directorios tienen información que apunta hacia la ubicación de los archivos reales. Esta información (tanto en los archivos y directorios) junto con el nombre del creador, tamaño, permisos, etc, es guardada en lo que se denomina TABLA DE INODOS en ciertos tipos de sistemas operativos. El sistema de archivos crea esta tabla que contendrá la mayoría de la información de los archivos. Técnicamente el directorio almacena información acerca de los archivos que contiene: como los atributos de los archivos o dónde se encuentran físicamente en el dispositivo de almacenamiento. En el entorno gráfico de los sistemas operativos modernos, el directorio se denomina metafóricamente carpeta y de hecho se representa 6.5. Directorios 105 Fundamentos de Sistemas Operativos, Release 1.0 con un icono con esta figura. Esta imagen se asocia con el ambiente administrativo de cualquier oficina, donde la carpeta de cartón encierra las hojas de papel de un expediente. Archivos y directorios no pueden ser diferenciados a través del nombre, sino solo a través de las herramientas del sistema operativo, las que además muestran otras propiedades de archivos y directorios, como fecha de creación, fecha de modificación, usuarios y grupos de usuarios que tienen acceso o derechos al archivo o directorio. Se le llama directorio-padre al directorio que contiene dentro de si otros directorios para formar una jerarquía de directorios que mantenien estructurados todos los archivos propios de un programa o destinados a un propósito específico. 6.6 Concepto de directorio Un directorio es un objeto que relaciona de forma unívoca un nombre de archivo (dado por el usuario) con su descriptor interno, también or106 Chapter 6. Sistemas de archivos Fundamentos de Sistemas Operativos, Release 1.0 ganiza y proporciona información sobre la estructuración del sistema de archivos. Un directorio puede verse como una colección de listados que contienen información acerca de los archivos. Esta es una unidad de organización interna del sistema operativo que se utiliza para localizar archivos. 6.7 Visión lógica de los directorios Los directorios se caracterizan por estar organizados en un esquema jerárquico. Las acciones principales que se pueden realizar sobre un directorio son las siguientes: • Crear (insertar) y borrar (eliminar) directorios. • Abrir y cerrar directorios. • Renombrar directorios. • Combinar dos directorios distintos. Cuando se pide abrir un archivo el Sistema Operativo busca el nombre en la estructura de dicho directorio. La organización jerárquica de un directorio: • Simplifica el nombrado de archivos ya que se le asignan nombre únicos que el usuario proporciona a su gusto. • Proporciona una gestión de la distribución ya que agrupa archivos de forma lógica y a gusto del usuario. 6.8 Estructura de los directorios Tanto la estructura del directorio como los archivos residen en disco. Por tanto, los directorios se suelen implementar como archivos: • Información en un directorio: nombre, tipo, dirección, longitud máxima y actual, tiempos de acceso y modificación, dueño, etc. 6.7. Visión lógica de los directorios 107 Fundamentos de Sistemas Operativos, Release 1.0 • Hay estructuras de directorio muy distintas. La información depende de esa estructura. Dos alternativas principales: • Almacenar atributos de archivo en entrada directorio. • Almacenar , con datos archivo en una estructura distinta. Ésta es mejor opción. A los usuarios les interesa la forma de nombrar sus archivos, las operaciones que pueden efectuarse en ellos, el aspecto que tiene el árbol de directorios y cuestiones de interfaz por el estilo. A los implementadores les interesa como están almacenados los archivos y directorios, como se administra el espacio en disco y como puede hacerse para que todo funcione de forma eficiente y confiable. 6.9 Implementación de Directorios Cuando se abre un archivo, el sistema operativo usa el nombre de la ruta proporcionado por el usuario para localizar la entrada del directorio. 6.9.1 Directorios en MS-DOS Los directorios pueden tener otros directorios, dando lugar a un sistema de archivos jerárquicos. En este sistema operativo es común que los diferentes programas de aplicación comiencen por crear un directorio en el directorio raíz pongan ahí todos sus archivos, con objeto que no halla conflictos entre las aplicaciones. 6.9.2 Directorios en UNIX La estructura de directorios es extremadamente sencilla. Cuando se abre un archivo, el sistema de archivos debe tomar el nombre que se le proporciona y localizar sus bloques de disco. 108 Chapter 6. Sistemas de archivos Fundamentos de Sistemas Operativos, Release 1.0 6.10 Administración Disco del Espacio en Es de interés primordial para los diseñadores de sistemas de archivos. Hay dos posibles estrategias para almacenar un archivo de n bytes: asignar n bytes consecutivos de espacio en disco, o dividir el archivo en varios bloques (no necesariamente) contiguos. Tamaño de bloque Una vez que se ha decidido almacenar archivos en bloques de tamaño fijo, surge la pregunta de qué tamaño deben tener los bloques. Dada la forma como están organizados los discos, el sector, la pista y el cilindro son candidatos obvios para utilizarse como unidad de asignación. En un sistema con paginación, el tamaño de página también es un contendiente importante. Administración de bloques libres Una vez que se ha escogido el tamaño de bloque, el siguiente problema es cómo seguir la pista a los bloques libres. Se utilizan ampliamente dos métodos. El primero consiste en usar una lista enlazada de bloques de disco, en la que cada bloque contiene tantos números de bloques de disco libres como quepan en él. El mapa de bits. Un disco con n bloques requiere un mapa de bits con n bits. Los bloques libres se representan con unos en el mapa, y los bloques asignados con ceros (o viceversa). 6.11 Rendimiento Archivos del Sistema de El acceso a un disco es mucho más lento que el acceso a la memoria. La lectura de una palabra de memoria por lo regular toma decenas de nanosegundos. La lectura de un bloque de un disco duro puede tardar 50 microsegundos. La técnica más común empleada para reducir los accesos a disco es el caché de bloques o el caché de buffer. 6.10. Administración del Espacio en Disco 109 Fundamentos de Sistemas Operativos, Release 1.0 6.12 Organización del directorio Se debe tener en cuenta la eficiencia, es decir, localizar un archivo rápidamente. El nombrado de los directorios debe ser conveniente y sencillo para los usuarios: • Dos usuarios pueden tener el mismo nombre para archivos distintos. • Los mismos archivos pueden tener nombres distintos. • Nombres de longitud variable. • Agrupación: agrupación lógica de los archivos según sus propiedades (por ejemplo: archivos del trabajo o universidad, juegos, etc.). • Sencillez: la entrada de directorio debe ser lo más sencilla posible. 6.13 Estructura física del directorio Los directorios son una tabla contigua con entradas de tamaño fijo. Los directorios son poco flexibles. En grandes directorios la búsqueda es lenta. 6.14 Funcionamiento del directorio 6.14.1 Compartir archivos En los sistemas operativos multiusuario, se puede desarrollar este tipo de actividad que he permitir a otros usuarios a accesar a los archivos que otro usuario distribuye. Siempre que tengan los derechos de acceso. 110 Chapter 6. Sistemas de archivos Fundamentos de Sistemas Operativos, Release 1.0 6.14.2 Agrupación de registros La ejecución de entradas y salidas, los registros se ubican en tres bloques: 6.14.3 Bloque fijo Los registros son guardados en un bloque por su longitud fija y por un número entero de registros, puede haber espacios sin utilizar en cada bloque. 6.14.4 Bloque de longitud variable por tramos Los registros son variables por su longitud y se agrupan en bloques no se dejan espacios. 6.14.5 Bloque de longitud variable sin tramos se usan registros de longitud variable pero no se dividen en tramos. Casi todos los bloques hay un espacio desperdiciado ya que no se aprovechan el espacio libre de este. 6.14.6 Gestión de almacenamiento secundario Es responsable de asignar los bloques a los archivos, pero esto crea dos problemas, uno es que el espacio del almacenamiento secundario se le asigna a los archivos, segundo, es la necesidad de dejar espacios libres para asignar de modo que estas dos tareas se relacionan entre sí, ya que esto influye en el método de gestión del espacio libre. 6.14. Funcionamiento del directorio 111 Fundamentos de Sistemas Operativos, Release 1.0 6.15 Permisos de archivos y directorios En cualquier sistema multiusuario, es preciso que existan métodos que impidan a un usuario no autorizado copiar, borrar, modificar algún archivo sobre el cual no tiene permiso. En Linux las medidas de protección se basan en que cada archivo tiene un propietario (usualmente, el que creó el archivo). Además, los usuarios pertenecen a uno o más grupos, los cuales son asignados por el Administrador dependiendo de la tarea que realiza cada usuario; cuando un usuario crea un archivo, el mismo le pertenece también a alguno de los grupos del usuario que lo creó. Así, un archivo en Linux le pertenece a un usuario y a un grupo, cada uno de los cuales tendrá ciertos privilegios de acceso al archivo. Adicionalmente, es posible especificar qué derechos tendrán los otros usuarios, es decir, aquellos que no son el propietario del archivo ni pertenecen al grupo dueño del archivo. En cada categoría de permisos (usuario, grupo y otros) se distinguen tres tipos de accesos: lectura (Read), escritura (Write) y ejecución (eXecute), cuyos significados varían según se apliquen a un archivo o a un directorio. En el caso de los archivos, el permiso R (lectura) habilita a quién lo posea a ver el contenido del archivo, mientras que el permiso W (escritura) le permite cambiar su contenido. El permiso X (ejecución) se aplica a los programas y habilita su ejecución. Para los directorios, el permiso R permite listar el contenido del mismo (es decir, “leer” el directorio, mientras que el W permite borrar o crear nuevos archivos en su interior (es decir, modificar o “escribir” el directorio). El permiso X da permiso de paso, es decir, la posibilidad de transformar el directorio en cuestión en el directorio actual (ver comando cd). En los listados de directorio, los permisos se muestran como una cadena de 9 caracteres, en donde los primeros tres corresponden a los permisos del usuario, los siguientes tres a los del grupo y los últimos, a los de los demás usuarios. La presencia de una letra (r, w o x) indica 112 Chapter 6. Sistemas de archivos Fundamentos de Sistemas Operativos, Release 1.0 que el permiso está concedido, mientras que un guión (-) indica que ese permiso está denegado. Los permisos de un archivo o directorio pueden cambiarse desde el administrador de archivos KFM utilizando la ventana de propiedades o utilizando el comando chmod 6.16 Rutas de Directorios 6.16.1 Nombres de ruta Un nombre de ruta define de manera única a un archivo o directorio en particular especificando su ubicación. Los nombres de ruta son similares a un mapa de caminos o a un conjunto de instrucciones que le indican al usuario cómo ir de un lugar en la jerarquía de directorios a otro. Por ejemplo, si el alumno le estuviera dando a alguien de otro país instrucciones acerca de cómo llegar a él, tendría que especificar dónde vive. Los directorios de un sistema de archivos pueden compararse a un país, estado, ciudad, etcétera. Si la Tierra fuera un disco duro con un sistema de archivos, la consideraríamos la raíz del mismo. Si quisiéramos identificar la ubicación de una persona para decirle a alguien dónde vive, especificaríamos el nombre de ruta hasta llegar a dicha persona. Utilizaríamos un nombre de ruta totalmente calificado para que no existiera ninguna duda de que estamos hablando de esa persona del planeta Tierra, y no de cualquier otro planeta. 6.16.2 Componentes de la ruta Las barras dentro del nombre de ruta son delimitadoras entre nombres de objetos. Las barras actúan como separadores. Los nombres de objetos pueden ser directorios, subdirectorios o archivos. DOS y Windows indican los directorios utilizando una barra invertida (). Todos los sistemas de archivos UNIX utilizan una barra (/) en los nombres de ruta. La barra se encuentra por lo general cerca de la tecla Shift 6.16. Rutas de Directorios 113 Fundamentos de Sistemas Operativos, Release 1.0 derecha en la mayoría de los teclados. Una barra (/) en la primera posición de cualquier nombre de ruta representa al directorio raíz. 6.16.3 Directorio de Árbol 6.16.4 Directorio de un solo Nivel 114 Chapter 6. Sistemas de archivos Fundamentos de Sistemas Operativos, Release 1.0 6.16.5 Directorio de Dos Niveles 6.16.6 Directorio de Grafo Aciclico 6.16.7 Directorio de Grafo General 6.17 Glosario • Bloque: Unidad lógica de disco duro. 6.17. Glosario 115 Fundamentos de Sistemas Operativos, Release 1.0 116 Chapter 6. Sistemas de archivos Fundamentos de Sistemas Operativos, Release 1.0 • Caché: Memoria pequeña de acceso rápido que almacena los datos usados por un periférico recientemente. • Cluster: Conjunto de bloques. • FAT: File Allocation Table o tabla de asignación de archivos. • Nodo Índice: Bloque especial que almacena atributos de archivo y punteros hacia datos o hacia otros nodos índice. 6.18 Referencias • Giampaolo Dominic. Practical File System Design with the Be File System. Morgan Kaufmann Publishers INC, San Francisco California. 1999. • Tanenbaum Andrew. Sistemas Operativos Modernos. Tercera Edición. PEARSON EDUCACIÓN, México, 2009. • Downey, Allen. Think OS A Brief Introduction to Operating Systems. Green Tea Press. Needham. Massachusetts. 2014. • Silberschatz, Abraham. Operating System Conceps. Wiley. Ninth Edition. United States. 2013. • Overview of FAT, HPFS, and NTFS File Systems. (n.d.). Retrieved 24 April 2015, from https://support.microsoft.com/enus/kb/100108 • UNIX File System. (n.d.). Retrieved 23 April 2015, from http://www.cis.rit.edu/class/simg211/unixintro/Filesystem.html • Rutas de Directorios (2015, 12 de Marzo). Recuperado el 12 de Marzo del 2015, de https://sites.google.com/a/ingenieria.lm.uasnet.mx/so/t3#sectionArchivos-RutasDeDirectorios • Directorios (2015, 12 de Marzo). Recuperado el 12 de Marzo del 2015, de http://es.wikipedia.org/wiki/Directorio 6.18. Referencias 117 Fundamentos de Sistemas Operativos, Release 1.0 • archivos Linux (2015, 12 de Marzo). Recuperado el 12 de Marzo del 2015, de http://www.investigacion.frc.utn.edu.ar/labsis/Publicaciones/apunte_linux/ma.htm • Filesystem (2015, 12 de Marzo). cuperado el 12 de Marzo del 2015, http://www.ant.org.ar/cursos/curso_intro/filesystem.html Rede • Sistema de archivos (2015, 12 de Marzo). Recuperado el 12 de Marzo del 2015, de http://laurel.datsi.fi.upm.es/_media/docencia/asignaturas/dso/sistemaarchivosdso_ • Sistemas Operativos.: Sistemas de gestion de archivos. (2015, 12 de Marzo). Recuperado el 12 de Marzo del 2015, de http://sistemasoperativos03unefa.blogspot.com/2011/12/normal-0-21-false-false-false-esve-x.html 118 Chapter 6. Sistemas de archivos