Está en la página 1de 75

Fundamentos básicos de

los Sistemas Operativos


Índice de contenido
Fundamentos básicos de los sistemas operativos
Capítulo 1. Consideraciones generales de los sistemas operativos.........................7
Objetivos..................................................................................................................7
Servicios de un sistema operativo............................................................................7
Evolución histórica...................................................................................................7
Tipos de sistemas operativos....................................................................................8
Llamadas al sistema.................................................................................................9
Estructura del núcleo de un sistema operativo.........................................................9
Capítulo 2. Descripción y control de procesos........................................................11
Espacio de direcciones de memoria lógica o virtual de un proceso.......................11
Tipos de procesos...............................................................................................11
Estados de un proceso........................................................................................11
Control de los procesos..........................................................................................12
Estructuras de control del sistema operativo.....................................................12
Creación de procesos.........................................................................................12
Terminación de procesos...................................................................................13
Cambio de proceso............................................................................................13
Ejecución del sistema operativo.............................................................................13
Procesos multihilo..................................................................................................13
Control de hilos.................................................................................................14
Tipos de hilos.....................................................................................................14
Principales configuraciones en función del número y tipo de hilos soportados
por un sistema operativo....................................................................................15
Capítulo 3. Planificación de procesos......................................................................17
Niveles de planificación.........................................................................................17
Planificador a corto plazo..................................................................................17
Planificador a medio plazo................................................................................18
Planificador a largo plazo..................................................................................18
Criterios generales considerados en la planificación de procesos..........................18
Criterios considerados en la planificación del procesador.....................................18
Expropiabilidad del procesador..............................................................................19
Algoritmos de planificación...................................................................................19
Primero en llegar – primero en ser servido – FCFS..........................................19
Primero el proceso más corto – SJF..................................................................19
Menor tiempo restante.......................................................................................20
Planificación de turno rotatorio.........................................................................20
Planificación basada en prioridades..................................................................20
Planificación basada en múltiples colas de prioridad........................................21
Múltiples colas de prioridad y realimentación..................................................21
Planificación por tiempo límite.........................................................................22
Elección del algoritmo de planificación............................................................22
Planificación de hilos.............................................................................................22
Capítulo 4. Sincronización y comunicación de procesos.......................................23
Exclusión mutua.....................................................................................................23
Interacción entre procesos concurrentes............................................................23

ii
Condiciones de carrera......................................................................................23
Secciones críticas...............................................................................................23
Descripción de la exclusión mutua....................................................................23
Soluciones software a la exclusión mutua.........................................................24
Soluciones a la exclusión mutua con apoyo del hardware................................25
Semáforos...............................................................................................................25
Implementación.................................................................................................25
Utilidad de los semáforos..................................................................................27
Sincronización de procesos...............................................................................27
Problemas potenciales asociados a un mal uso de los semáforos.....................27
Problemas clásicos de sincronización de procesos concurrentes...........................28
El problema de los productores y los consumidores.........................................28
El problema de los lectores y los escritores......................................................28
Monitores...............................................................................................................29
Definición..........................................................................................................29
Estructura y declaración de un monitor.............................................................29
Uso de los monitores.........................................................................................30
Paso de mensajes....................................................................................................30
Definición..........................................................................................................30
Especificación de la fuente y el destino del mensaje........................................31
Esquemas de sincronización..............................................................................31
Formato y almacenamiento de los mensajes.....................................................32
Uso del paso de mensajes..................................................................................32
Capítulo 5. Interbloqueo..........................................................................................33
Introducción...........................................................................................................33
Definición y condiciones del interbloqueo............................................................33
Grafos de asignación de recursos...........................................................................33
Prevención de interbloqueos..................................................................................34
Eliminación de la condición de exclusión mutua..............................................34
Eliminación de la condición de retención y espera...........................................34
Eliminación de la no existencia de expropiación..............................................34
Eliminación de la espera circular......................................................................34
Evitación de interbloqeos.......................................................................................34
Estado de la asignación de recursos: estados seguros y estados inseguros.......35
Denegación de asignación de recursos: el algoritmo del banquero...................35
Denegación de la iniciación de un proceso.......................................................35
Detección y recuperación de interbloqueos...........................................................36
Algoritmos de detección de interbloqueos........................................................36
Frecuencia de invocación del algoritmo de detección de interbloqueos...........36
Técnicas de recuperación del interbloqueo.......................................................36
Ventajas e inconvenientes..................................................................................36
Otras estrategias de tratamiento de interbloqueos..................................................37
Capítulo 6. Administración de memoria.................................................................38
Espacio de núcleo y espacio de usuario............................................................38
Área de intercambio en memoria secundaria....................................................38
Asignación de memoria en sistemas monoprogramados.......................................39
Particionamiento fijo..............................................................................................40
Particiones de igual tamaño...............................................................................40
Particiones de distinto tamaño...........................................................................40
Traducción de direcciones y protección............................................................40

iii
Ventajas e inconvenientes..................................................................................41
Particionamiento dinámico.....................................................................................41
Asignación de espacio de memoria principal....................................................41
Traducción de direcciones y protección............................................................42
Ventajas e inconvenientes..................................................................................42
Paginación simple..................................................................................................42
Traducción de direcciones.................................................................................43
Tablas de páginas paginadas..............................................................................44
Tablas de páginas invertidas..............................................................................45
Protección..........................................................................................................46
Compartición de páginas...................................................................................46
Ventajas e inconvenientes..................................................................................46
Segmentación simple.............................................................................................46
Traducción de direcciones.................................................................................47
Protección..........................................................................................................47
Compartición de segmentos..............................................................................47
Ventajas e inconvenientes..................................................................................47
Segmentación con paginación simple....................................................................48
Capítulo 7. Memoria virtual....................................................................................49
Paginación por demanda........................................................................................49
Reinicio de instrucciones...................................................................................50
Localización de las páginas en memoria secundaria.........................................50
Bloqueo de marcos de página............................................................................50
Tratamiento de un fallo de página.....................................................................50
Conjunto de trabajo de un proceso.........................................................................51
Reemplazamiento de páginas.................................................................................51
Algoritmo de reemplazamiento óptimo.............................................................52
Algortimo de reemplazamiento LRU................................................................52
Algoritmo de reemplazamiento mediente envejecimiento................................52
Algoritmo de reemplazamiento FIFO...............................................................52
Algoritmo de reemplazamiento de la segunda oportunidad (algoritmo del reloj)
...........................................................................................................................53
Algoritmo de reemplazamiento del reloj considerando el conjunto de trabajo.53
Conclusiones sobre los algoritmos de reemplazamiento...................................54
Asignación de memoria principal..........................................................................54
Control de carga.....................................................................................................55
Copia en memoria secundaria de páginas modificadas..........................................55
Consideraciones adicionales sobre la paginación por demanda.............................55
Tamaño de página..............................................................................................55
Paginación por adelantado.................................................................................56
Reserva de marcos libres...................................................................................56
Capítulo 8. Gestión de la Entrada/Salida...............................................................57
Peticiones de E/S....................................................................................................57
Capas del núcleo de un sistema operativo encargadas de la E/S...........................57
Subsistema de E/S.............................................................................................57
Drivers de dispositivos de E/S...........................................................................58
Manejador de las interrupciones........................................................................58
Buffering................................................................................................................58
Estrategias..........................................................................................................59
Caché de buffers de bloques de disco................................................................59

iv
Spooling.................................................................................................................59
Detalles de la gestión de E/S de algunos dispositivos............................................59
Relojes...............................................................................................................59
Discos duros......................................................................................................60
Dispositivos de E/S adaptados al usuario..........................................................62
Capítulo 9. Gestión de archivos...............................................................................64
Archivos.................................................................................................................64
Tipos de archivos...............................................................................................64
Atributos de un archivo.....................................................................................64
Estructura interna de un archivo........................................................................64
Métodos de acceso a un archivo........................................................................65
Operaciones sobre archivos...............................................................................65
Directorios..............................................................................................................66
Estructura de los directorios..............................................................................66
Operaciones sobre directorios...........................................................................67
Sistemas de archivos..............................................................................................67
Estructura de un sistema de archivos.................................................................67
Montaje de un sistema de archivos....................................................................68
Asignación de espacio.......................................................................................68
Gestión del espacio libre...................................................................................69
Implementación de directorios..........................................................................70
Consistencia.......................................................................................................70
Recuperación de archivos......................................................................................71
Copias de seguridad...........................................................................................71
Instantáneas.......................................................................................................71
Eficiencia................................................................................................................72

v
Capítulo 1. Consideraciones generales de los sistemas
operativos
Un sistema operativo es una capa de software cuya función es administrar todos los dispositivos
hardware del computador y suministrar para usuarios y programas una interfaz apropiada con el
hardware.

Objetivos
Gestionar eficientemente los dispositivos hardware
• Tiempo de procesador a los programas de usuario: planificador.
• Ocupación/gestión de memoria principal
• Gestión de memoria secundaria: área de intercambio (zona donde se almacenan los
programas que hay que ejecutar pero que aún no disponen de espacio en memoria principal)
y sistema de archivos y resto de dispositivos E/S.
Ofrecer una interfaz cómoda a los usuarios. El SO proporciona una máquina virtual que envuelve al
hardware facilitando su programación. Capas:
• Hardware
• Núcleo (kernel), proporciona un conjunto de instrucciones como llamadas al sistema.
• Utilidades del SO (intérpretes de comandos, sistemas de ventanas, compiladores, etc).
• Programas de aplicación.

Servicios de un sistema operativo


• Ejecución de programas.
• Acceso a los dispositivos de E/S.
• Manipulación del sistema de archivos
• Comunicación y sincronización.
• Detección y respuesta a errores
• Protección y seguridad.
• Contabilidad.

Evolución histórica
• Procesamiento serie
• Procesamiento por lotes (batch)
• Multiprogramación (multitarea). Aprovechamiento de operaciones de E/S de un proceso
para ejecutar otro.
• Multiprogramación por tiempo compartido. Debe gestionar los recursos asignándolos de
manera equitativa.

Apuntes por Demetrio Quirós – Fundamentos básicos de los Sistemas Operativos 7


Tipos de sistemas operativos
En función del número de usuarios simultáneos
• Monousuario y multiusuario.
Según el número de programas cargados en memoria principal:
• Monoprogramado y multiprogramado.
• Se denomina grado de multiprogramación el número de programas cargados en memoria
principal. Para implementar multiprogramación se precisan algoritmos de planificación,
mecanismos de sincronización y de asignación y protección de memoria principal y
secundaria. El hardware también debe soportar protección de la memoria, E/S por
interrupciones y DMA. Un SO puede ser multiacceso (acceso desde dos o más terminales)
pero no necesariamente multitarea (sistema de venta de billetes, por ejemplo). Un SO
multiprocesamiento coordina la actividad de varios procesadores. Son multiprogramados por
definición.
En función de los requisitos temporales de los programas a ejecutar:
• Sistemas por lotes o batch, planificación del procesador simple; suele utilizarse E/S por
programa; gestión sencilla de la memoria principal: bloque del SO y bloque de programas
• Sistemas de tiempo compartido o sistemas interactivos. Sistemas multiusuario con
multiprogramación. El planificador debe asegurar el reparto equitativo del tiempo de
procesador así como poseer mecanismos de protección de MP, MS y acceso concurrente a
archivos.
• Sistemas de tiempo real. Pueden ser en tiempo real estricto o suave. Las primeras requieren
un tiempo límite preestablecido de respuesta. Utilizan un sistema de planificación de tipo
expropiativo, en el que el proceso con más prioridad toma el control. la gestión de la
memoria es menos exigente. (VxWorks, QNX)
• Sistemas híbridos. Soportan tanto trabajos por lotes como aplicaciones interactivas o
aplicaciones suaves en tiempo real. Prioridad de ejecución mínima para trabajos por lotes,
media para interactivos y máxima para aplicaciones en tiempo real. (UNIX, LINUX)
En función de la finalidad del computador.
• Sistemas para macrocomputadores.
• Sistemas operativos para servidores de red.
• Sistemas operativos para computadoras personales.
• Sistemas para computadoras de mano.
• Sistemas integrados.
Otros tipos importantes de SO
• Sistemas paralelos o multiprocesador. Comparten bus, reloj, memoria, E/S. Se les suele
denominar como sistemas fuertemente acoplados. Los SO paralelos más comunes utilizan
multiprocesamiento simétrico. Cada procesador ejecuta su propia copia del SO, que se
comunican entre ellas cuando es necesario.
• Sistemas distribuidos. Se ejecutan en sistemas informáticos distribuidos implementados
mediante redes. Se les suele denominar sistemas débilmente acoplados. El usuario no sabe si
el proceso se ejecuta en su propio procesador o en el de otra máquina de la red.

8 Capítulo 1. Consideraciones generales de los sistemas operativos


• Sistemas operativos de red. Posibilita el acceso a contenido y recursos entre computadoras
mediante el paso de mensajes.

Llamadas al sistema
La mayoría de procesadores disponen de dos modos de operación: modo núcleo y modo usuario.
Los programas de usuario deben hacer uso de llamadas al sistema para poder utilizar los recursos
hardware a través del SO.
• Mediante el uso de librerías de llamadas al sistema, de forma similar a como se invoca
cualquier otra función.
• De forma directa, mediante programas en lenguaje ensamblador.
La llamada al sistema provoca una trampa (tramp), haciendo que el procesador conmute a modo
núcleo. Para poder acceder a los parámetros de la llamada al sistema se utiliza:
• Cargar los parámetros en registros. Método sencillo, puede que no se tengan registros
suficientes.
• Almacenamiento en un bloque o tabla de memoria. Sólo es necesario conocer la dirección
de comienzo del bloque.
• Almacenamiento en una pila.
Las llamadas al sistema, atendiendo a su funcionalidad, se pueden agrupar en:
• Control de programas en ejecución (procesos).
• Administración de archivos y directorios.
• Comunicaciones.
• Gestión de dispositivos.
• Gestión de información del sistema.

Estructura del núcleo de un sistema operativo


La forma más eficiente de diseñar un SO consiste en descomponerlo en varios componentes o
subsistemas. La mayoría disponen de:
• Subsistema de control de procesos.
• Subsistema de control de la memoria principal.
• Subsistema de gestión de archivos.
• Subsistema de E/S.
El núcleo de un sistema operativo se puede considerar como un conjunto lógico de módulos
software. El nucleo puede tener
• Estructura monolítica o simple. Todos los subsistemas y las estructuras de datos del núcleo
se ubican en un mismo módulo lógico. El software del núcleo está escrito como un conjunto
de procedimientos. Un procedimiento es visible por todos los demás. (MSDOS, UNIX
tradicional).
• Estructura en módulos. Cada módulo con una interfaz bien definida. De fácil mantenimiento
con una ligera merma en el rendimiento.
• Estructura en capas o niveles. El núcleo se organiza en capas de software en la que las capas
pueden invocar a las capas inferiores, pero nunca a las superiores. Un esquema típico en seis

Apuntes por Demetrio Quirós – Fundamentos básicos de los Sistemas Operativos 9


capas: capa 0, controladores hardware; capa 1, control, sincronización y comunicación de
procesos; capa 2, gestión de memoria; capa 3, comunicaciones entre procesos y el operador
de consola; capa 4, gestión de E/S; capa 5, programas de usuario.
• Estructura extensible. Puede considerarse como un caso particular de la estructura modular.
Posee un módulo principal, el núcleo extensible o micronúcleo, y varios módulos como
extensiones del núcleo. El micronúcleo realiza los servicios absolutamente esenciales, los
que dependen estrechamente de la arquitectura de la máquina como la gestión de
interrupciones, comunicación entre procesos, gestión de memoria a bajo nivel y gestión de
E/S. El resto de las funciones se realizan en modulos de extensión del núcleo. Los procesos
de usuarios se comunican con las extensiones del núcleo utilizando un mecanismo cliente
(applicación de usuario) – servidor (extensión del núcleo).
La comunicación cliente/servidor se realiza mediante el paso de mensajes. Las ventajas de
un núcleo extensible son:
Manejabilidad. Cada extensión del núcleo se encarga de un servicio del sistema.
◦ Extensibilidad. Añadir nuevas características añadiendo un nuevo módulo.
◦ Fiabilidad. Las extensiones se ejecutan como procesos de usuario. Ante el fallo de un
servicio, el resto puede seguir disponible.
◦ Soporte simultáneo de múltiples sistemas operativos. Sobre un mismo micronúcleo
pueden implementarse diferentes extensiones.
◦ Portabilidad. Solo es necesario reescribir el micronúcleo al ser la única parte
dependiente del hardware.
Su principal desventaja es un menor rendimiento debido al paso de mensajes (creación,
envío, procesamiento).

10 Capítulo 1. Consideraciones generales de los sistemas operativos


Capítulo 2. Descripción y control de procesos
Un proceso es un programa en ejecución. También puede definirse como la entidad que se puede
asignar y ejecutar en un procesador: es la unidad básica de trabajo de un sistema informático.
Si un programa se ejecuta más de una vez, cada copia tendrá su propio proceso asignado.
Cuando un proceso puede interactuar con los usuarios se dice que está en primer plano
(foreground), en caso contrario un proceso se encuentra en segundo plano (background).

Espacio de direcciones de memoria lógica o virtual de un proceso.


El espacio de direcciones de memoria lógica o virtual de un proceso (imagen del proceso o espacio
de direcciones de usuario) se divide en varias regiones: la región de código (o región de texto), la
región de datos y la región de pila.
La región de datos puede dividirse en región de datos inicializados, de tamaño fijo, y región de
datos no inicializados, de tamaño variable.
La región de pila se crea automáticamente y su tamaño se ajusta dinámicamente en tiempo de
ejecución. El registro puntero de pila almacena la próxima entrada libre o la última utilizada,
dependiendo de la arquitectura del procesador.
Puesto que la región de pila y la de datos no inicializados puede variar durante la ejecución de un
proceso se deben reservar regiones libres adyacentes.
A parte de las regiones del espacio de direcciones de memoria lógica a las que se accede en modo
usuario, el SO ubica estructuras de datos relativas al proceso en curso que le permiten controlar su
ejecución y que son accesibles en modo supervisor o núcleo.

Tipos de procesos
• Procesos de usuario. Pueden ejecutarse en primer o segundo plano. Se ejecutan en modo
usuario.
• Procesos demonio. Procesos no asociados a ningún usuario. Realizan tareas relacionadas
periódicas de administración del sistema. Se ejecutan en modo usuario generalmente en
segundo plano.
• Procesos del sistema operativo. Realizan tareas de administración (como el intercambio de
procesos entre memoria principal y secundaria) del sistema en modo supervisor y,
generalmente, en segundo plano.

Estados de un proceso
Aunque el número y el nombre depende de cada sistema operativo, algunos de los estados más
habituales son:
• Nuevo.
• Preparado.
• Ejecutándose.
• Bloqueado.
• Terminado.
Además, nos podemos encontrar con otros dos estados disponibles en algunos sistemas operativos:

Apuntes por Demetrio Quirós – Fundamentos básicos de los Sistemas Operativos 11


• Preparado en memoria secundaria.
• Bloqueado en memoria secundaria.

Control de los procesos

Estructuras de control del sistema operativo


El sistema operativo debe mantener información sobre el estado de cada proceso y cada recurso.
Esta información se guarda en tablas en memoria
• Tabla de procesos. Cada entrada en la tabla almacena un PCB (Process Control Block) con
diversa información:
◦ Identificador del proceso.
◦ Identificador del usuario.
◦ Estado del proceso.
◦ Contenido de algunos registros del procesador.
◦ Información de planificación del proceso.
◦ Información de localización de la memoria principal asociada al proceso.
◦ Información de tipo estadístico.
◦ Información de estado de E/S.
◦ Información sobre el evento por el que el proceso ha entrado en modo bloqueado.
• Tablas de memoria, con información sobre espacio libre y asignado.
• Tablas de E/S, con información sobre disponibilidad de dispositivos y quien lo usa.
• Tablas de archivos, con información sobre archivos abiertos por los procesos.
Además, podemos encontrar las pilas de control del sistema o pilas del sistema operativo, así como
pilas de interrupciones, colas de procesos preparados y bloqueados, etc.

Creación de procesos
• Comprobar si el proceso puede ser creado.
• Asignar una nueva entrada de la tabla de procesos para el nuevo proceso.
• Reservar espacio en memoria para el proceso.
• Inicializar el bloque de control del proceso.
• Establecer los enlaces adecuados.
Las causas que originan la creación de un proceso pueden ser:
• El arranque del sistema operativo.
• Interacción del usuario mediante intérprete de comandos o entorno de ventanas.
• Inicio de un trabajo por lotes.
• Un proceso en ejecución invoca una llamada al sistema para crear otro proceso.
◦ UNIX y Linux, mediante llamada a fork. Crea una copia exacta del proceso padre.
Cuando el hijo es planificado para ejecutarse, invoca a execve, y lanza el otro programa.

12 Capítulo 2. Descripción y control de procesos


◦ En Windows, createprocess utiliza otro espacio de direcciones distinto para el proceso
hijo.

Terminación de procesos
Cuando se produce una excepción en su ejecución.
Cuando finaliza la tarea para la que ha sido creado
• En UNIX, llamada al sistema exit.
• En Windows llamada a ExitProcess.
Cuando un proceso privilegiado detenga otro.
• En UNIX, llamada al sistema kill.
• En Windows, llamada al sistema TerminateProcess.
Una vez finalizado el proceso, hay que liberar los recursos que utilizaba. El PCB no se elimina
inmediatamente, sino después de haber auditado los datos.

Cambio de proceso
Un proceso A se interrumpe para iniciar o continuar la ejecución de otro proceso B: cambio de
contexto o cambio de proceso. Causas más frecuentes para un cambio de contexto son:
• El proceso en ejecución pasa al estado bloqueado.
• La terminación voluntaria o forzada del proceso en ejecución.
• El sistema operativo termina de atender una interrupción y existe un proceso B en estado
preparado con mayor prioridad que el proceso actual.
• El proceso en ejecución ha excedido el tiempo máximo de ejecución ininterrumpida.
Para proceder a un cambio de contexto, el sistema operativo sigue los pasos siguientes:
• Salva el contexto del proceso A en su PCB.
• Se ejecuta el algoritmo de planificación para seleccionar el proceso B.
• Cargar el PCB del proceso B seleccionado.
El tiempo de conmutación es el tiempo que se tarda en completar todo el proceso debido a las
limitaciones físicas de los componentes.

Ejecución del sistema operativo


En función de la tarea o servicio realizado, el tiempo utilizado por el sistema operativo puede ser
contabilizado a un determinado proceso. El tiempo de uso de las tareas y servicios propios de la
administración del sistema no se contabilizan a ningún proceso de usuario; este tiempo no dedicado
a tareas de usuario se denomina sobrecarga del sistema (overhead).
El tiempo de determinadas tareas del sistema operativo, como la atención a las interrupciones
hardware, no es sencillo asignarlas a un proceso en particular dado su carácter asíncrono. UNIX,
por ejemplo, se las anota al proceso ejecutándose en el momento de producirse la interrupción,
aunque no sea este el causante.

Procesos multihilo
Un proceso está caracterizado por dos elementos que pueden ser tratados de forma independiente:

Apuntes por Demetrio Quirós – Fundamentos básicos de los Sistemas Operativos 13


• Conjunto de recursos asignados: espacio de direcciones, archivos abiertos, etc.
• Traza de ejecución, hilo de control, hilo o hebra (thread). Hace referencia a las instrucciones
que ejecuta el proceso durante su tiempo de vida.
Los sistemas operativos modernos introducen el modelo de proceso multihilo: un proceso puede
estar formado por múltiples hilos. Estos sistemas operativos utilizan los procesos como unidad de
asignación del procesador que sigue una determinada traza de ejecución y tiene asignado una pila
de usuario, espacio de almacenamiento y un bloque de control del hilo. Este bloque de control
contiene el identificador numérico del hilo, el estado del hilo, su prioridad de ejecución y los
valores de los registros. A un hilo se le llama a veces proceso ligero (lightweigth process).
Cada hilo perteneciente a un proceso comparte con los restantes hilos del mismo proceso los
mismos recursos bloque de control del proceso, etc.
Ventajas de procesos multihilos respecto de múltiples procesos:
• Aumento del rendimiento del sistema.
• Ahorro de recursos.
• Comunicación más eficiente.
• Mayor aprovechamiento de las arquitecturas multiprocesador.
• Simplificación de la estructura de las aplicaciones.
El principal inconveniente es la necesidad de sincronización de acceso a las estructuras de datos que
comparten los hilos.

Control de hilos
Como sucede con los procesos, un hilo puede encontrarse durante su tiempo de vida en diferentes
estados. En un determinado instante, un proceso se encontrará en un estado determinado que no
tiene por que coincidir con el estado de sus hilos. Obviamente, el estado del proceso limita el estado
en el que pueden encontrarse sus hilos: si un proceso se encuentra en estado preparado ninguno de
sus hilos puede estar ejecutándose.
La planificación de la cola de hilos se realiza a nivel de hilos. Cuando un hilo termina su ejecución
simplemente desaparece, ya no es planificable.
El poder realizar un cambio de hilo dentro de un mismo proceso cuando un hilo cambia al estado
bloqueado depende del tipo de implementación de hilos que soporte el sistema operativo.
En el momento que un hilo finaliza su ejecución sus recursos asignados son liberados. Un proceso
no puede entrar en estado terminado hasta que no hayan finalizado todos sus hilos.

Tipos de hilos
Hilos a nivel de usuario. O, simplemente, hilos de usuario, son implementados por una biblioteca
de hilos que se ejecuta a nivel de usuario. Inicialmente, una aplicación comienza con un solo hilo.
Este proceso puede iniciar otro hilo invocando a la función apropiada de la biblioteca de hilos del
SO.
Cada proceso requiere una tabla de hilos, en la que cada entrada, denominada bloque de control del
hilo, mantiene la información asociada al hilo (contador del programa, registro de pila, etc.) Esta
tabla es similar a la tabla de procesos.
La realización del cambio de hilo dentro de un mismo proceso se realiza sin necesidad de realizar
un cambio de modo y un cambio de contexto. Toda esta actividad tiene lugar en modo usuario
dentro del proceso en ejecución, sin intervención del sistema operativo. Esto proporciona las
siguientes ventajas:

14 Capítulo 2. Descripción y control de procesos


• Portabilidad. Al no requerir la intervención del SO, sólo de la biblioteca de hilos que puede
estar disponible para múltiples SO.
• Mejora del rendimiento del sistema. Al realizarse toda la gestión de hilos en modo usuario.
• Planificación independiente. Cada proceso puede emplear un algoritmo de planificación
distinto y estos a su vez distintos del que emplee el sistema operativo.
La principal desventaja se da en aquellos sistemas operativos que solo soportan un hilo a nivel de
núcleo: cuando un hilo de un proceso entra en estado bloqueado, todo el proceso se bloquea: el
sistema operativo desconoce la existencia de hilos de usuario. Otra desventaja es que cuando un hilo
se está ejecutando no se puede planificar otro hilo de usuario del mismo proceso a no ser que el
primero ceda voluntariamente el uso del procesador.
Hilos a nivel de núcleo
Los hilos del núcleo son implementados y gestionados directamente por el núcleo del SO.
• No precisan biblioteca de hilos.
• El sistema mantiene una única tabla de hilos.
• Si uno se bloquea se puede planificar otro del mismo o distinto proceso.
• En sistemas multiprocesador puede ejecutarse un hilo en cada procesador.
• Su gestión contribuye a la sobrecarga del sistema.
• Algunos SO, por ello, limitan el número de hilos del núcleo.
• Para ahorrar en tiempo, cuando un hilo se destruye se marca como no planificable pero su
estructura de datos no se elimina, se reutiliza para otros hilos.

Principales configuraciones en función del número y tipo de hilos soportados por un


sistema operativo
Dependiendo del número y tipo de hilos soportados por un sistema operativo, se pueden distinguir
las siguientes configuraciones:
• Múltiples hilos de usuario sin soporte de hilos del núcelo.
◦ El sistema planifica procesos, no hilos.
◦ La gestión de hilos la realiza una biblioteca de hilos.
◦ Cuando un hilo realiza una llamada al sistema, comienza a ejecutarse el SO.
◦ Si la llamada requiere el bloqueo del hilo, se bloquea el proceso completo.
◦ No pueden ejecutarse varios hilos al mismo tiempo, ya que sólo uno puede acceder al
SO.
• Un hilo del núcleo por cada hilo de usuario.
◦ No se precisa biblioteca de hilos, solo acceder a las utilidades de hilos del núcleo.
◦ Si un hilo de usuario se bloquea se puede planificar otro del mismo proceso.
◦ La planificación la realiza el SO.
◦ Debido a la sobrecarga, se limita el número de hilos que es posible crear.
• Menor número de hilos del núcleo que hilos de usuario.
◦ Se requiere biblioteca de hilos para gestión de hilos de usuario.

Apuntes por Demetrio Quirós – Fundamentos básicos de los Sistemas Operativos 15


◦ Los hilos de usuario se asocian a un número <= de hilos del núcleo.
◦ Es el programador de la aplicación quien se encarga de establecer el número de hilos del
núcleo que necesita.
◦ Auna las ventajas de las dos configuraciones anteriores, si está bien implementada.

16 Capítulo 2. Descripción y control de procesos


Capítulo 3. Planificación de procesos
En una máquina con multiprogramación pueden ejecutarse concurrentemente varios procesos. Si la
máquina dispone de un único procesador, en un determinado instante de tiempo sólo un proceso o
hilo puede usarlo. El sistema operativo debe decidir qué proceso es el que va a ser ejecutado.

Niveles de planificación
Colas de procesos para planificar los recursos del procesador:
• Cola de procesos en estado preparado.
• Cola de procesos en estado preparado en memoria secundaria.
• Cola de procesos en estado bloqueado.
• Cola de procesos en estado bloqueado en memoria secundaria.
• Cola de trabajos por lote o cola de entrada.
Un proceso puede pasar por varias colas. La actividad de determinar cuándo se entra en una cola o
se pasa a otra se denomina planificación de procesos y al componente que la realiza planificador. Se
distinguen tres niveles de planificación:
• Planificación a corto plazo, que decide qué proceso será ejecutado a continuación.
• Planificación a medio plazo, de determina qué proceso en cola de memoria principal pasa a
cola de memoria secundaria y viceversa.
• Planificación a largo plazo, determina qué trabajo por lotes pasa a ser ejecutado mediante la
creación de un proceso.
Además, se puede distinguir un cuarto nivel de planificación, la planificación de E/S.
Cada nivel de planificación es implementado por su propio planificador.

Planificador a corto plazo


Desde el punto de vista lógico, todo planificador se puede dividir en tres componentes o elementos:
• Encolador (enqueuer), encargado de incluir al proceso en la cola de procesos preparados y
de asignarle una prioridad.
• Conmutador de contexto (context switcher), encargado de guardar el contexto del proceso a
ser desalojado y cargar el contexto del proceso a ser ejecutado.
• Distribuidor o despachador (dispatcher), encargado de seleccionar un proceso de la cola de
procesos preparados y cederle el control del procesador. El tiempo que transcurre entre la
detención de un proceso y la ejecución de otro se llama tiempo de despacho. Algunos SO no
permiten la expropiación de un proceso que se ejecuta en modo núcleo que está realizando
una llamada al sistema. Estos sistemas se llaman de nucleo no expropiable.
Algunas circunstancias que hacen necesaria una llamada al planificador a corto plazo son:
• Cuando se ha terminado de crear un nuevo proceso hijo.
• Cuando un proceso entra en estado bloqueado en espera de que se producza algún evento.
• Cuando se termina de atender una interrupción.
• Cuando un proceso finaliza.

Apuntes por Demetrio Quirós – Fundamentos básicos de los Sistemas Operativos 17


Planificador a medio plazo
También conocido como planificador de memoria o intercambiador. Decide qué procesos de
memoria principal se pasa a memoria secundaria y viceversa. Se ejecuta con menor frecuencia que
el planificador a corto plazo. Puede ser invocado cuando queda espacio libre en la memoria
principal o porque el número de procesos en el estado preparado cae por debajo de algún límite
prefijado.

Planificador a largo plazo


También se denomina planificador de trabajos o planificador de admisión. Decide qué trabajo de
los pendientes en la cola trabajos por lotes será admitido para ser ejecutado.
La admisión de un trabajo consiste en la creación de un proceso para el procesamiento de dicho
trabajo.
El planificador a largo plazo permite regular el nivel de multiprogramación del sistema,
invocándolo cuando se termina un trabajo o tras cierto tiempo de inactividad del procesador.
A tener en cuenta es que la ejecución de un proceso comienza con una ráfaga de CPU, esto es,
utilizando el procesador de forma continuada durante un cierto periodo de tiempo. Así nos podemos
encontrar con procesos limitados por CPU, en los que éste se encuentra la mayor parte del tiempo
utilizando la CPU y poco los recursos de E/S y los procesos limitados por E/S. El planificador debe
intentar seleccionar los trabajos de forma que exista un equilibrio entre procesos de un tipo y de
otro.
Algunos sistemas operativos como UNIX no disponen de planificador a largo plazo.

Criterios generales considerados en la planificación de procesos


• Equidad. Requisistos similares → tiempo de uso de los recursos similares.
• Previsibilidad. Características similares → tiempo de ejecución similares.
• Uso equilibrado de los recursos. Mantener todos los recursos ocupados / optimizados.
• Proporcionalidad. Peticiones sencillas → mejor tiempo de respuesta que peticiones
complejas.

Criterios considerados en la planificación del procesador


El planificador del procesador elige el próximo proceso que pasará a ser ejecutado en el procesador
en base a la optimización simultánea de alguno o alguno de los siguientes criterios:
• Utilización del procesador o eficacia. Porcentaje de tiempo del procesador activo.
• Productividad (throghput) o rendimiento. Número de trabajos completados por u.t. (1 hora)
• Tiempo de entrega (turnaround time), también denominado tiempo de retorno o tiempo de
estancia. Tiempo desde que se lanza un proceso hasta que finaliza.
• Tiempo de espera. Tiempo total de estancia en las colas de espera.
• Tiempo de respuesta (response time). Tiempo desde que se lanza una orden hasta que se
obtiene el resultado.
• Plazo de finalización (deadline). Tiempo máximo que un proceso tiene para ser completado
en un sistema de tiempo real.
La elección de los criterios a optimizar depende del tipo de sistema operativo. En un sistema por
lotes debe intentar maximizar la utilización del procesador y la productividad, uno de tiempo
compartido el tiempo de respuesta y uno de tiempo real el tiempo de entrega.

18 Capítulo 3. Planificación de procesos


Normalmente, el planificador optimiza los valores medios de los criterios que considera.
Es más importante minimizar la varianza en el tiempo de respuesta que minimizar el tiempo de
respuesta promedio.
Cuando se intentan optimizar varios criterios simultáneamente, se debe tener en cuenta que pueden
ser incompatibles entre sí.

Expropiabilidad del procesador


Planificación del procesador no expropiativa (non preemptive) si permite que un proceso pueda
estar ejecutándose en el procesador ininterrumpidamente.
• Utilizada en sistemas por lotes.
• También se utiliza en sistemas en tiempo real, en el que los procesos no utilizan el
procesador por largos períodos de tiempo.
Planificación del procesador expropiativa (preemptive) si el proceso que se está ejecutando puede
ser interrumpido en cualquier momento.
• Mayor sobrecarga en el sistema
• Proporciona mejor servicio a la población de procesos
• Requiere que el núcleo disponga de mecanismos de sincronización
• Utilizada en sistemas de tiempo compartido o interactivos.
El tiempo máximo de ejecución ininterrumpida se denomina quantum (cuanto).

Algoritmos de planificación

Primero en llegar – primero en ser servido – FCFS


Abreviadamente FCFS (First Come First Served).
• Cede el uso del procesador al primer proceso que lo solicite.
• No expropiativo.
• Requiere de una cola FIFO de procesos preparados.
• Tiempo de espera promedio bastante grande.
• Mejor para procesos largos.
• Favorece a los procesos limitados por el procesador frente a los limitados por E/S.
• Se desaconseja su uso como principal algoritmo de planificación. Útil en combinación con
otros.

Primero el proceso más corto – SJF


Abreviadamente SJF, Shortest Job First o SPN Shortest Job Next.
• Se ejecuta primero el proceso con tiempo de procesamiento más corto.
• No expropiativo.
• Si dos o más procesos tienen el mismo tiempo de procesamiento se aplica FCFS.
• Minimiza el tiempo de espera promedio de un conjunto de procesos.

Apuntes por Demetrio Quirós – Fundamentos básicos de los Sistemas Operativos 19


• Se suele utilizar en SO por lotes, tanto en el planificador a largo como a corto plazo.
• Se precisa conocer por adelantado el tiempo de procesamiento de cada proceso.
• En SO de tiempo compartido, se puede estimar la duración de las siguientes ráfagas
utilizando la duración de las anteriores. Se suele utilizar un preditor promedio exponencial.
M n+ 1=α⋅t n+ (1−α)⋅M n . donde Mn+1 es el promedio estimado para la próxima ráfaga; t n es
la duración de la última ráfaga, Mn el promedio estimado para la última ráfaga y α el peso
que se le asigna entre 0 y 1.
• Al tener que calcular estimaciones, la sobrecarga se hace mayor cuanto mayor es la
precisión del cálculo.
• Los procesos largos pueden sufrir inanición.

Menor tiempo restante


Abreviadamente SRT, Shortest Remaining Time next, versión expropiativa del SFJ.
• Algoritmo expropiativo.
• Siempre selecciona al proceso con el menor tiempo restante de ejecución.
• Suele utilizarse en sistemas de procesos por lotes.
• Requiere una estimación de los tiempos restantes de ejecución de la población de procesos.
• Puede producir inanición a los procesos largos.
• A igualdad de tiempo de servicio restante se aplica FCFS.

Planificación de turno rotatorio


Round Robin o cíclico, similar al FCFS pero expropiatorio.
• Asigna el uso ininterrumpido del procesador durante un periodo de tiempo determinado
llamado cuanto, quantum o time slice.
• Al finalizar el cuanto, se interrumpe el proceso actual y se ejecuta el siguiente en la cola. El
proceso interrumpido pasa al final de la cola.
• Si un proceso finaliza antes que su cuanto, se planifica el siguiente proceso preparado sin
esperar a la finalización del cuanto.
• Si finaliza el cuanto de un proceso y no existen procesos en cola, vuelve a planificarse el
mismo proceso.
• Elemento clave para el rendimiento del algoritmo es la elección del tamaño del cuanto.
• Se recomienda un cuanto ligeramente mayor que el tiempo promedio de duración de una
ráfaga de procesador.
• Algoritmo diseñado para los sistemas de uso compartido.
• El tiempo de respuesta promedio, el tiempo de retorno promedio y el tiempo de espera
promedio pueden ser largos.

Planificación basada en prioridades


Asigna a cada proceso una determinada prioridad en el momento de su creación.
• Siempre se planifica para ejecución el proceso de mayor prioridad.

20 Capítulo 3. Planificación de procesos


• La asignación de prioridades a los procesos puede realizarse en función de factores internos
del sistema, como requerimientos de memoria, duración promedio de la ráfaga.. o a factores
externos, como la importancia del usuario.
• Si la prioridad asignada no se modifica durante el tiempo de vida del proceso, se denomina
asignación de prioridades estática; dinámica si se modifica.
• Puede ser expropiativo y no expropiativo. Cuando es de tipo expropiativo se dice que está
guiado por eventos (event-driven).
• Un proceso con baja prioridad puede sufrir inanición.
• Técnicas para evitar la inanición:
◦ Envejecimiento de procesos (aging), aumentando la prioridad conforme aumenta el
tiempo de espera.
◦ Disminuir la prioridad del proceso en ejecución en cada interrupción de reloj.
◦ Limitar el tiempo de ejecución.
• Puede darse el fenómeno de inversión de prioridad que ocurre cuando un proceso más
prioritario debe esperar a que un recurso se libere por otro proceso con menor prioridad.
Puede resolverse mediante el traspaso o herencia de prioridad.

Planificación basada en múltiples colas de prioridad


Se disponen varias colas cada una de las cuales dispone únicamente de procesos con un
determinado nivel de prioridad o dentro de un rango de prioridades.
• Siempre se ejecuta un proceso de la cola de mayor prioridad.
• Sólo cuando esa cola se vacía, se ejecutan los de la siguiente cola.
• Un proceso sólo puede pertenecer a una cola.
• Para planificar cada cola puede usarse FCFS, SJF, etc.
• Puede producirse inanición de los procesos de las colas de menor prioridad. Para evitarlo,
puede asignarse a los procesos de cada cola un porcentaje de tiempo de procesador

Múltiples colas de prioridad y realimentación


Se permite que un proceso pueda ir cambiando de cola de prioridad durante su existencia.
• Requiere definir un mecanismo que regule cómo se modifica la prioridad de los procesos,
esto es, cómo y cuándo se produce el paso de una cola a otra.
• Un mecanismo puede consistir en reducir la prioridad del proceso en cada cuanto de
ejecución hasta que llega a la cola de menor prioridad, donde se queda, siendo entonces esta
cola de turno rotatorio.
◦ Con este mecanismo se favorecen los procesos nuevos y cortos frente a los viejos y
largos.
• Para evitarlo puede asignarse un cuanto de mayor tamaño conforme disminuye la prioridad
de las colas.
◦ Esta técnica no evita compeltamente la inanición, por lo que puede combinarse con la de
envejecimiento de procesos.

Apuntes por Demetrio Quirós – Fundamentos básicos de los Sistemas Operativos 21


Planificación por tiempo límite
En los sistemas de tiempo real estricto el tiempo de servicio de algunos procesos debe completarse
en un determinado plazo o tiempo límite (deadline).
• El planificador sólo admite en la cola de procesos preparados aquellos a los que pueda
garantizar que su tiempo de servicio se atenderá dentro de su tiempo límite, en función de
los tiempos de espera existentes en la cola.
• Debe conocerse por adelantado el tiempo de servicio y deadline de cada proceso

Elección del algoritmo de planificación


En primer lugar deben fijarse los criterios de selección y a continuación evaluar los diferentes
algoritmos de planificación usando algún método de evaluación.
• Modelado determinista. Evalua cada algorimo candidato usando una carga de trabajo
predeterminada e idéntica para todos ellos. Es difícil establecer esta carga de manera realista
y manejable.
• Modelo analítico mediante sistema de colas. Se obtiene un modelo analítico matemático.
Cada recurso hardware del sistema y cada cola software asociada se modela como una
estación de servicio que consta de un servidor y una cola de espera. Se establece para cada
estación de servicio una determinada tasa de llegada y una tasa de servicio de peticiones. El
conjunto formado por las estaciones de servicio y sus clientes (los usuarios) forma un
sistema de colas que puede ser analizado usando la teoría de colas.
• Simulación. Se construye un programa que reproduce el comportamiento temporal del
sistema basándose en sus estados y sus transiciones.

Planificación de hilos
La planificación de hilos depende de los tipos de hilos soportados por el SO.
• Si sólo se soportan hilos a nivel de usuario el SO no es consciente de su existencia, debiendo
ser el proceso que los lanza quien debe encargarse de su planificación.
• Si se soportan hilos del núcleo el sistem operativo los planifica utilizando alguno de los
métodos vistos anteriormente.
◦ El planificador debe tener en cuenta la sobrecarga que puede producir en el sistema el
cambio de contexto entre hilos de distintos procesos.

22 Capítulo 3. Planificación de procesos


Capítulo 4. Sincronización y comunicación de procesos
La ejecución concurrente de procesos presenta varios problemas, todos ellos asociados al hecho de
que no es posible predecir la velocidad relativa de ejecución de un proceso. Dicha velocidad es
función de la política de planificación del sistema operativo, de la forma en que se tratan las
interrupciones y de la actividad de los otros procesos en el sistema.
Uno de los principales problemas de la ejecución concurrente de procesos es que el acceso a
recursos globales compartidos (memoria, dispositivos de E/S, etc) debe controlarse de alguna forma
si se desea que el resultado de la ejecución de un proceso sea independiente de la velocidad de
ejecución del proceso con respecto a los otros procesos concurrentes.

Exclusión mutua

Interacción entre procesos concurrentes


En un sistema con multiprogramación se ejecutan múltiples procesos de manera concurrente.
Podemos distinguir
• Procesos independientes, que se ejecutan sin tener en cuenta la existencia de otros procesos.
• Procesos cooperantes, que intercambian información o colaboran entre sí para compartir un
recurso o realizar alguna tarea.
◦ Cooperación directa: los procesos conocen la existencia e identidad de los otros procesos
con los que colaboran.
◦ Cooperación indirecta, los procesos no conocen la existencia e identidad de los otros
procesos y, en consecuencia, no se comunican con ellos pero deben garantizar que los
recursos queden en un estado coherente.

Condiciones de carrera
El problema denominado condición de carrera (race condition) surge cuando múltiples procesos
independientes se ejecutan concurrentemente y acceden para leer o escribir en un recurso
compartido. En ese caso el resultado final de la ejecución depende del órden en que se hayan
planificado los procesos.

Secciones críticas
Sección crítica o región crítica de un proceso es una instrucción o conjunto de instrucciones
secuenciales de su código que requieren manipular un recurso compartido (variable, dato, fichero,
…) con otros procesos. Dentro del código de un proceso pueden existir varias regiones críticas.

Descripción de la exclusión mutua


Las condiciones de carrera se evitarían si el uso de un recurso por parte de un proceso excluye su
uso para los restantes. Este mecanismo se denomina de exclusión mutua.
Sin más requisitos adicionales la exclusión mutua puede producir problemas como interbloqueos o
inanición de procesos.
• El interbloqueo o bloqueo mutuo de dos o más procesos se produce cuando dos procesos A y
B necesitan dos recursos R1 y R2 para realizar una cierta función. Si A posee R1 y B posee
R2, ambos se quedarán esperando por el recurso que necesitan; no pueden liberar el recurso
que poseen porque están esperando el otro recurso para realizar la función correspondiente.

Apuntes por Demetrio Quirós – Fundamentos básicos de los Sistemas Operativos 23


• La inanición de un proceso se produce cuando este no puede progresar al necesitar un
recurso al que nunca llega a acceder porque el sistema operativo siempre da prioridad a
otros procesos.
Para evitar esto, los mecanismos de exclusión mutua deben cumplir cinco requisitos:
1. Sólo un proceso puede estar a la vez en una sección crítica asociada a un recurso R.
2. No pueden realizarse suposiciones sobre la velocidad relativa y prioridad de ejecución de los
procesos concurrentes.
3. Un proceso que no está ejecutando una sección crítica asociada a un recurso R no está
impidiendo o bloqueando el uso de R a otros procesos.
4. Debe evitarse la inanición de procesos. Un proceso no debe permanecer en su sección crítica
por tiempo ilimitado.
5. Si ningún proceso está en una sección crítica asociada a R, debe concederse rápidamente el
acceso a esa sección crítica al proceso que lo solicite.

Soluciones software a la exclusión mutua


No presuponen el apoyo del sistema operativo o del hardware del ordenador para su
implementación.
Hacen uso de un bucle de comprobación del valor de una o varias variables cerrojo (lock). La
comprobación del valor en un bucle se denomina cerrojo con vuelta (spinlock). Este tipo de espera
se denomina espera activa (busy waiting) o espera cíclica (spin waiting).
• Uso de cerrojo y alternancia estricta. Esta solución considera la existencia de una variable
global de acceso que se usa como cerrojo y que puede tomar como valor el identificador
numérico de un proceso.
Este método posee dos inconvenientes: la velocidad de ejecución se ve limitada por el
proceso más lento. Además, si un proceso falla antes de cambiar el valor de la variable
global el otro proceso quedará bloqueado indefinidamente.
• Algortimo de Peterson. Simplificado para dos procesos, se dispone de un vector donde cada
proceso establece a TRUE su deseo de acceder al recurso. Además, se guarda en una variable
global el identificador del otro proceso. Un bucle de espera cíclica comprueba que la
petición pueda ser atendida y que el recurso no está siendo utilizado por el otro proceso.

#define FALSE 0
#define TRUE 1
int turno;
int peticion_rec[2];
void acceso_sc(int pid) {
int otro_pid;
otro_pid = 1 – pid;
peticion_rec[pid] = TRUE;
turno = otro_pid;
while(turno == otro_pid && peticion_rec[otro_pid == TRUE):
}

Cada proceso llama a acceso_sc antes de acceder a su sección crítica y al salir llamaría a
salida_sc, que establece a FALSE su entrada en peticion_rec. Este algoritmo garantiza la
exclusión mutua ya que el proceso que primero ejecuta la instrucción
peticion_rec[pid] = TRUE obtiene el acceso al recurso. Se evita la posibilidad de
interbloqueo al almacenarse en turno el valor del pid del otro proceso.

24 Capítulo 4. Sincronización y comunicación de procesos


Soluciones a la exclusión mutua con apoyo del hardware
• Uso de instrucciones máquina especiales que bloquean el uso del bus. Se caracterizan por
ser atómicas, es decir, se ejecutan en un único ciclo de instrucción que no puede ser
interrumpido. Una instrucción típica en muchos procesadores es probar y configurar (test
and set): ccc r1, cerrojo, que copiaría el contenido de la posición de memoria compartida
cerrojo en el registro r1 y escibe en cerrojo un valor distinto de cero.

El principal inconveniente es que también hay que realizar una espera activa para comprobar
el valor del cerrojo. También pueden producirse interbloqueos.
• Bloqueo de las interrupciones. Antes de entrar en una región crítica, puede ejecutarse una
instrucción especial que bloquea el mecanismo de interrupciones del sistema, restaurándolo
al salir de la sección crítica. Pero el sistema se puede degradar bastante al no permitirse
atender las interrupciones mas prioritarias en el momento en que llegan, Además, se deja en
manos del proceso la decisión de ceder el procesador, pudiendose quedar el sistema colgado
si este nunca lo devuelve. Esta solución no sirve en el caso de multiprocesadores.

Semáforos
Son un mecanismo de sincronización de procesos concurrentes gestionados por los sistemas
operativos. Un semáforo es una variable que almacena un valor entero sobre el que se pueden
realizar tres operaciones básicas:
• Asignar un valor inicial entero no negativo. S = N

• P(S). [wait]. Disminuir en una unidad el valor del semáforo. S = S – 1. Si S se hace


negativo, el proceso que ha llamado al semáforo pasa a la cola de procesos bloqueados
asociada al semáforo.
• V(S). [signal].Incrementa en una unidad el valor del semáforo, S = S + 1. Si S es menor o
igual a cero, se eliminar uno de los procesos bloqueados la cola y se pasa al estado
preparado.
Los nombres P y V, se suelen encontrar como wait y signal. En este texto wait_sem y signal_sem.
El anterior es un semáforo general o semáforo con contador. La versión de semáforo que sólo puede
tomar los valores 0 y 1 se denomina semáforo binario o mutex funcionando de la siguiente manera:
• wait_sem(S). Si S = 0, el proceso pasa a cola de bloqueados, si S = 1, pone el semáforo a
cero y continúa su ejecución.
• signal_sem(S). Si la cola de bloqueados está vacía, pone el semáforo a 1 y continúa. Si no
está vacía, se elimina un proceso de la cola de bloqueados y pasa al estado preparado.

Implementación
El sistema operativo se encarga de asignar las estructuras de datos necesarias para los semáforos y
de realizar las operaciones sobre ellos.
Las operaciones wait_sem y signal_sem son implementadas por el núcleo como primitivas o
funciones atómicas, esto es, que se ejecutan como un único ciclo de instrucción que no puede ser
interrumpido.
En la implementación de estas primitivas en el núcleo se ha de resolver un problema de exclusión
mutua.
En sistemas monoprocesadores la exclusión mutua se garantiza bloqueando las interrupciones
cuando se está ejecutando una operación sobre el semáforo.

Apuntes por Demetrio Quirós – Fundamentos básicos de los Sistemas Operativos 25


struct semaforo {
int contador;
/* Otras variables para implementar el semáforo y su cola */
/* que dependen del sistema operativo */
}

void init_sem(semaforo S, int valor)


S.contador = valor;
}

void wait_sem(semaforo S) {
/* Bloqueo de interrupciones */
S.contador = S.contador – 1;
if (S.contador < 0) {
/* Añadir el proceso a la cola del semáforo */
/* Bloquear el proceso */
/* Desbloquear las interrupciones */
} else {
/* Desbloquear las interrupciones */
}
}

void signal_sem(semaforo S) {
/* Bloqueo de las interrupciones */
S.contador = S.contador + 1;
if (contador <= 0) {
/* Eliminar un proceso P de la cola del semáforo */
/* Añadir el proceso P a la cola de procesos preparados */
}
/* Desbloqueo de las interrupciones */
}

En sistemas multiprocesador no puede emplearse la técnica de bloqueo de interrupciones, sino que


se utilizan instrucciones especiales del procesador.

struct semaforo {
int contador;
int ocupado;
/* Otras variables para implementar el semáforo y su cola */
/* que dependen del sistema operativo */
}

void init_sem(semaforo S, int valor)


S.contador = valor;
}

void wait_sem(semaforo S) {
while (!test_set_maquina(S.ocupado)) // Bucle de espera activa
S.contador = S.contador – 1;
if (S.contador < 0) {
/* Añadir el proceso a la cola del semáforo */
/* Bloquear el proceso */
S.ocupado = 0;
}

void signal_sem(semaforo S) {
while (!test_set_maquina(S.ocupado)) // Bucle de espera activa
S.contador = S.contador + 1;
if (contador <= 0) {
/* Eliminar un proceso P de la cola del semáforo */
/* Añadir el proceso P a la cola de procesos preparados */
}
S.ocupado = 0;
}

Si el procesador no dispone de ninguna instrucción especial, debe emplearse algún algoritmo como
el de Peterson.
La cola puede gestionarse con cualquier algoritmo, siendo FIFO el más utilizado.

26 Capítulo 4. Sincronización y comunicación de procesos


Utilidad de los semáforos

Obtención de exclusión mutua


Se utilizan tantos semáforos como recursos distintos se compartan, protegiendo el acceso a los
recursos mediante secciones críticas.
#define TRUE 1
semaforo S
void proceso_X() {
while(TRUE) {
/* Sección no crítica */
wait_sem(S);
/* Sección crítica asociada al recurso a utilizar */
signal_sem(S);
/* Sección no crítica*/
}
}

Sincronización de procesos
En este caso basta con que el proceso que espera la ocurrencia de un suceso ejecute wait_sem para
pasar al estado bloqueado. El proceso que lanza la operación ejecuta signal_sem para notificar que
el suceso se ha producido, provocando que el proceso que espera prosiga su ejecución.

#define TRUE 1
semaforo S

void procesoA() {
while(TRUE) {
// . . .
wait_sem(S); // Se bloquea en espera de un evento
// . . .
}
}

void procesoB() {
while(TRUE) {
// . . .
signal_sem(S); // Notifica la ocurrencia de un evento
// . . .
}
}

void main() {
init_sem(S, 0); // Inicia el semáforo binario S
ejecución_concurrente(procesoA, procesoB);
}

Problemas potenciales asociados a un mal uso de los semáforos


Una mala colocación de las operaciones signal_sem y wait_sem puede provocar errores difíciles de
detectar. En los siguientes ejemplos el semáforo acceso se utiliza para garantizar exclusión mutua.

signal_sem(acceso);
// Sección crítica
wait_sem(acceso);

En este caso se ha invertido el órden correcto de las operaciones, por lo que varios procesos podrían
estar accediendo al mismo tiempo a la sección crítica.

wait_sem(acceso);
// Sección crítica
wait_sem(acceso)

En este ejemplo se escibe un segundo wait_sem en lugar del correcto signal_sem para indicar la
liberación del recurso. Por tanto, el proceso nunca desbloqueará el recurso, ya que una vez

Apuntes por Demetrio Quirós – Fundamentos básicos de los Sistemas Operativos 27


finalizada la sección crítica vuelve a bloquearse. El resto de procesos que intenten acceder a su
sección crítica también serán bloqueados ya que el recurso nunca se ha dado por liberado
produciéndose un interbloqueo.

Problemas clásicos de sincronización de procesos concurrentes

El problema de los productores y los consumidores


Un proceso (o varios) generan datos y otro proceso (o varios) los consumen. Se utiliza un buffer (el
recurso compartido a proteger), en el que los productores escriben, si no está lleno, y los
consumidores leen, si no está vacío.

#define TRUE 1
#define N 100 // Tamaño del buffer
semaforo_binario acceso;
semaforo ocupado, disponible;

void productor() {
int dato; // Dato a grabar en el buffer
while (TRUE) {
dato = generar_dato();
wait_sem(disponible); // Espera/comprueba que el buffer tenga espacio libre
wait_sem(acceso); // Espera a que el buffer esté disponible
escribir_buffer(dato); // Entrar en sección crítica: escribir en el buffer
signal_sem(acceso); // Liberar el buffer
signal_sem(ocupado); // Avisa al consumidor de la existencia de datos
}
}

void consumidor() {
int dato; // Dato a leer del buffer
while (TRUE) {
wait_sem(ocupado); // Espera a que haya datos disponibles en el buffer
wait_sem(acceso); // Espera a que el buffer esté disponible
leer_buffer(dato); // Leer dato del buffer / Sección crítica
signal_sem(acceso); // Liberar el buffer
signal_sem(disponible); // Informa que tras la lectura, hay espacio en el buffer
}
}

void main() {
init_sem(acceso, 1); // Inicializa el semáforo binario
init_sem(disponible, N); // Indica el espacio disponible
init_sem(ocupado, 0); // Indica el espacio ocupado
ejecución_concurrente(productor, consumidor);
}

Se utilizan un semáforo binario para acceder al buffer y dos semáforos para indicar el espacio
disponible y el ocupado en el buffer, que serán utilizados por los consumidores y productores.

El problema de los lectores y los escritores


Un ejemplo típico de acceso a bases de datos. Múltiples lectores acceden a los registros, un escritor
sólo puede acceder si no hay ningún lector accediendo. Los lectores sólo pueden acceder si no se
está escribiendo. Múltiples lectores pueden estar accediendo al mismo tiempo. Sólo un escritor
puede acceder.
Para llevar la cuenta del número de lectores se utiliza una variable global contador cuyo acceso se
protege mediante un semáforo binario. Otro semáforo binario controla el acceso a los datos.

28 Capítulo 4. Sincronización y comunicación de procesos


#define TRUE 1
semaforo_binario S1, S2;
int contador = 0;

void lector() {
while (TRUE) {
wait_sem(S2); // Intenta acceder a la variable contador
contador = contador + 1; // Hay un lector más accediendo
if (contador == 1) wait_sem(S1); // Si es el 1er lector, bloquea el acceso al escritor
signal_sem(S2); // Se libera el acceso a la variable contador
leer_dato();
wait_sem(S2); // Solicitud de acceso a la variable contador
contador = contador – 1; // Hay un lector menos
if (contador == 0) signal_sem(S1); // No hay lectores, se permite el acceso al escritor
signal_sem(S1); // Libera el acceso a la variable contador
procesar_dato();
}
}

void escritor() {
producir_dato();
wait_sem(S1); // Espera a tener acceso de escritura
escribir_dato();
signal_sem(S1); // Libera el recurso
}

void main() {
init_sem(S1, 1);
init_sem(S2, 1);
contador = 0;
}

Monitores

Definición
Un monitor, es un módulo software que consta de un conjunto de procedimientos, variables y
estructuras de datos que posee la propiedad especial de que solo permite a un único proceso
simultáneamente ejecutar alguno de sus procedimientos. Las variables contenidas en un monitor
sólo son accedidas por los procedimientos del monitor y no por procedimientos externos.
Para la sincronización de procesos, el monitor dispone de las variables de condición, cada una de
ellas asociadas a una cola de procesos bloqueados en espera de que esa condición se cumpla.
Sobre una variable de condición se pueden realizar dos operaciones, en este texto:
• wait_mon(X). El proceso que realiza esta operación queda suspendido en la cola de procesos
bloqueados asociada a la condición X. Al contrario que en los semáforos, esta operación
siempre produce el bloqueo del proceso que la invoca.
• signal_mon(X). Comprueba si en la cola de procesos bloqueados asociada a la variable X
existe algún proceso. En ese caso, se desbloquea un proceso. Esta operación no opera sobre
un contador. Si no hay ningún proceso en cola, esta operación no tiene ningún efecto y la
señal de aviso se pierde. Según la propuesta de B. Hansen (1975) el proceso que invoca esta
operación sale del monitor inmediatamente, siendo por tanto la sentencia final del
procedimiento de un monitor.

Estructura y declaración de un monitor


Un monitor consta de N procedimientos, M variables de condición, un conjunto de datos y algunas
rutinas de inicialización del monitor. En el monitor sólo puede haber a la vez un proceso ejecutando
alguno de sus procedimientos.
Cuando un proceso entra en el monitor permanece hasta que invoque wait_mon(X). En ese momento
el proceso pasa a la cola de bloqueados X pudiendo entrar otro proceso al monitor. Si un proceso en

Apuntes por Demetrio Quirós – Fundamentos básicos de los Sistemas Operativos 29


el monitor invoca signal_mon(X) un proceso de la cola de bloqueados es desbloqueado o, si
estuviera vacía, entraría un nuevo proceso al monitor en caso de que hubiese procesos esperando en
la cola de entrada.

Uso de los monitores


Los monitores también pueden utilizarse para garantizar la exclusión mutua y la sincronización
entre procesos.
Por la propia definición del monitor la exclusión mutua está garantizada defininiendo el acceso a los
recursos compartidos dentro del monitor.
Mediante el uso de las variables de condición y las operaciones wait_mon y signal_mon se puede
proporcionar la sincronización de procesos.
La solución a los productores y consumidores utilizando monitores sería:

#define TRUE 1
#define N 100 // Capacidad del buffer
monitor mon1 // Definición del monitor
condicion lleno vacio; // Variables de condición
int contador; // Variables locales
char buffer[N];

void escribir(int dato) { // Procedimiento del monitor


if (contador == N) wait_mon(lleno); // Si buffer está lleno, bloquea escritor
insertar_dato(buffer, dato);
contador = contador + 1;
if (contador == 1) signal_mon(vacio); // Si buffer no vacío, desbloquea lector
}

void leer(int dato) {


if (contador == 0) wait_mon(vacio); // Si buffer vacío, se bloquea lector
extraer_dato(buffer, dato);
contador = contador – 1;
if (contador == N-1) signal_mon(lleno); // Si no lleno, desbloquea escritor
}

{
contador = 0; // Inicialización del monitor
}
end monitor

void productor() {
while (TRUE) {
dato = producir_dato();
mon1.escribir(dato);
}
}

void consumidor() {
while (TRUE) {
mon1.leer(dato);
consumir_dato(dato);
}
}

void main() { ejecucion_concurrente(productor, consumidor) }

Paso de mensajes

Definición
El paso de mensajes es un mecanismo de sincronización y comunicación entre procesos soportado
por los sistemas operativos tanto de sistemas centralizados como distribuidos. Un mensaje es un
conjunto de información que puede ser intercambiada entre un proceso emisor y un proceso
receptor.
Las operaciones básicas son:

30 Capítulo 4. Sincronización y comunicación de procesos


send(destino, mensaje)
receive(fuente, mensaje)

El argumento mensaje es la dirección de memoria de la estructura de datos que contiene el mensaje


a enviar o donde se almacena el mensaje a recibir.
Los aspectos básicos a considerar son
• La especificación de la fuente y el destino del mensaje.
• El esquema de sincronización.
• El formato del mensaje.
• El medio de almacenamiento.

Especificación de la fuente y el destino del mensaje

Comunicación directa
Emisor y receptor del mensaje especifican explícitamente a qué proceso va dirigido o de quién se
espera el mensaje. Otra posibilidad es que el receptor especifique implícitamente el proceso emisor
del mensaje, pudiendo llegar éste de cualquier emisor.
La comunicación directa explícita es útil para procesos concurrentes cooperantes, la comunicación
directa implícita cuando un proceso realiza una operación en función del mensaje enviado por un
proceso que no se conoce a priori (cola de impresión...).
Comunicación indirecta
El proceso emisor envía el mensaje a una estructura de datos compartida, el buzón, que se
implementa como una cola de mensajes.
• Un emisor – un receptor: para comunicación privada entre procesos.
• Un emisor – varios receptores: para difundir determinada información entre varios procesos.
• Varios emisores – un receptor: típico en aplicaciones cliente – servidor.
• Varios emisores – varios receptores: varios servidores atienden concurrentemente a varios
clientes.

Esquemas de sincronización
Pueden distinguirse varios casos en función de si el proceso emisor o receptor pueden pasar al
estado bloqueado al realizar una operación send o receive.
• Send con bloqueo: el emisor pasa al estado bloqueado hasta que el mensaje sea recibido por
el receptor o por el buzón.
• Send sin bloqueo: el emisor envía el mensaje al buzón o al destinatario y sigue con su
ejecución. Al no garantizarse su recepción deben emplearse mensajes de respuesta. El
emisor también podría estar intentando enviar el mensaje repetidamente, degradando el
rendimiento
• Receive con bloqueo: el receptor permanece en estado bloqueado en espera un mensaje. Si
este nunca llega, el receptor quedaría indefinidamente bloqueado.
• Receive sin bloqueo. El receptor obtiene un mensaje de un buzón o un emisor y prosigue su
ejecución. El mensaje puede ser nulo o no.
El esquema más utilizado es el envío sin bloqueo y la recepción con bloqueo. El envio y recepción
con bloqueo se conoce como cita (rendezvous) entre emisor y receptor.

Apuntes por Demetrio Quirós – Fundamentos básicos de los Sistemas Operativos 31


Formato y almacenamiento de los mensajes
El mensaje está formado por una cabecera y un cuerpo.
La longitud del mensaje puede ser fija o variable. Los mensajes de longitud fija son más eficientes
para el sistema operativo, siendo los de longitud variable más sencillos para el programador de los
procesos emisores.
Dependiendo de la capacidad de las colas de mensajes tenemos
• Mecanismo de mensajes sin buffer, en el que los mensajes nunca pueden esperar y el proceso
emisor se bloquea en espera de su recepción.
• Mecanismo de mensajes con buffer, en el que los mensajes se almacenan en un buffer
normalmente gestionado por un algoritmo de tipo FIFO.

Uso del paso de mensajes


Se pueden utilizar para intercambiar información entre procesos así como para garantizar la
exclusión mutua y la sincronización.
#define TRUE 1
#define N 5 // Número de procesos
void proceso(int i) {
mensaje testigo;
while (TRUE) {
// Sección no crítica
receive(buzon1, testigo);
// Sección crítica
send(buzon1, testigo);
// Sección no crítica
}
}
void main() {
mensaje nulo;
crear_buzon(buzon1);
send(buzon1, nulo);
ejecucion_concurrente(proceso(1),..., proceso(N));
}

Ejemplo de exclusión mutua utilizando un buzón y send sin bloqueo y receive con bloqueo. El
mensaje se utiliza como paso de testigo para ir pasando la utilización del recurso entre procesos.

32 Capítulo 4. Sincronización y comunicación de procesos


Capítulo 5. Interbloqueo

Introducción
De forma general, un recurso hardware o software se puede clasificar en:
• Recurso reutilizable, como archivos, semáforos, y elementos hardware. Una instancia de un
recurso reutilizable sólo puede asignarse a un proceso como máximo. Sólo cuando un
proceso finaliza el uso de de una instancia de un recurso reutilizable puede ser usada por
otro. Los recursos hardware son reutilizables.
• Recurso consumible, como buffers de entrada/salida y mensajes. Estos recursos pueden
crearse y posteriormente consumirse (destruirse).

Definición y condiciones del interbloqueo


De forma general puede definirse como aquella situación en la que un conjunto de procesos está
bloqueado en espera de la liberación de uno o varios recursos que se encuentran asignados a otros
procesos del mismo conjunto.
Para que se produzca el interbloqueo es necesario que se produzcan cuatro condiciones:
1. Exclusión mutua, por la que cada instancia de un recurso solo puede ser asignada a un
proceso como máximo.
2. Retención y espera. Cada proceso retiene los recursos asignados mientras espera adquirir
otros que necesita.
3. No existencia de expropiación. Si un proceso posee un recurso, no se le puede expropiar.
4. Espera circular, en la que una cadena de procesos se encuentra uno esperando la liberación
de un recurso que posee el siguiente en la cadena y el último espera por el primero.
Tres son las principales estrategias para el tratamiento de los interbloqueos:
1. Prevención de interbloqueos, impidiendo que alguna de las cuatro condiciones anteriores
llegue a producirse.
2. Evitación de interbloqueos, examinando las consecuencias de asignar los recuros antes de
hacerlo.
3. Detección y recuperación de interbloqueos, comprobando cada cierto tiempo la existencia
de interbloqueos y actuando para eliminarlos de haberse producido.

Grafos de asignación de recursos


Un grafo de asignación de recursos puede utilizarse para detectar la presencia de interbloqueos,
suponiendo que las condiciones de exclusión mutua y no expropiación ya se cumplen. Con los
grafos se comprueba si existe condiciones de retención y espera y espera circular.
Si el grafo no contiene ningún camino que sea un ciclo puede garantizarse la no existencia de
interbloqueos. Si aun habiendo un ciclo alguno de los recursos dispone de más de una instancia y
esa instancia no forma parte de otro ciclo no existe interbloqueo.
Cada proceso se representa con un cículo y cada recurso con un cuadrado. Cada instancia de un
recurso se representa con un punto dentro del cuadrado. Si un proceso ha solicitado un recurso y se
encuentra bloqueado se representa una flecha que sale del proceso hacia el recurso. Si un proceso
tiene asignada una instancia de un recurso se representa una flecha desde la instancia del recurso
hasta el proceso.

Apuntes por Demetrio Quirós – Fundamentos básicos de los Sistemas Operativos 33


Figura 5.1: Grafo de asignación de recursos.
Con un ciclo, pero sin interbloqueos.

Prevención de interbloqueos
Esta estrategia persigue eliminar alguna de las cuatro condiciones necesarias para la existencia de
interbloqueos.

Eliminación de la condición de exclusión mutua


Esta condición no puede eliminarse en recursos compartidos si se quiere garantizar la integridad y
no corrupción.

Eliminación de la condición de retención y espera


Puede eliminarse haciendo que un proceso solicite al mismo tiempo todos los recursos que precisa,
no concediéndoselos si alguno no se encuentra disponible. Requiere el previo conocimiento de las
necesidades. Puede degradar el rendimiento del sistema o provocar inanición si un proceso retiene
un recurso y otros esperan a obtenerlo. Los recursos pueden verse infrautilizados.

Eliminación de la no existencia de expropiación


La expropiación solo es posible si el sistema puede salvar el estado en que se encuentra antes de la
expropiación para poder restaurarlo al mismo estado una vez devuelto. Aumenta la sobrecarga del
sistema.

Eliminación de la espera circular


Puede eliminarse asignando un número a cada recurso y obligando a que los procesos sólo puedan
solicitar los recursos en orden ascendente. La principal desventaja es que los recursos deben ser
solicitados en ese orden y no cuando realmente se necesiten.

Evitación de interbloqeos
Consiste en conceder sólo aquellas peticiones de recursos que tengan garantizado que no
conducirán a un estado de interbloqueo.
Un proceso debe especificar por adelantado todos los recursos que va a necesitar. Después, los va
solicitando conforme los va necesitando. Si la concesión es segura, no conduce a interbloqueo, se
realiza.
El sistema operativo debe llevar la cuenta de los recursos disponibles, el número de recursos
asignados a cada proceso y el número de recursos que restan por asignar. Además comprueba que la
asignación es segura.

34 Capítulo 5. Interbloqueo
Estado de la asignación de recursos: estados seguros y estados inseguros.
Se dispone de:
Vector de recursos existentes, RE; cada elemento del vector R En indica la cantidad de instancias n
existentes del recurso R.
Vector de recursos disponibles, RD; donde se indica el número de instancias disponibles del recurso
R.
Matriz N de recursos máximos necesitados por cada proceso. Cada fila corresponde a un proceso y
cada columna a un recurso existente en el sistema.
Matriz A de recursos asignados a cada proceso, correspondiendo cada fila a un proceso y cada
columna al número de recursos asignados
El estado del sistema con respecto a la asignación de sus recursos en un instante determinado queda
definido por los vectores RE, RD y las matrices N y A.
Un estado se dice que es seguro si posibilita al menos una secuencia de asignación de recursos a los
procesos que garantiza que estos puedan finalizar sin producirse interbloqueos. Un estado inseguro
no ofrece esa garantía, aunque no necesariamente tiene que conducir a un estado de interbloqueo.
En la práctica, habría que comprobar que ( N i− Ai)≤R D , esto es, que los recursos necesitados
menos los asignados no superan los recursos disponibles.
Ver ejemplos 5.3 y 5.4 en el libro de teoría, páginas 176-179.

Denegación de asignación de recursos: el algoritmo del banquero.


Consiste en no conceder una petición de recurso si esta concesión puede conducir a un estado
inseguro.
Este algoritmo asegura que el número de recursos asignados a todos los procesos nunca puede
exceder del número de recursos del sistema y que nunca se puede hacer una asignación peligrosa,
que conduzca a un estado inseguro. Para ello:
1. Se parte de un estado inicial seguro Sk, con k = 0: Sk = {N, A, RE, RD}
2. Cuando un proceso solicita un recurso se simula su concesión y se crea un estado ficticio
S' = {N', A', RE, R'D}
3. Se comprueba si S' es seguro. Si lo es, S k+1 = S', en caso contrario se deniega la petición y se
bloquea el proceso hasta que se le puedan conceder los recursos.
4. Volver al paso 2.

Denegación de la iniciación de un proceso


Esta técnica consiste en no iniciar un proceso si el número máximo de recursos que va a necesitar
durante su ejecución puede conducir a un estado de interbloqueo. Esta técnica no es óptima, ya que
supone que todos los procesos van a solicitar simultaneamente todas las instancias de recursos que
van a necesitar.
En la práctica se trata de determinar que el proceso p+1 puede iniciar su ejecución si el número
máximo de instancias j que necesita sumadas al número máximo de instancias de esos recursos
necesitadas por los procesos existentes no superan el número de instancias existentes.

Apuntes por Demetrio Quirós – Fundamentos básicos de los Sistemas Operativos 35


Detección y recuperación de interbloqueos
Esta estrategia consiste en no limitar las asignaciones de recursos a los procesos y comprobar
periodicamente si se ha producido algún interbloqueo. En caso afirmativo, se emplea alguna técnica
para recuperar el sistema del interbloqueo.

Algoritmos de detección de interbloqueos


El algoritmo de Coffman emplea RE, vector de recursos existentes; RD, vector de recursos
disponibles; A, matriz de recursos asignados a cada proceso; y M, matriz de recursos adicionales
necesitados por cada proceso.
Inicialmente todos los procesos están sin marcar y se van marcando aquellos que pueden ser
completados. Los procesos marcados no pueden provocar interbloqueo. Si al finalizar el algoritmo
queda más de un proceso sin marcar existe interbloqueo.
1. Se marca cada proceso que tenga su fila en A a cero, dado que ese proceso no tiene ningún
recurso asignado y, por tanto, no puede producir interbloqueo.
2. Se realiza la asignación X = RD, donde X es un vector auxiliar.
3. Para cada proceso i no marcado se comprueba M i≤ X
4. Si no existe ningún i que cumpla la condición, el algoritmo finaliza. Si existe un proceso i
que cumpla la condición se marca el proceso y se ejecuta hasta que finalice y libere los
recursos, se realiza X = X + Ai (que incrementa los recursos disponibles con los liberados
por el proceso i) y se vuelve al paso 3.

Frecuencia de invocación del algoritmo de detección de interbloqueos


Invocarlo cada vez que se solicite un recurso aumenta la sobrecarga del sistema. Una solución
óptima puede ser invocarlo cada T unidades de tiempo o cuando el nivel de utilización del
procesador caiga por debajo de un límite, lo que podría denotar inactividad por existencia de
interbloqueo.

Técnicas de recuperación del interbloqueo


• Recuperación mediante expropiación de recursos. Mediante algún criterio de selección se
van expropiando recursos a algunos procesos y concediéndoselos a otros para conseguir salir
del interbloqueo.
• Recuperación mediante el retroceso de los procesos interbloqueados a algún punto de
control previo. En cada punto de control se guarda el contexto de cada proceso. En caso de
interbloqueo se restaura el contexto anterior.
• Recuperación mediante aborto selectivo de procesos, estableciendo un criterio para ir
abortando procesos (bloqueados o no).
• Recuperación mediante el aborto de todos los procesos bloqueados. La solución más
drástica pero la más utilizada.

Ventajas e inconvenientes
La detección y recuperación de interbloqueos permite una mayor concurrencia de procesos ya que
no limita el número de asignaciones. Sin embargo, la detección introduce sobrecarga aunque puede
limitarse con algoritmos eficaces. La recuperación sí produce elevada sobrecarga y
desaprovechamiento de recursos. Es eficaz en sistemas con baja probabilidad de interbloqueos.

36 Capítulo 5. Interbloqueo
Otras estrategias de tratamiento de interbloqueos
• Estrategias mixtas, agrupando los recursos en diferentes clases, ordenando las clases para
evitar la espera circular y utilizando para cada clase la estrategia más oportuna.
• Ignorar los interbloqueos. Sistemas como UNIX o Windows no utilizan ninguna estrategia
de tratamiento de interbloqueos.

Apuntes por Demetrio Quirós – Fundamentos básicos de los Sistemas Operativos 37


Capítulo 6. Administración de memoria
Para que un programa pueda ser ejecutado por el procesador primero debe ser cargado en la
memoria principal. El subsistema de administración de la memoria principal es el encargado de
administrar, junto con el hardware, la memoria principal entre todos los procesos que se ejecutan en
el computador.
• Técnicas de asignación contigua. Todo el espacio de direcciones lógicas de un proceso se
carga de forma contigua en memoria principal.
◦ Particionamiento fijo.
◦ Particionamiento dinámico.
• Técnicas de asignación no contigua. El espacio de direcciones lógicas de un proceso se
divide en bloques de igual o distinto tamaño. Los bloques de un mismo proceso no tienen
por qué estar cargados de forma contigua en memoria principal.
◦ Paginación simple: bloques del mismo tamaño.
◦ Segmentación simple: bloques de distinto tamaño.

Espacio de núcleo y espacio de usuario


Al espacio ocupado por el código, las estructuras de datos y la pila o pilas del núcleo del sistema
operativo se le llama espacio del núcleo. El acceso al espacio del núcleo sólo puede realizarse en
modo núcleo.
Al espacio ocupado por la imagen de un proceso, es decir, a su espacio de direcciones de memoria
lógica se denomina espacio de usuario. El acceso al espacio de usuario puede realizarse en modo
núcleo o modo usuario.
En definitiva, en la memoria principal de un sistema multiprogramado pueden distinguirse el
espacio del núcleo, uno o varios espacios de usuario y espacio libre.

Área de intercambio en memoria secundaria


Un programa es un archivo ejecutable que reside en memoria secundaria dentro de algún directorio
del sistema de archivos.
El sistema operativo reserva espacio en memoria secundaria para almacenar las imágenes de los
procesos. A dicho espacio se le denomina área de intercambio.
Se denomina intercambio (swapping) a la operación de cargar la imagen de un proceso desde el área
de intercambio a memoria principal y viceversa. Se habla de intercambio fuera de memoria
principal (swapping out), al paso de la imagen desde el área de memoria principal al área de
intercambio y de intercambio dentro de memoria principal (swapping in) al caso contrario.
La operación de swapping out se suele realizar
• Cuando se requiere espacio en memoria principal para cargar otros procesos.
• Cuando otro proceso requiere de más espacio debido al crecimiento de su región de datos o
de pila.
• Cuando es necesario regular el grado de multiprogramación del sistema.
La operación de swapping in suele realizarse
• Cuando se desea aumentar el grado de multiprogramación.

Apuntes por Demetrio Quirós – Fundamentos básicos de los Sistemas Operativos 39


• Existe espacio en memoria principal para cargar más procesos.
• Existe un proceso de mayor prioridad en el área de intercambio.
Si el sistema no soporta memoria virtual la imagen del proceso se intercambia al completo.
La operación de intercambio es realizada por un proceso del sistema denominado intercambiador,
encargado de
• Gestionar y asignar el espacio de intercambio.
• Seleccionar procesos para ser intercambiados fuera de memoria principal. Se esogen
primero aquellos procesos bloqueados con menor prioridad y mayor tiempo de residencia en
memoria. A continuación se escogen los preparados con los mismos criterios anteriores.
• Seleccionar procesos para ser intercambiados dentro de memoria principal. Se escogen
aquellos procesos preparados para ejecución que lleven mayor tiempo de espera o con
mayor prioridad.
Puede considerarse que el intercambiador realiza las funciones del planificador a medio plazo.
No se trabaja directamente con el archivo ejecutable asociado al proceso y se trabaja con una
imagen en el área de intercambio debido a que
• Una operación de lectura escritura es más rápida en el área de intercambio que en el sistema
de ficheros.
• La imagen de un proceso es una entidad dinámica cuyo contenido suele diferir del archivo
ejecutable conforme va ejecutándose el proceso.

Asignación de memoria en sistemas monoprogramados


En sistemas monoprogramados la memoria principal se divide en dos particiones. Una está
reservada para contener permanentemente aquellas partes del sistema operativo que deben estar
siempre en memoria principal. A este conjunto del sistema operativo residente en memoria se
denomina monitor del sistema operativo.
La memoria no ocupada conforma otra partición en la que se carga de forma temporal un proceso
de usuario o alguna parte no residente del sistema operativo.
En función de en qué parte de la memoria, direcciones bajas o direcciones altas, se encuentra el
monitor del sistema operativo podemos encontrarnos con tres posibles configuraciones de memoria:
• Configuración 1. La memoria principal se implementa con una memoria RAM. El sistema
operativo ocupa desde la dirección física 0 hasta DirF1. La parte superior, desde DirF+1 hasta
DirMAX está disponible. Esta configuración no es usada actualmente, pero sí en los primeros
micro y macrocomputadores.
• Configuración 2. La memoria principal se implementa mediante una RAM y una ROM. El
SO ocupa la ROM en la parte superior de la memoria principal, desde Dir F1+1 hasta DirMAX.
Sistema poco flexible, pero utilizado en sistemas integrados y computadores de mano.
• Configuración 3. La memoria principal se implementa con una RAM y una ROM. La
partición del sistema operativo ocupa la parte inferior de la RAM, en la que se almacena el
cargador de programas y el intérprete de comandos. El resto de la RAM forma la partición
de usuario y en la ROM se almacenan los vectores de interrupción del hardware y las rutinas
de servicio de interrupción. Esta memoria es conocida como BIOS, Basic Input Output
System. Configuración utilizada en los primeros microcomputadores. MsDOS.

40 Capítulo 6. Administración de memoria


Para garantizar la protección del sistema operativo y evitar que los procesos de usuario hagan
referencia a direcciones físicas del espacio del sistema operativo se utilizan uno o dos registros para
almacenar la dirección base de inicio de la partición y/o el tamaño de la partición.

Particionamiento fijo
La forma más sencilla de gestionar la memoria en sistemas multiprogramados consiste en dividir la
memoria principal en un número fijo de N particiones que pueden ser de igual o diferente tamaño.
Esta división puede realizarse manualmente al arrancar el sistema o de manera automática.
Esta técnica se conoce como particionamiento fijo.
Se reserva una partición para contener el sistema operativo en un extremo de la memoria,
normalmente en la parte baja. Las restantes N-1 particiones estarán disponibles para cargar
procesos.
El número de particiones define el grado de multiprogramación del sistema.
El sistema operativo mantiene una tabla de descripción de particiones que contiene la dirección
física de comienzo (dirección base), el tamaño y el estado (libre o no) de cada partición.

Particiones de igual tamaño


La asignación de memoria con particionamiento fijo y particiones de igual tamaño es bastante
simple, ya que no importa qué partición libre se asigne a un proceso, pero:
• Limita el tamaño máximo de los procesos que se pueden cargar en memoria principal. Si un
proceso tiene un espacio de direcciones lógicas mayor que el disponible en la partición no
podrá cargarse. Esta limitación puede soslayarse si el proceso ha sido programado con la
técnica de overlay o superposición, mediante la cual sólo una parte del proceso precisa que
se encuentre en memoria.
• Fragmentación interna. Si el tamaño del espacio de direcciones lógicas es inferior al de la
partición asignada existe un espacio libre no asignable a otros procesos.

Particiones de distinto tamaño


Para asignar las particiones a los procesos, el sistema operativo puede mantener una cola de
procesos por partición. Un proceso ingresa a la cola asociada a la partición de menor tamaño que
pueda contenerlo. La planificación de cada cola se realiza de forma independiente.
Este sistema puede provocar que las particiones de mayor tamaño nunca se ocupen. Para resolverlo
puede emplearse una única cola para todas las particiones. En el momento en que una partición
queda libre, se localiza un proceso que pueda ser cargado según alguno de estos criterios:
• Criterio del primer ajuste. Consistente en buscar el proceso más cercano a la cabecera de la
cola con tamaño menor o igual a la partición. Búsquedas rápidas pero no minimiza la
fragmentación interna.
• Criterio del mejor ajuste. Busca en toda la cola el proceso de mayor tamaño que entre en la
partición. Minimiza la fragmentación interna pero enlentece la búsqueda y discrimina a los
procesos más pequeños. Podría solucionarse imponiendo un número máximo de veces que
puede ser discriminado un proceso.
La existencia de fragmentación interna y la limitación del tamaño máximo del proceso que puede
ser cargado en memoria es menor en el caso de utilizar particiones de distinto tamaño.
Configurando una partición lo suficientemente grande también es posible cargar procesos de mayor
tamaño.

Apuntes por Demetrio Quirós – Fundamentos básicos de los Sistemas Operativos 41


Traducción de direcciones y protección
La traducción de direcciones lógicas a direcciones físicas en la técnica de particionamiento fijo
requiere el uso de dos registros: el registro base y el registro límite.
Cuando un proceso es planificado, el sistema operativo carga en el registro base la dirección física
de comienzo de la partición donde se aloja y en el registro límite la dirección lógica más alta del
espacio de direcciones lógicas del proceso.
Cuando se referencia una dirección se compara con el registro límite y si es igual o inferior a este se
suma al registro base. Este mecanismo impide que se accedan a direcciones inferiores o superiores a
las asignadas a su espacio lógico.
Gracias a este mecanismo de traducción de direcciones es posible cargar el proceso en cualquier
partición de la memoria principal. Se dice entonces que el sistema soporta la reubicación dinámica
en tiempo de ejecución.

Ventajas e inconvenientes
La principal ventaja es su facilidad de implementación, únicamente requiere de una tabla de
descripción de particiones y una o varias colas, lo que produce poca sobrecarga.
Los principales inconvenientes son que provoca fragmentación interna, el tamaño máximo de un
proceso y la limitación del grado de multiprogramación en función del número de particiones.

Particionamiento dinámico
En el particionamiento dinámico el número de particiones no es fijo, sino que va variando con el
tiempo. La memoria principal se divide en particiones, una zona contigua de memoria ocupada, y
huecos, una zona contigua de memoria libre. Esta técnica ha dejado de utilizarse, pero fue usada en
macrocomputadoras como el OS/MVT de IBM.
Cuando un proceso debe ser cargado en memoria el sistema localiza un hueco del mismo tamaño o
mayor que el proceso. Ese espacio define una partición y el espacio sobrante define un nuevo
hueco.
Conforme se van cargando procesos se van generando nuevos huecos cada vez más pequeños, en lo
que se conoce como fragmentación externa. Una técnica para solucionar la fragmentación externa
es la compactación de memoria, que consiste en agrupar todos los huecos y mover las particiones.
El inconveniente es que se produce alta sobrecarga.
Es común que se utilice una unidad mínima de asignación o bloque de memoria mínimo. Esto evita
el tener huecos de pequeño tamaño que no pueden ser utilizados. Como contrapartida, se produce
fragmentación interna, aunque despreciable en comparación con la técnica de particionamiento fijo.
El sistema mantiene una o varias estructuras de datos que contengan información sobre los huecos y
las particiones. Estas estructuras pueden ser mapas de bits o listas enlazadas simples o dobles.
Manteniendo una lista para huecos y otra para particiones asignadas es posible acelerar el proceso
de búsqueda de hueco disponible.

Asignación de espacio de memoria principal


Algunos de los algoritmos de búsqueda más utilizados para realizar la asignación de espacio a un
proceso con un espacio de direcciones lógicas de tamaño S son:
• Algoritmo del primer ajuste (first fit): Se asigna el primer hueco con un tamaño igual o
mayor que S. Rápido, pero produce pequeños huecos al comienzo de la estructura de datos.

42 Capítulo 6. Administración de memoria


• Algoritmo del siguiente ajuste (next fit): La búsqueda de un hueco de tamaño igual o mayor
que S comienza donde se quedó la última búsqueda. Aunque se pensó para evitar los
problemas del anterior, a la larga produce peores resultados.
• Algoritmo del mejor ajuste (best fit): Se busca en toda la estructura de datos un hueco que
sea igual o con el mínimo exceso posible del valor de S. Más lento, produce pequeños
huecos no utilizables que obliga a compactar.
• Algoritmo del peor ajuste (worst fit): Se busca el hueco más grande posible para intentar que
los huecos que se generen sean aprovechables con posterioridad. Distintas simulaciones han
demostrado que no es muy efectivo.
En resumen, el más rápido es el de primer ajuste y el de menor aprovechamiento de la memoria es
el de peor ajuste.

Traducción de direcciones y protección


Al igual que en la técnica de particionamiento fijo, se utilizan dos registros dedicados denominados
registro base y registro límite.
Cuando se va a ejecutar un proceso el sistema operativo carga en el registro base la dirección física
de inicio de la partición de memoria asociada al proceso y en el registro límite el tamaño de la
partición.
Cuando se haga referencia a una dirección lógica dentro del proceso se compara con el valor del
registro límite. Si se excede, se lanza una excepción.

Ventajas e inconvenientes
• Minimiza la fragmentación interna, que es como máximo cercana a una unidad de
asignación
• Permite ejecutar procesos de mayor tamaño.
• Permite asignar fácilmente más espacio a procesos cuya región de datos o pila aumenta por
encima del tamaño inicialmente asignado, reubicando el proceso o asignando un hueco
contíguo.
Los inconvenientes son
• Estructuras de datos más complejas, que aumentan la sobrecarga del sistema.
• Produce fragmentación externa, lo que reduce el aprovechamiento de la memoria.

Paginación simple
La técnica de paginación consiste en dividir la memoria principal en bloques del mismo tamaño, S P,
denominados marcos de página o páginas físicas. El espacio de direcciones de un proceso también
se divide en bloques del mismo tamaño SP, denominados páginas o páginas lógicas.
Una página de un proceso se carga en un marco de página libre de memoria principal.
Si CMP es la capacidad de la memoria principal, el número N MP de marcos de página de tamaño SP en
que se divide es

N MP = floor
( )
C MP
SP
Cada marco de página se identifica de forma unívoca mediante un número de marco de página j. De
esta manera, se hará referencia al marco de página j o marco j de la memoria principal.

Apuntes por Demetrio Quirós – Fundamentos básicos de los Sistemas Operativos 43


De otra parte, si CX es el tamaño del espacio de direcciones lógicas de un proceso, el número de
páginas NP de tamaño SP en que se descompone es:
CX
N P=ceil ( )
SP
Cada página de un proceso se identifica por un entero positivo i denominado número de página.
De los marcos en que se descompone la memoria principal, N MP, un número determinado de ellos, V,
están reservados para el núcleo.
Una dirección física consta de dos campos: número de marco de página de f bits y el
desplazamiento dentro del marco, de d bits.
El tamaño del campo de número de marco de página se obtiene a partir del número de marcos de
página existentes y el tamaño del campo desplazamiento a partir del tamaño de una página o de un
marco de página expresado en unidades direccionables.
Una dirección lógica consta de los campos de número de página, de p bits, y el desplazamiento
dentro de la página, de d bits.
El cálculo del tamaño de cada uno de estos campos es
min f {N MP ≤2 f } min d {S P ≤2 d } min p {N P ≤2 p }
El tamaño de una dirección física es n= f + d , y el de una dirección lógica m= p+ d . La longitud
de una dirección lógica es menor o igual que la longitud de la dirección física.
Para implementar la paginación generalmente se usan las siguientes estructuras:
• Tablas de páginas. A cada proceso se le asigna una. Cada entrada i de la tabla contiene el
marco j donde se encuentra almacenada la página i del proceso y los permisos de acceso.
• Tabla de marcos de página. Con tantas entradas como marcos de página tiene la memoria
principal. Cada entrada j contiene su estado libre u ocupado, punteros para crear una lista de
marcos libres y la ubicación en memoria secundaria de la copia de la página i contenida en
el marco.
• Lista de marcos libres. Consultada cuando hay que asignar espacio a los procesos. Cuando
hay que asignar un marco se selecciona el primero de la lista. Los nuevos marcos libres se
añaden por el final.
Para que un proceso pueda ser ejecutado, todas sus páginas deben estar cargadas en memoria,
aunque no necesariamente en marcos contiguos. Cuando un proceso de NP páginas de tamaño tiene
que ser cargado, el sistema comprueba que existan NP marcos libres. Si los hay, se eliminan de la
lsita de marcos libres, se marcan como ocupados en la tabla de marcos de página y se carga en ellos
las páginas del proceso. A continuación se crea o actualiza la tabla de páginas del proceso indicando
el número de marco donde está cargada cada página. Además, si la tabla de páginas no estaba
creada ya, se almacena en el PCB del proceso un puntero a la dirección física de comienzo de la
tabla de páginas.

Traducción de direcciones
El hardware debe disponer de ciertos componentes donde cargar la información necesaria para
realizar la traducción de instrucciones. Pueden ser:
• Registro base, donde se almacena la dirección física de comienzo de la tabla de páginas.
• Banco de registros, para almacenar una copia completa de la tabla de páginas.

44 Capítulo 6. Administración de memoria


• Buffer de traducción de vista lateral (Translation Lookaside Buffer, TLB), una caché de alta
velocidad donde guardar algunas entradas de la tabla de páginas.
En función de la utilización de uno u otro componente se emplea uno u otro método.
Traducción de direcciones con registro base
El sistema carga en el registro base la dirección física DirF0 de comienzo de la tabla de páginas.
Cuando se referencia a una dirección lógica DirL se suma el campo número de página i a DirF0 para
obtener la dirección física DirF1 de la entrada i de la tabla de páginas.
A continuación se accede a DirF1 en memoria para obtener el marco de página j donde se encuentra
la página i. Añadiendo el desplazamiento, se obtiene la dirección requerida.
Este mecanismo solo precisa que se cargue el registro base con cada cambio de proceso, lo que
acelera estos cambios.
En contra, la traducción requiere de un acceso a memoria para localizar en la tabla de páginas el
marco j donde se encuentra la página i, lo que produce un retraso en la ejecución de la instrucción y
hace que este mecanismo se utilice en raras ocasiones.
Traducción de direcciones con banco de registros
Cuando se produce un cambio de contexto, el sistema operativo carga en el banco de registros una
copia de la tabla de páginas del proceso que se va a ejecutar.
De esta forma, en vez de localizar el número de marco donde se aloja la página en la tabla de
páginas en memoria se accede a su copia en el banco de registros.
Esta solución no precisa de ningún acceso a memoria, por lo que es más rápida, sin embargo sólo
puede utilizarse si el tamaño de la tabla de páginas no excede del tamaño del banco de registros.
El cambio de proceso se ve ralentizado al tener que cargar toda la tabla de páginas en el banco de
registros desde la memoria.
Traducción de direcciones con un TLB
Un TLB es una memoria caché especial de alta velocidad con una capacidad de entre 8 y 4096
entradas.
Cuando el procesador hace referencia a una dirección lógica DirL, primero se examina en paralelo
todas las entradas del TLB y se verifica si alguna coincide con el número de página i a que hace
referencia. Si se produce un acierto, se recupera el número de marco j de esa entrada para componer
la dirección física DirF junto con el campo desplazamiento d.
Si se produce un fallo, se acude a su búsqueda en la tabla de páginas en memoria como se realiza
con el método de registro base y esa entrada se copia al TLB en una posición libre o, si está lleno,
mediante algún algoritmo de reemplazo.
Cuando se produce un cambio de proceso se carga en el registro base la dirección de la tabla de
páginas y se limpia el TLB, que se irá cargando a medida que se vayan produciendo fallos en la
búsqueda de entradas.
El uso del TLB está a medio camino entre la solución de registro base y la de banco de registros.

Tablas de páginas paginadas


Para evitar las tablas de páginas de gran tamaño estas se pueden descomponer, a su vez, en páginas,
obteniendo una tabla de páginas paginada. De esta forma la tabla de páginas se fragmenta y puede
ubicarse en memoria principal de forma no contigua. Se tienen así dos tipos de páginas:
• Páginas ordinarias, que contienen instrucciones y datos del espacio lógico de un proceso.

Apuntes por Demetrio Quirós – Fundamentos básicos de los Sistemas Operativos 45


• Páginas de tablas de páginas, que contienen entradas de tablas de páginas.
Para localizar en memoria principal a las páginas de una tabla de páginas se utiliza otra tabla de
páginas denominada tabla de páginas de primer nivel o tabla de páginas primaria. A las entradas
de la tabla de páginas original contenidas en una página se les denomina tablas de páginas de
segundo nivel o tabla de páginas secundaria.
Para cada proceso existe una tabla primaria y varias de segundo nivel, tantas como páginas ocupe la
tabla de páginas original del proceso.
Existen dos niveles de paginación: el primero permite localizar el marco de página donde se ubican
las páginas de la tabla de página original, el segundo permite localizar el marco donde se ubica la
página ordinaria i a que hace referencia a que hace referencia la dirección lógica.
El campo número de página de una dirección lógica se descompone en dos campos:
• Índice de tabla primaria, ITP, que contiene el número de la tabla de páginas de primer nivel
donde buscar el marco de memoria que contiene a la página que ubica la tabla de páginas de
segundo nivel. Si la tabla de páginas de primer nivel tiene N TP1 entradas, el tamaño r de ese
campo será min r {N TP1 ≤2r }
• Índice de tabla secundaria, ITS, que contiene el número de la entrada de la tabla de páginas
de segundo nivel donde bucar el marco de página que contiene a la página ordinaria
referenciada. Si la tabla secundaria tiene NTP2 entradas, el tamaño s del campo será
min s {N TP2 ≤2 s }
El número de entradas de la tabla de páginas de primer nivel es igual al número de páginas
que se necesitan para contener la tabla de páginas original.
El número de entradas de la tabla de segundo nivel es igual al número de entradas de la tabla
de páginas original contenidas en una página.
La traducción de una dirección lógica a un dirección física se realiza
1. Se suma ITP al contenido del registro base DirF0 para construir la dirección física DirF1 de la
entrada de la tabla de páginas de primer nivel donde buscar el marco de memoria k que
contiene a la página donde se ubica la tabla de segundo nivel.
2. Se accede a DirF1 para leer el número de marco k y se le suma al ITS para construir la
dirección física DirF2 de la entrada de la tabla de páginas de segundo nivel donde localizar el
marco de memoria j que contiene la página i referenciada en la dirección lógica DirL
3. Se accede a memoria principal para leer el número de marco j y construir la dirección física
DirF3 equivalente a la dirección lógica DirL.
Se requiere de esta forma de dos accesos a memoria para realizar la traducción.
Si la tabla de páginas de primer nivel aún resulta grande, puede descomponerse en otras páginas,
alcanzando paginaciones de 3º nivel (SPARC) o 4º nivel (Motorola 68030).

Tablas de páginas invertidas


Otra posible solución a las tablas de páginas de gran tamaño. Se utiliza una única tabla de páginas
invertida en vez de una tabla de páginas por proceso.
En la tabla invertida, se asocia una entrada por cada marco j de la memoria principal en vez de por
cada página i de un proceso. El número de entradas es fijo e igual al número de marcos.
Cada entrada j contiene el número de página i que se aloja en el marco j, identificador del proceso al
que pertenece la página (Pid), y bits de control.

46 Capítulo 6. Administración de memoria


Para traducir una dirección lógica se compara el campo número de página de la dirección y el Pid
con los campos homónimos de cada entrada de la tabla. Si se produce una coincidencia en la
entrada j, ese marco j es quien contiene la página i referenciada que se requiere para construir la
dirección física.
La búsqueda de una entrada en la tabla invertida puede ralentizar el tiempo de traducción. Puede
acelerarse utilizando una tabla hash y TLB.

Protección
En la gestión de memoria mediante paginación, la protección se implementa a nivel de página. Cada
entrada i de la tabla de páginas de un proceso contiene un campo de uno o varios bits que permiten
determinar el tipo de acceso permitido sobre dicha página: w, rw, x, etc. En caso de intento de
violación se lanza una excepción.
También se incorpora un registro límite donde se carga el número de páginas de que consta el
proceso.

Compartición de páginas
El espacio lógico de un proceso puede dividirse en las regiones de código, datos y pila. En
paginación simple, todas las páginas deben estar cargadas en memoria.
En sistemas de tiempo compartido, multiples usuarios pueden estar ejecutando el mismo programa
de manera simultanea. Si el programa posee código reentrante, no modificable, se puede ahorrar
espacio en memoria cargando sólo una imagen de ese proceso y compartiéndola entre todos los
usuarios.
Se utiliza un contador de referencias que lleva la cuenta del número de instancias activas. Se
elimina de memoria cuando el contador se hace cero.

Ventajas e inconvenientes
La paginación simple presenta varias ventajas
• No produce fragmentación externa.
• Produce una sobrecarga pequeña, la gestión de las estructuras de datos no requiere de mucho
tiempo de procesador.
• No precisa de intervención humana para la definición de las particiones.
• Permite compartición de código común entre varios procesos.
La principal desventaja es que produce fragmentación interna, de término medio, media página por
proceso.
La paginación es invisible al programador, lo que puede ser considerado tanto como una ventaja
como un inconveniente.

Segmentación simple
La segmentación simple es una técnica de gestión de la memoria que soporta los elementos en los
que se descompone el código de un programa. Básicamente, el compilador divide el programa en
segmentos. Cada segmento es una entidad lógica conocida por el programador y asociada a una
determinada estructura de datos o módulo.
Cada segmento, código principal, subrutinas, datos, pila... tiene su propio espacio de direcciones
lógicas. Cuando el sistema operativo crea un proceso asociado a un determinado programa, asigna
a cada segmento un identificador numérico positivo h, el número del segmento.

Apuntes por Demetrio Quirós – Fundamentos básicos de los Sistemas Operativos 47


Una dirección lógica consta de dos campos: el número de segmento, de s bits, y el desplazamiento
dentro del segmento, de d bits. En un proceso se pueden tener direcciones lógicas de diferente
tamaño, si bien el campo número de segmento tendrá siempre la misma longitud, el campo
desplazamiento depende del número de unidades direccionables que existan en ese segmento en
concreto.
En segmentación simple, un proceso no puede ser ejecutado si todos sus segmentos no se
encuentran cargados en memoria principal. El sistema operativo debe buscar un hueco para cada
segmento. Si algún segmento no pudiera ser cargado no aborta la carga del proceso.
Además, en la carga el sistema crea una tabla de segmentos asociados al proceso idexada por
número de segmento que contiene la dirección física base de cada segmento y su longitud, además
de otros datos como permisos, ubicación en memoria secundaria, etc.

Traducción de direcciones
Si se dispone de un registro base, en cada cambio de contexto el sistema carga en ese registro la
dirección física de comienzo de la tabla de segmentos, Dir F0, obtenida del bloque de control del
proceso.
Para llegar a una dirección física DirF a partir de una dirección lógica DirL se siguen estos pasos:
• Se suman el campo número de segmento h de la dirección lógica y Dir F0 para obtener la
dirección DirF1 de la entrada h de la tabla de segmentos.
• Se accede a DirF1 y se lee la dirección física base y la longitud del segmento h.
• Se compara el campo desplazamiento con la longitud del segmento, lanzando una excepción
si se supera el tamaño.
• Si el desplazamiento es menor que la longitud se suma la dirección física base del segmento
h al desplazamiento indicado en DirL para obtener la dirección física DirF equivalente.
El principal inconveniente es que se requiere de un acceso a memoria para leer la tabla de
segmentos, lo que provoca un retardo en la ejecución de la instrucción en curso.
Para acelerar la ejecución puede utilizarse un banco de registros o un TLB.

Protección
La protección del espacio de direcciones se implementa a nivel de segmento. En cada entrada h de
la tabla de segmentos de un proceso se almacenan los permisos de acceso sobre dicho segmento.
Adicionalmente suele haber un registro límite donde se almacena en cada cambio de contexto el
número de segmentos de que consta el proceso que va a ser ejecutado.

Compartición de segmentos
Esta técnica permite que un segmento de código o datos sea compartido por más de un proceso.
Para ello el sistema operativo mantiene una tabla con los segmentos cargados en memoria principal
en la que se contabilizan las referencias que otros procesos realizan a estos segmentos. Cuando el
contador de referencias se haga cero, el segmento puede ser eliminador de memoria principal.

Ventajas e inconvenientes
Como ventajas:
• Produce una fragmentación interna despreciable, de como máximo cercana a una unidad de
asignación.
• Soporta la visión modular que el programador posse del programa.

48 Capítulo 6. Administración de memoria


• Permite manejar con facilidad estructuras de datos que crecen. Si un segmento precisa de
más espacio, tan solo hay que asignarle un hueco contiguo o reasignarlo a un hueco de
mayor tamaño.
• Facilita la protección y compartición de las distintas partes de un programa al asignarse un
segmento independiente a cada una de ellas.
Entre los inconvenientes, destacan:
• Produce fragmentación externa, lo que reduce el aprovechamiento de la memoria y requiere
el uso de compactación, aunque menor que el producido con la técnica del particionamiento
dinámico.
• Aumenta la sobrecarga del sistema debido a que las estructuras de datos y algoritmos son
más complejos que en particionamiento dinámico.

Segmentación con paginación simple


La segmentación y la paginación pueden combinarse para aprovechar las ventajas de ambos
métodos.
Mediante esta técnica se divide cada segmento de un proceso en un determinado número de
páginas. Una dirección lógica se descompone en tres campos: número de segmento, de s bits,
número de página, de p bits y desplazamiento, de d bits.
Con la carga de un proceso en memoria principal, el sistema operativo crea una tabla de segmentos
del proceso y varias tablas de páginas, una por segmento. La entrada de la tabla de segmentos no
contiene la dirección física del segemento, sino la de la tabla de páginas asociada al segmento.
Ahora, el campo longitud del segmento viene expresado en número de páginas.
Si se dispone de un registro base, el proceso de traducción de direcciones comienza cargando en el
registro base la dirección física DirF0 de comienzo de la tabla de segmentos asociada al proceso.
Cuando se hace referencia a una dirección lógica DirL se traduce a una dirección física
1. Se suma el campo de número de segmento h de la dirección lógica y DirF0 para obtener la
dirección de comienzo de la entrada h de la tabla de segmentos, DirF1.
2. Se accede a DirF1 para obtener la dirección base de la tabla de páginas y la longitud del
segmento.
3. Se compara el valor desplazamiento de DirL con la longitud del segmento h. Si el
desplazamiento es mayor, se genera una excepción.
4. Se el desplazamiento es menor, se suma el campo número de página de DirL y la dirección
física base de la tabla de páginas del segmento para obtener la dirección física DirF2 de la
entrada i de la tabla de páginas.
5. Se accede a DirF2 para leer el número de marco j que contiene la página referenciada.
6. Se construye la dirección física DirF con el número de marco leído y el campo
desplazamiento de DirL.
El mecanismo precisa de dos accesos a memoria principal, pudiendo acelerarse utilizando un banco
de registros o un TLB.

Apuntes por Demetrio Quirós – Fundamentos básicos de los Sistemas Operativos 49


Capítulo 7. Memoria virtual
La técnica de gestión de memoria conocida como memoria virtual consiste en tener cargadas en
memoria principal solo aquellas partes (páginas o segmentos) del espacio de direcciones lógicas,
ahora también llamadas direcciones virtuales, de un proceso que se van necesitando durante su
ejecución.
La memoria virtual permite ampliar el grado de multiprogramación, dado que en memoria principal
caben más procesos si sólo se cargan algunas partes de cada proceso.
La implementación de la memoria virtual requiere que el hardware soporte el reinicio de las
instrucciones de su repertorio. Además, suele utilizarse un componente denominado unidad de
gestión de memoria (Memory Management Unit, MMU), encargada de realizar la traducción de la
dirección virtual a la dirección física.
La memoria virtual puede implementarse usando paginación por demanda (UNIX, Linux,
Windows), segmentación por demanda (OS/2) o segmentación con paginación por demanda
(Multics)

Paginación por demanda


La técnica de paginación por demanda divide el espacio de memoria principal en bloques de igual
tamaño, marcos de página, y el espacio de direcciones del proceso en bloques de igual tamaño,
páginas.
Para que un proceso se pueda ejecutar no es necesario que todas sus páginas se encuentren cargadas
en memoria principal. Cuando se referencia una página no cargada se produce un fallo de página.
Otras tareas a realizar por el Sistema Operativo son:
• Reemplazamiento de páginas, en caso de que se produzca un fallo de página y no haya
ningún marco libre, es necesario decidir qué marco hay que intercambiar a memoria
secundaria.
• Asignación de marcos de memoria principal. El sistema debe decidir cuántos marcos asignar
inicialmente a cada proceso.
• Control de carga, decidir el grado de multiprogramación del sistema.
• Copia en memoria secundaria de páginas modificadas, en qué momento y de qué forma.
Se mantienen las siguentes estructuras de datos: tabla de marcos de página, listas de marcos libres
y tablas de páginas.
Cuando un proceso entra en estado preparado para ejecución se crea una tabla de páginas en
memoria principal en la que cada entrada contiene, al menos, los siguientes campos:
• Número de marco de página.
• Validez o presencia, que indica si la página es válida o no.
• Protección, de uno a tres bits que indican los permisos de R, W y X.
• Referenciada, un bit activo cuando la página es referenciada por una dirección virtual.
• Modificada, un bit que indica si la página ha sido modificada y debe ser actualizada en
memoria secundaria.

Apuntes por Demetrio Quirós – Fundamentos básicos de los Sistemas Operativos 51


Reinicio de instrucciones
Un fallo de página puede producirse tanto en la fase de búsqueda, al intentar traducir la siguiente
instrucción a ejecutar, como de ejecución, en la búsqueda de operandos.
La arquitectura del computador debe poder reiniciar la instrucción desde su inicio, fase de
búsqueda. Para ello, se suele disponer de un registro donde se almacena el valor del registro
contador de programa CP antes de iniciar la fase de búsqueda.
En caso de que el procesador soporte direccionamiento indexado también deberá guardarse el valor
del registro índice por si fuera necesario restaurarlo tras un fallo de página.

Localización de las páginas en memoria secundaria


Cuando la referencia a una página produce un fallo de página el sistema operativo debe leer esa
página desde la memoria secundaria y copiarla a la memoria principal. De igual modo, si no hay
marcos libres en la memoria principal el sistema operativo debe seleccionar una página para ser
reemplazada y, si esta ha sido modificada o no existe en el área de intercambio, debe ser copiada
allí.
El sistema operativo puede buscar en dos posibles localizaciones de memoria secundaria:
• Bloque de disco de un archivo ejecutable. Parte de las páginas en que se divide el espacio de
direcciones, código y datos, son creadas por el sistema operativo a partir del archivo
ejecutable del que es instancia el proceso.
• Bloque de disco del área de intercambio, utilizada para el almacenamiento de las páginas de
un proceso cuando se intercambia fuera y para el almacenamiento de las páginas que han
sido seleccionadas para ser reemplazadas tras un fallo de página.
Cada bloque del área de intercambio se identifica por un número de bloque o dirección de disco. El
sistema mantiene ciertas estructuras de datos para localizar los bloques donde se encuentran
almacenadas las páginas.
Algunos sistemas copian por adelantado al área de intercambio todas las páginas de un proceso
cuando es creado con el fin de acelerar el tratamiento de los fallos de página. Pero si el espacio de
direcciones del proceso crece es necesario aumentar el tamaño en disco por lo que hay que mover
todo el espacio del proceso. Para evitar esto, se copia el proceso por partes, datos, código, etc. de
manera que si sólo es preciso crecer la parte de datos el trabajo es menor.
Otros sistemas no copian el espacio de direcciones completo a memoria de intercambio, sólo las
páginas que son necesarias. En ese caso, se utiliza una estructura de datos denominada tabla de
disco donde se relaciona cada página con el bloque de disco donde se encuentra alojada.

Bloqueo de marcos de página


Se dice que un marco de memoria está bloqueado o pinchado (pinning) si su contenido no puede ser
reemplazado. Este bloqueo resulta útil si el marco contiene información que conviene que no sea
borrada, por ejemplo los marcos reservados para alojar el espacio del núcleo.

Tratamiento de un fallo de página


Cuando durante el ciclo de ejecución de una instrucción se hace referencia a una determinada
posición de memoria, la dirección de memoria virtual es pasada a la MMU para traducirla a una
dirección física. Ésta comprueba que la dirección está dentro del rango de direcciones permitido.
Si lo está accede a la tabla de páginas y comprueba el bit de validez o presencia. Si está activado, la
página se encuentra en memoria principal, con lo que la MMU toma el valor del campo de marco de
página para construir la dirección física junto al desplazamiento de la dirección virtual.

52 Capítulo 7. Memoria virtual


Si el bit de validez está desactivado se produce un fallo de página y se guarda en la pila el
contenido del contador del programa y de los registros especiales y pasa el control al sistema
operativo.
El sistema operativo guarda el contexto del proceso cuya ejecución produjo la excepción y
comprueba que, en efecto, se debe a un fallo de página. A continuación intenta averiguar la
dirección que produjo el fallo, bien consultado registros internos del procesador o simulando su
ejecución.
Determinada la dirección se comprueba que ésta sea legal, si no lo es se aborta el proceso. Si la
dirección sí es legal, se consulta la lista de marcos libres y si no ha y ninguno se invoca a un
algoritmo de reemplado para seleccionar un marco donde cargar la página que produjo el fallo.
Si la página contenida en el marco elegido ha sido modificada, se planifica para ser copiada a disco
duro y mientras tanto se bloquea el proceso y el marco para evitar que pueda ser seleccionado por
otro proceso. Una vez que el marco está limpio, esto es, que la página que contenía se ha pasado a
disco, se planifica la página a ser copiada de memoria al marco, se actualizan las tablas de página y
se restaura el contador de programa y los registros para que una vez que se pase el proceso al estado
preparado para ejecución se carge su contexto y continúe la ejecución desde el punto en que se
interrumpió.

Conjunto de trabajo de un proceso


Los programas que se ejecutan en un computador cumplen el principio de localidad de referencias,
también denominado principio de proximidad, que afirma que durante un determinado intervalo de
tiempo de ejecución de un proceso éste referencia direcciones virtuales próximas entre sí, esto es,
páginas cercanas. Este conjunto de páginas forma una zona de localidad del proceso.
Así, el conjunto de trabajo de un proceso en el instante ti de tiempo virtual es el conjunto de páginas
distintas que el proceso ha referenciado en sus últimas δ referencias a memoria principal. El tiempo
virtual es el tiempo que un proceso está siendo ejecutado en el procesador.
Si se elige un valor de δ muy pequeño el conjunto de trabajo no cubrirá toda la zona de localidad
actual si se elije muy grande se cubrirá más de una zona de localidad.
En la práctica, para reducir la sobrecarga se construye el conjunto de trabajo periodicamente cada
cierto tiempo virtual Δ. Para ello se revisa el campo referenciada (bit r) de cada entrada de la tabla
de páginas del proceso. El conjunto de trabajo está formado por todas aquellas páginas que tengan
el bit r activado. Una vez construido, se pone r a cero.
Así puede definirse el conjunto de trabajo de un proceso como el conjunto de páginas distintas que
el proceso en ejecución ha referenciado en el intervalo de tiempo virtual.
Dos conclusiones interesantes son:
• Una página miembro de un conjunto de trabajo no debe ser seleccionada como página
víctima para ser reemplazada ya que provocaría un nuevo fallo de página.
• Un proceso debe tener asignados el suficiente número de marcos para poder tener cargado
en memoria su conjunto de trabajo. En otro caso estará provocando continuamente fallso de
página produciendo el fenómeno de sobrepaginación o trasiego (thrashing)

Reemplazamiento de páginas
El reemplazamiento de páginas consiste en seleccionar una página k cargada en un marco j de
memoria principal para ser reemplezada por la página i a la que hacía referencia la dirección virtual
que produjo el fallo de página. La página seleccionada para ser reemplazada se denomina página

Apuntes por Demetrio Quirós – Fundamentos básicos de los Sistemas Operativos 53


víctima. El conjunto de marcos candidatos hace referencia a los marcos de memoria principal donde
se encuentran almacenadas las páginas candidatas a ser reemplazadas.
• Estrategia de reemplazamiento de páginas local, cuando el conjunto de páginas candidatas a
ser reemplazadas pertenecen al mismo proceso que provocó el fallo.
• Estrategia de reemplazamiento de páginas global, cuando el conjunto de páginas candidatas
está formado por todas las páginas cargadas en memoria principal en marcos no bloqueados.
La estrategia de reemplazamiento local es más fácil de analizar, pero su implementación es más
complicada y produce mayor sobrecarga.
Es deseable que el algoritmo de reemplazamiento disminuya el número de fallos de página a
medida que aumenta el número de marcos de página de la memoria principal. Si esto no sucede se
dice que el algortimo pacede la anomalía de Belady. El alogirtmo FIFO sufre de esta anomalía.

Algoritmo de reemplazamiento óptimo


Selecciona para ser reemplazada la página del conjunto de páginas candidatas a ser reemplazada
que tardará más en volver a ser referenciada. Esto obliga a conocer con antelación qué direcciones
virtuales van a ser referenciadas, pero esto no es posible y de ahí que este algoritmo no pueda ser
implementador en la práctica pero sí sirve como referencia para comparar con otros algoritmos.

Algortimo de reemplazamiento LRU


El algoritmo de reemplazamiento de la página usada menos recientemente o algoritmo LRU (Least
Recently Used) selecciona para ser reemplazada la página del conjunto de páginas candidatas que
lleva más tiempo sin ser referenciada.
Este algoritmo es bastante bueno pero de implementación compleja. Produce bastante sobrecarga.
Suele implementarse mediante una lista en la que cada entrada contiene el número de página del
conjunto de páginas a ser reemplazada. Cada vez que una página es referenciada se coloca al
principio de la lista y al final la página menos referenciada, esto es, la candidata a ser sustituida.
Cada vez que se referencia una dirección virtual la lista debe ser reordenada.
Otra implementación se basa en un contador hardware que se incrementa cada vez que se referencia
una dirección. En la tabla de páginas se añade un campo que almacena ese valor cuando una página
es referenciada. De este modo, se selecciona para reemplazar la página que contenga el menor valor
en ese campo.

Algoritmo de reemplazamiento mediente envejecimiento


El algoritmo de reemplazamiento mediante envejecimiento (aging) es una aproximación al
algoritmo LRU pero que introduce menor sobrecarga ya que puede impelmentarse de forma más
eficiente.
Se utiliza un registro de desplazamiento de n bits, inicialmente a cero. Cada cierto tiempo T el
contenido del registro se desplaza a la derecha y se carga en el bit más significativo el bit
referenciada, r, después este bit se pone a cero. De este modo, la página a ser reemplazada es la que
tenga un menor valor en el registro.
El tamaño del registro determina la edad máxima que puede registrarse, ya que en un registro de 8
bits, todos a cero, no se puede determinar si la página no se ha referenciado en un tiempo ≥ 8T o se
acaba de cargar.

Algoritmo de reemplazamiento FIFO


El algoritmo de reemplazamiento FIFO selecciona para ser reemplazada aquella página del conjunto
de páginas candidatas a ser reemplazadas que lleva más tiempo cargada en memoria principal.

54 Capítulo 7. Memoria virtual


Para ello, el sistema mantiene una lista enlazada o cola FIFO en la que cada entrada contiene el
número de página de una página del conjunto de páginas candidatas a ser reemplazadas. Cuando
una página se carga en memoria se coloca al final de la lista. Así, la página que se encuentre en la
cabeza de la lista indica la página que lleva más tiempo cargada en memoria y será la elegida para
ser reemplazada.
La gestión de este algoritmo requiere muy poco tiempo de proceso. Es el más sencillo de programar
y de implementar, pero no tiene una buena tasa de aciertos y además pacede la anomalíua de
Belady.

Algoritmo de reemplazamiento de la segunda oportunidad (algoritmo del reloj)


Es una variante del algortimo FIFO que busca la página que lleva más tiempo cargada en memoria
y no ha sido referenciada recientemente.
Básicamente se consulta el bit referenciada, r, de la página que se encuentra al principio de la cola
FIFO, si r es cero, entonces es seleccionada para ser reemplazada. Si r es 1, se pone a cero y se
envía la página al final de la cola.
Se obtiene un mejor rendimiento que con FIFO pero a costa de mayor sobrecarga, ya que hay que
estar moviendo elementos en la cola.
Una forma de disminuir la sobrecarga es utilizar una lista o cola circular, así el puntero índice de
cola es quien se mueve y no los elementos de la cola.
En este caso el algoritmo recibe el nombre de algoritmo del reloj.
Si además del bit referenciada se tiene en cuenta el bit modificada, m, se mejora sustancialmente la
efectividad. En este caso nos encontramos con varias posibilidades.
• r = 0 y m = 0. Página no referenciada recientemente y no modificada, candidata ideal para
ser reemplazada.
• r = 0 y m = 1. Página no referenciada recientemente pero modificada. De ser elegida es
preciso actualizar la página en la memoria de intercambio.
• r = 1 y m = 0. Ha sido referenciada recientemente, por lo que no es buena candidata.
• r = 1 y m = 1. Ha sido referenciada y modificada recientemente, por lo que es probable que
vuelva a ser referenciada y, además, es preciso actualizarla en memoria de intercambio.
Con estas premisas, el algoritmo del reloj busca en primer lugar, a partir de la posición del puntero,
una página se busca una página con r = 0 y m = 0, si no se encuentra se busca entonces alguna con
r = 0 y m = 1, pero actualiza todos los r = 1 y los pone a cero. Si no encuentra ninguna vuelve a
buscar r = 0 y m = 0, de no encontrarla por cuarta vez busca una página con r = 0 y m = 1, con la
seguridad de que ahora sí tendrá éxito ya que en la segunda ronda todos los r se pusieron a cero.

Algoritmo de reemplazamiento del reloj considerando el conjunto de trabajo


El algoritmo del reloj puede ser mejorado si se considera el conjunto de trabao de un proceso. A este
algoritmo resultante se le conoce con el nombre de algoritmo WSClock.
En este caso, cada entrada i de la página de un proceso debe tener un campo denominado tiempo de
último uso, que contiene el tiempo virtual de último uso de la página. Cuando se produce un fallo de
página se examina el bit r y si está a 1, se escribe en ese campo el tiempo virtual del proceso.
La diferencia del tiempo virtual del proceso con el tiempo almacenado nos da la edad del proceso.
Siendo Δ el intervalo del conjunto de trabajo, si la edad de la página es mayor que Δ, no pertenece al
conjunto de trabajo.

Apuntes por Demetrio Quirós – Fundamentos básicos de los Sistemas Operativos 55


El algoritmo WSClock busca páginas con r = 0 y m = 0 y que no pertenezcan al conjunto de trabajo
del proceso. Si durante una vuelta completa se da la situación de que todas las páginas pertenecen al
conjunto de trabajo del proceso, entonces seleccionará la primera página que encuentre con r = 0 y
m = 0, aunque pertenezca al conjunto de trabajo.

Conclusiones sobre los algoritmos de reemplazamiento


Los algoritmos más utilizados por los sistemas operativos modernos son el de envejecimiento y el
WSClock.
La estragegia de reemplazo limita los algoritmos de reemplazamiento a utilizar. Así, algoritmos
como FIFO, LRU y envejecimiento pueden utilizarse tanto con estrategia de reemplazo global o
local.
El algoritmo WSClock sólo puede utilizarse con estrategia de reemplazo local.

Asignación de memoria principal


Esta tarea consiste básicamente en decidir cuántos marcos de página de la memoria principal se
reserva para un proceso que se tiene que ejecutar.
Se deben reservar como mínimo los marcos suficientes para contener todas las páginas a las que
pueda referenciar cualquier instrucción del repertorio de la máquina.
Como máximo, en teoría, se pueden asignar a un proceso todos aquellos que no estuvieran
bloqueados, pero esto anula los beneficios de la multiprogramación.
Dos estrategias de asignación son:
• Asignación fija. Consistente en asignar a cada proceso un número fijo de marcos. El
principal inconveniente es que si el conjunto de trabajo del proceso crece por encima del
número de marcos asignados se producirá sobrepaginación aunque existan marcos libres en
memoria. Si el conjunto de trabajo disminuye, por debajo del número de marcos asignados,
se estaría desperdiciando memoria. Si el sistema operativo utiliza estrategia de asignación
fija, es obligado que la estrategia de reemplazo sea local.
• Asignación variable. Modifica a lo largo del tiempo el número de marcos que un proceso
tiene asignados. Minimiza la memoria desperdiciada y la sobrepaginación a costa de
aumentar la sobrecarga ya que el sistema debe decidir continuamente cuántos marcos
reservar a cada proceso.
Para implementar la asignación variable, que proporciona mejores resultados, se debe utilizar un
algoritmo de asignación de marcos, siendo los más conocidos:
• Algoritmo de asignación equitativa. Cada cierto tiempo se comprueba el número de
procesos en ejecución y se asigna a cada uno el mismo número de marcos.
• Algortimo de asignación proporcional. Se asigna a cada proceso un número de marcos
proporcional a su tamaño y/o su prioridad.
• Algoritmo de asignación por la frecuencia de fallos de página o algoritmo PFF. Se basa en
que cuanto mayor sea el número de marcos asignado a un proceso menor será su tasa de
fallos, siempre que el algoritmo de reemplazamiento no sufra la anomalía de Belady.
Si la tasa de fallos se encuentra por encima de cierto límite, se asignan más marcos al
proceso. Si la tasa de fallos cae por debajo de un límite inferior se le quitan marcos. Si la
tasa de fallos está por encima del límite pero no existen marcos libres será necesario
intercambiar algún proceso al área de intercambio

56 Capítulo 7. Memoria virtual


Control de carga
En un sistema multiprogramado con memoria virtual mediante demanda de página, el sistema
operativo debe controlar el número de procesos que tienen páginas cargadas en memoria principal,
esto es, debe controlar el grado de multiprogramación GM.
Debe encontrarse un valor óptimo de GM con el fin de que se optimice al máximo el tiempo de
utilización del procesador. Si el grado de multiprogramación es bajo, el procesador se verá
infautilizado por ausencia de procesos; si el G M es alto puede que no se puedan contener en la
memoria principal los conjuntos de trabajo de los procesos, produciéndose sobrepaginación y por
tanto infrautilización del procesador, que debe esperar a que se realicen los intercambios con la
memoria secundaria.
Si se detecta sobrepaginación es necesario reducir GM intercambiando algunos procesos a memoria
secundaria y repartir los marcos libres entre los procesos que la estaban provocando.

Copia en memoria secundaria de páginas modificadas


La estrategia seguida para realizar la copia a memoria secundaria de las páginas modificadas,
conocida como política de limpieza (cleaning policy) puede ser:
• Limpieza por demanda. La página no se escribe hasta que es seleccionada para ser
reemplazada. Se aplaza la escritura hasta que no sea estrictamente necesario pero cuando se
produce un fallo de página hay que realizar dos operaciones de E/S: una para actualizar la
página modificada y otra para leer la nueva página.
• Limpieza por adelantado. Las páginas modificadas se agrupan en lotes y se planifica su
escritura cada cierto tiempo. Permite atender más rápidamente los fallos de página, al
realizar el volcado de la página antes de que se solicite, pero puede darse el caso de que una
página haya sido grabada y vuelva a ser modificada, debiendo realizarse de nuevo su copia.
Este problema puede solucionarse grabando solo las candidatas a ser reemplazadas.

Consideraciones adicionales sobre la paginación por demanda


Aspectos a tener en cuenta al diseñar la memoria virtual de un sistema con paginación por demanda
son el tamaño de página, la paginación por adelantado y la reserva de marcos libres (buffering).

Tamaño de página
El tamaño de página viene determinado por la arquitectura del computador, siempre potencia de
dos. Algunos computadores permiten seleccionar el tamaño dentro de un rango de valores. Para
seleccionar el tamaño adecuado hay que tener en cuenta:
• Fragmentación interna. De promedio es de media página por proceso. Cuanto mayor sea el
tamaño de página, mayor será la cantidad de memoria no utilizada.
• Tamaño de la tabla de páginas. Cuanto menor sea el tamaño de página en más páginas se
descompondrá el proceso y en consecuencia el tamaño de la tabla de páginas será mayor.
Además el tiempo de cambio de proceso aumenta al tener que cargar o vaciar más registros,
con MMU, o banco de registros, si se dispone de TLB.
• Número de fallos de página. Si el tamaño de página es pequeño el espacio de direcciones
virtual constará de más páginas, aumentando la probabilidad de que se produzca un fallo de
página.
• Tiempo de uso de E/S. Se tarda menos tiempo en transferir una página de tamaño grande que
varias de tamaño más pequeño. Si el espacio de direcciones virtuales se descompone en

Apuntes por Demetrio Quirós – Fundamentos básicos de los Sistemas Operativos 57


mayor número de páginas aumenta la probabilidad de realizar operaciones de E/S, tiempo
que no puede ser utilizado para la ejecución de procesos.
El aumento del tamaño de la memoria principal de los computadores provoca que se de menos
importancia a la existencia de fragmentación interna, escogiéndose tamaños de página cada vez
mayores.

Paginación por adelantado


Cuando comienza la ejecución de un proceso o se continúa con uno que estaba bloqueado se
produce un conjunto de fallos de página iniciales hasta que se carga el conjunto de trabajo.
Para evitar esto se puede usar la estrategia de paginación por adelantado (prepaging), que consiste
en cargar un cierto número de páginas N PA antes de iniciar o continuar su ejecución o cada vez que
se produce un fallo de página.
En general, si se cargan NPA páginas se referenciarán NPR páginas y no se referenciarán NPA - NPR.
Cada página referenciada cargada por adelantado evita un fallo de página. Si el tiempo que se
ahorra en tratar NPR fallos de página es superior al empleado en cargar las NPA - NPR que no son
referenciadas sí compensa utilizar paginación por adelantado.
Si se decide utilizarla, la selección del conjunto NPA puede hacerse:
• Cargar el conjunto de trabajo del proceso, que debe ser mantenido por el sistema operativo.
Opción empleada cuando se va continuar con la ejecución de un proceso interrumpido o
bloqueado.
• Cargar un conjunto de páginas contiguas en el área de intercambio, ya que el tiempo es
menor si se traen de una vez que si se recuperan una a una cuando sean referenciadas.

Reserva de marcos libres


Si se dispone de una lista de marcos libres donde cargar una página referenciada por una dirección
virtual que ha producido un fallo, el tiempo de tratamiento del fallo se reduce, ya que sólo hay que
hacer uso de esa reserva de marcos libres.
Si la reserva de marcos libres cae por debajo de un límite se utiliza un algoritmo de
reemplazamiento para seleccionar marcos reemplazables.
Mientras una página siga cargada en un marco, aunque esté entre los marcos libres, podrá ser
utilizada. Para ello cuando se produce un fallo de página primero se comprueba si está en la lista de
marcos libres antes de acudir a memoria secundaria. De este modo, esta lista de marcos libres se
utiliza como caché software de páginas.
Esta estrategia en ocasiones se denomina buffering de páginas.

58 Capítulo 7. Memoria virtual


Capítulo 8. Gestión de la Entrada/Salida
De forma general los dispositivos de E/S se pueden clasificar en dispositivos modo bloque y
dispositivos en modo carácter.
• Un dispositivo en modo bloque almacena la información en bloques de tamaño fijo, 512
bytes normalmente.
• Un dispositivo en modo carácter envía o recibe información como una secuencia o flujo
lineal de bytes.
Un dispositivo debe ser conectado a un módulo hardware denominado controlador de E/S para que
pueda ser utilizado por el computador. Un controlador puede manejar uno o varios dispositivos del
mismo tipo.
El sistema operativo se encarga de la gestión del acceso de los procesos a los dispositivos de E/S,
gestiona el buffering o el spooling.

Peticiones de E/S
Una operación de E/S puede ser solicitada por un proceso o por el propio sistema operativo
mediante una llamada al sistema indicando la dirección lógica del dispositivo, la dirección lógica
del espacio del proceso donde se almacenarán los datos y la cantidad de datos a transferir.

Capas del núcleo de un sistema operativo encargadas de la E/S


El software del núcleo encargado de la gestión de E/S se puede organizar en tres capas: susbsistema
de E/S, drivers de los dispositivos y manejadores de interrupciones.
Cada capa posee una interfaz bien definida para comunicarse con las capas adyacentes y realiza
unos servicios determinados.

Subsistema de E/S
Es el componente que se encarga de efectuar todas las tareas necesarias para la realización de las
operaciones de E/S comunies a todos los dispositivos e independiente de estos. Entre sus tareas se
encuentran:
• Asignación y liberación de dispositivos dedicados. Los dispositivos dedicados son aquellos
que sólo pueden ser utilizados por un proceso cada vez, como impresoras o unidades de
cinta. El subsistema de E/S determina si la petición de un proceso sobre un dispositivo
dedicado puede ser aceptada o rechazada.
• Bloqueo de procesos que solicitan una operación de E/S. El susbistema puede decidir pasar
al estado bloqueado al proceso que realiza la petición de E/S, dependiendo del tipo de
llamada y del estado del dispositivo.
• Planificación de la E/S. El sistema debe planificar el usao de los dispositivos con el fin de
optimizar su uso, disminuir el tiempo de espera promedio y distribuir equitativamente el uso
de los recursos, atendiendo a las prioridades de las peticiones.
• Invocación del driver de dispositivo apropiado. Para el subsistema de E/S, un dispositivo es
una caja negra que soporta un conjunto estándar de operaciones. Realmente cada dispositivo
implementa estas operaciones de forma diferente y son los drivers los que conocen estas
particularidades.
• Almacenamiento temporal de datos o buffering.

Apuntes por Demetrio Quirós – Fundamentos básicos de los Sistemas Operativos 59


• Proporcionar un tamaño uniforme de bloque a los niveles superiores de software.
• Gestión de errores producidos en una operación de E/S. Estos errores pueden ser errores de
dispositivos o errores de programación
El subsistema de E/S debe proporcionar una interfaz para los drivers de los dispositivos, tanto de
llamadas del subsistema al driver como del driver al susbsistema. En los sistemas operativos
modernos esta interfaz es uniforme.

Drivers de dispositivos de E/S


Un driver de dispositivo contiene el código que permite a un sistema operativo controlar a un
determinado tipo de dispositivo. Se diseña teniendo en cuenta las características del dispositivo y
las especificaciones del interfaz de drivers del subsistema de E/S.
Un driver suministra al subsistema de E/S el conjunto de funciones que se pueden realizar sobre el
dispositivo. Además puede invocar ciertas rutinas o procedimientos del núcleo, según estén
definidos en la interfaz.
El driver interactúa con el dispositivo cargando las órdenes en sus registros. Un driver debe realizar
un conjunto de acciones cuando el subsistema de E/S invoca una función. En general son:
• Comprobar que los parámetros son correctos y que la función se puede realizar.
• Traducir los parámetros de la función en parámetros específicos del dispositivo.
• Comprobar su el dispositivo está ocupado, encolando la petición, o libre y preparado o si es
necesario inicializarlo.
• Generar un conjunto de órdenes en función de la petición y cargarla en los registros del
controlador.
• Si el tiempo de espera de la ejecución de la órden es elevado, se bloquea utilizando algún
mecanismo de sincronización.
• Comprobar que no se hayan producido errores en la operación de E/S, tomando las medidas
para resolverlo o abortar la operación.
• Examinar la cola de peticiones pendientes de E/S y atenderla o quedar a la espera en estado
bloqueado.
El código de los drivers es reentrante, es decir, que no se modifica, por lo que es posible ejecutar
varias instancias del mismo driver simultáneamente.

Manejador de las interrupciones


Cuando una operación de E/S finaliza y el dispositivo se encuentra preparado para gestionar otra, su
controlador genera una interrupción. Cada interrupción suministra un número denominado número
del vector de interrupción que se utiliza de índice en una tabla denominada tabla de vectores de
interrupción, normalmente almacenada en las posiciones más bajas de memoria y en la que cada
entrada, vector de interrupción, contiene entre otras informaciones la dirección de comienzo del
manejador, handler, de la interrupción. Estos forman parte del núcleo y son extremadamente
dependientes del hardware.

Buffering
Si la transferencia de datos desde un dispositivo al proceso que realiza la petición se realizara de
forma directa a su espacio de direcciones, el proceso debería estar cargado en un marco de memoria
durante todo el tiempo desde la petición hasta la obtención de resultados. El marco debe ser
bloqueado para evitar que la página del proceso fuera reemplazada. Cuanto mayor sea el número de

60 Capítulo 8. Gestión de la Entrada/Salida


marcos bloqueados menor será el número de marcos candidatos a ser reemplazados lo que puede
dar lugar a la sobrepaginación. Además, el proceso no puede ser intercambiado hasta que no finalice
la operación de E/S.
Para evitar estos problemas se utilizan los buffers, área de la memoria principal a la que únicamente
tiene acceso el sistema operativo. El subsistema de E/S asigna buffers para las operaciones de E/S y
los drivers de dispositivo o rutinas de servicio de interrupción transfieren los datos entre los
dispositivos y buffers o viceversa. Además, los buffers sirven para adaptar las distintas velocidades
y tamaño de unidad de transferencia por parte de los dispositivos.

Estrategias
• Buffering con buffer único. Los datos se transfieren desde el dispositivo hasta el buffer y del
buffer al espacio del proceso en una operación de lectura. Desde el espacio del proceso al
buffer y del buffer al dispositivo en una operación de escritura. No se puede volver a utilizar
el buffer hasta que no finalice la operación completa y se vacíe el buffer.
• Buffering con dos buffers o buffering doble. Cuando se llena un buffer se utiliza el siguiente.
Mientras se llena el segundo se vacía el primero. En esta estrategia se desacopla el productor
del consumidor, ya que mientras uno escribe en un buffer se lee del otro. Además se reduce
el tiempo de espera de productor o consumidor.
• Buffering circular. Cuando un proceso realiza ráfagas largas de E/S es más conveniente el
empleo del bufferfng circular, consistente en disponer de varios bufferes utilizados de forma
consecutiva, volviendo a emplear el primero, si está vacío, finalizado el ciclo.

Caché de buffers de bloques de disco


Para reducir el número de operaciones de E/S a disco muchos sistemas operativos implementan vía
software un caché de buffers de bloques de disco, un área de la memoria principal del espacio del
núcleo reservada para buffers y que contiene los bloques de disco recientemente transferidos.
La gestión de la caché es similar a las caché hardware, debiend utilizarse algún algoritmo de
reemplazamiento (FIFO, LRU, etc) para seleccionar los buffers cuyo contenido deba ser
reemplazado.

Spooling
Una técnica muy utilizada para la asignación y control de los dispositivos de E/S dedicados, como
una impresora, suele utilizarse la técnica del spooling. Se implementa mediante un proceso demonio
y un directorio especia, directorio de spool o spooling. El proceso demonio es el único autorizado
para acceder al dispositivo. Si un proceso quiere hacerlo, envía los archivos deseados al directorio
de spooling desde donde el demonio los irá cogiendo para enviarlos al dispositivo.

Detalles de la gestión de E/S de algunos dispositivos

Relojes
Una forma de generar una señal periódica, reloj, es mediante un chip denominado reloj
programable que, entre otros, contiene un contador, un registro y un cristal de cuarzo.
Un reloj programable dispone de varios modos de operación, como el de disparo único o el de onda
cuadrada. En el modo disparo único cuando el contador alcanza el valor cero se genera una
interrupción y se detiene hasta que vuelva a ser inicializado.
En modo onda cuadrada el reloj se rearma automáticamente volviendo a cargar en el contador el
valor del registro y comenzando de nuevo la cuenta.

Apuntes por Demetrio Quirós – Fundamentos básicos de los Sistemas Operativos 61


El tiempo transcurrido entre dos interrupciones de reloj se denomina tic de reloj o, simplemente, tic.
El valor del tic puede ajustarse dependiendo del valor del registro. Se denomina frecuencia de reloj
al número de tics por segundo.
Para relojes en tiempo real es útil que el contador se incremente, en vez de decrementarse.
Los relojes programables sirven para diversas tareas como:
• Planificación de procesos. Para controlar los cuantos asignados a los procesos en Round
Robin, por ejemplo. En algoritmos basados en prioridades, para adaptarla en función del
tiempo de uso del procesador que lleve acumulado.
• Mantenimiento del tiempo real. En MS el punto de referencia son las 00:00:00 UTC del 1 de
enero de 1980 y en UNIX la misma hora y día de 1970. Para llevar el conteo de la hora es
necesario un contador de 64 bits. Para facilitar la gestión se utilizan dos contadores de 32
bits, uno con el conteo en segundos y otro para el número de tics del segundo actual.
También se utiliza un contador de tics desde el tiempo de arranque, que se suma al valor de
alguna posición de memoria donde se almacena el valor del tiempo real en el momento del
arranque.
• Disparo de alarmas. El sistema puede avisar a los procesos cuando haya transcurrido
determinado intervalo de tiempo. Si más de un proceso requiere una alarma, sería necesario
tener tantos relojes como procesos. Para evitarlo se utiliza la técnica de lista de alarmas, en
la que se almacenan las peticiones ordenadas por tiempo de disparo. Cada entrada almacena
la diferencia entre el tiempo de disparo de todas las entradas precedentes y el tiempo de
disparo que requiere. Sólo se decrementa un contador que, cuando llega a cero dispara la
alarma del primer proceso de la lista y elimina la entrada.
• Invocación de tareas periódicas del sistema. El sistema operativo mantiene una lista de
tareas periódicas, generalmente de adminstración, que son lanzadas de forma similar al
disparo de alarmas.
Puesto que a lo largo de un segundo se producen muchas interrupciones de reloj, las tareas que
realiza el driver de reloj deben realizarse lo más rápidamente posible para que no se resienta. Las
interrupciones de reloj, por ello, tienen una prioridad muy elevada.
Dependiendo del sistema operativo, algunas de las tareas que realiza el driver (decrementar cuantos
de ejecución, incrementar el tiempo de uso del proceso, incrementar el contador del reloj de tiempo
real, decrementar el contador de alarmas y tareas periódicas..) son delegadas al manipulador de la
interrupción de reloj.

Discos duros

Estructura física
Está formado por varios platos circulares de aleaciones de metal o plástico recubiertas de material
magnetizable que giran en torno a un eje vertical común a velocidades típicas de 5400, 7200 o
10800 rpm.
Cada superficie se divide en anillos concéntricos llamados pistas. Las pistas se dividen en sectores
donde se almacena la información. El sector es la unidad básica de transferencia de información de
un disco.
Sobre cada superfice existe un brazo en cuyo extremo se monta una cabeza de lectura/escritura. El
conjunto formado por las pistas de todas las superficies de todos los platos situadas a la misma
distancia del eje de rotación se denomina cilindro.

62 Capítulo 8. Gestión de la Entrada/Salida


Formateo a bajo nivel del disco
El formateo a bajo nivel o formateo físico es realizado por el fabricante del disco mediante el uso de
un software y el controlador del disco. Consiste en dividir cada superficie de los platos en pistas y
cada pista en sectores. Cada sector consta de:
• Cabecera o preámbulo. Patrón de bits que permite al controlador reconocer el comienzo del
sector, el número del sector y el número del cilindro.
• Área de datos. Con un tamaño típico de 512 bytes.
• Código de corrección de errores, ECC. Suele ocupar 16 bytes.
La capacidad del disco formateado a bajo nivel es inferior a la del disco sin formatear debido a los
huecos entre pistas y sectores y a una reserva de sectores para sustituir a sectores defectuosos.
Dentro de una pista los sectores se numeran desde 0 pero de manera intercalada en función de un
factor de intercalado o entrelazado. Del mismo modo, en una determinada zona de cilindros, la
numeración de los sectores de una pista está desplazada respecto de la pista adyacente, sesgo de
cilindro (cylinder skew), para mejorar el rendimiento y evitar tener que esperar una vuelta completa
para leer el primer sector.
La dirección física de un sector queda definida por la tripleta cilindro-cabeza-sector (CHS,
Cylinder-Head-Sector). Los discos más modernos soportan el método de acceso de
direccionamiento de bloques lógicos, (Logical Block Address, LBA). Cada bloque se hace
corresponder con un sector durante el formateo físico, haciendo corresponder de forma consecutiva
todos los sectores con bloques comenzado desde 0.
Particionamiento y formateo a alto nivel del disco
El particionamiento del disco consiste en establecer por software una o más particiones en el disco.
Una partición es un conjunto de cilindros contiguos. Desde un punto de vista lógico, cada partición
se considera como un disco distinto.
En el sector 0 del disco se crea el registro de arranque maestro (Master Boot Record, MBR), y a
continuación una estructura denominad tabla de particiones, que define el cilindro de comienzo de
cada partición y su tamaño.
Una vez particionado se debe realizar un formateo de alto nivel o formateo lógico, que establece el
sector de aranque del sistema operativo, si es una partición activa, y las estructuras de datos del
sistema de archivos.
Es posible no establecer ningún sistema de archivos y trabajar directamente como si fuera un array
de bloques lógicos, E/S en bruto. El área de intercambio de los sistemas UNIX utilizan este método.
Planificación del disco
El tiempo de lectura o escritura de un bloque del disco duro depende, entre otros factores, del
tiempo de posicionamiento de la cabeza de lectura/escritura y del tiempo de transferencia del
bloque desde el disco al controlador.
El tiempo de posicionamiento, o tiempo de acceso, es la suma del tiempo de búsqueda, tiempo
requerido para mover las cabezas hasta el cilindro, y la latencia rotacional o retardo rotacional,
tiempo necesario para que el principio del sector se posicione por el giro del disco debajo de la
cabeza.
Si las peticiones a disco se planifican adecuadamente es posible reducir el tiempo de búsqueda
promedio. Algunas estrategias son:
• Planificación de primero el del tiempo de búsqueda más corto (Shortest Search Time First,
SSTF). Se selecciona la petición que requiera, desde la posición actual, el tiempo de

Apuntes por Demetrio Quirós – Fundamentos básicos de los Sistemas Operativos 63


búsqueda más pequeño. Puede producir inanición de las peticiones de búsqueda más
alejadas si llegan continuamente peticiones a zonas más cercanas.
• Planificación LOOK. Las cabezas se desplazan en cierto sentido atendiendo las peticiones
que se encuentran en el camino y retorna hacia el sentido contrario. Si llega una petición
cercana pero en sentido contrario deberá esperar el regreso del cabezal.
En los discos que soportan LBA el algoritmo de planificación se implementa necesariamente en el
controlador del disco, el único que conoce los detalles de su organización física.
Tratamiento de los errores del disco
El error más frecuente es un error de lectura o escritura de un sector debido a que está dañado o
defectuoso. El controlador mantiene una lista de los sectores defectuosos para no utilizarlos. Un
sector defectuoso se identifica comprobando el ECC del sector. El controlador utiliza los sectores de
reserva mediante dos formas posibles:
• Sustitución directa. Si el sector j está dañado, se utiliza un sector de reserva como sector j.
Se presenta el problema de alterar la organización del entrelazado.
• Desplazamiento de sectores. Se desplaza una posición cada sector situado entre el sector de
reserva y el dañado. El sector de reserva se utiliza para contener el primer sector desplazado
y el último sector desplazado alberga el número de sector que estaba defectuoso. Mantiene
la organización de la pista, pero requiere más tiempo para realizarla.
Si el controlador no implementa ningún método de reemplazo, debe hacerlo el sistema operativo.
Para resolver los problemas provocados por fallos en los discos se desarrollan soluciones basadas en
múltiples discos, en la que los datos son distribuidos por más de uno y que, además, mejoran el
rendimiento al poder atender en paralelo peticiones de E/S independientes. El sistema más conocido
se denomina array redundante de discos independientes (Redundant Array of Independent Disks,
RAID).

Dispositivos de E/S adaptados al usuario

Gestión de la salida por pantalla


La pantalla de un computador es un dispositivo de salida de gráficos de trama (raster graphics) o de
mapa de bits (bitmaps). Cada punto de la pantalla, pixel, tiene asociado un número binario que
representa el color con que se representa en la pantalla.
La pantalla se conecta a través de un adaptador gráfico que posee aun memoria de video (VRAM)
en la que se almacenan los pixels de la imagen que se mostrará en pantalla. El tamaño de la VRAM
vendrá determinado por el número de bits necesarios para representar un pixel y por el tamaño de la
pantalla.
Las rutinas de manipulación y creación de gráficos pueden formar parte del sistema operativo y
ejecutarse en modo núcleo, como en Windows, o ser externas al sistema y ejecutarse en modo
usuario, como en UNIX/Linux.
Gestión de la entrada del teclado
Un teclado es un dispositivo modo carácter de entrada. Cada pulsación y liberación de tecla envían
un número a un registro del controlador E/S que lo supervisa. Éste genera una interrupción que,
atendida por el manejador correspondiente, despierta el driver de teclado.
El driver utiliza un mapa de teclas o mapa de código que resuelve la tecla pulsada en función de la
configuración de idioma y tipo de teclado. El bit más significativo del byte con que se informa de la
tecla pulsada indica si la tecla ha sido presionada o liberada. También lleva la cuenta de las teclas
que han sido pulsadas y no liberadas con el fin de poder capturar combinaciones de más de una

64 Capítulo 8. Gestión de la Entrada/Salida


tecla. El driver almacena la información en un pequeño buffer para que sea leída por el proceso
adecuado.
Gestión de la entrada del ratón
Un ratón es un dispositivo modo carácter de entrada. El desplazamiento del ratón provoca la
transmisión de un mesaje al registro del controlador de E/S, de unos 3 bytes, que contiene el
desplazamiento vertical, eje y, desplazamiento horizontal, eje x y estado de los botones, pulsado o
no pulsado. Los desplazamientos son relativos a la última posición registrada.
El controlador lanza una interrupción cada vez que recibe un mensaje y el manejador de la
interrupción despierta al driver, que lee el mensaje y lo coloca en una cola para que sea leído y
procesado por el proceso adecuado.

Apuntes por Demetrio Quirós – Fundamentos básicos de los Sistemas Operativos 65


Capítulo 9. Gestión de archivos

Archivos
Desde el punto de vista de los usuarios de los computadores, la unidad de trabajo es la abstracción
de almacenamiento en memoria secundaria conocida como archivo o fichero.

Tipos de archivos
Un archivo informáticose puede definir como un conjunto de información relacionada que se
almacena en memoria secundaria y que se identifica mediante un nombre, como una cadena de
caracteres. En general, un archivo contiene programas o datos.
Dos de los tipos de archivos comunmente soportados por los sistemas operativos son los directorios
y los archivos regulares u ordinarios.
Un directorio es un archivo que almacena una lista de los archivos y otros directorios que contiene.
Un archivo regular puede ser un archivo ASCII o un archivo binario.
• Un archivo binario contiene información de cualquier tipo codificado en binario con una
estructura determinada que solo puede ser interpretada por los programas que los utilizan.
• Un archivo ASCII está compuesto de líneas de caracteres ASCII codificados en binario que
no requiere de un programa que las interprete.
El nombre de un archivo es una cadena de caracteres. Cada sistema de archivos soportado por el
sistema operativo especifica la longitud máxima y el tipo de caracteres que puede tener. La
extensión del archivo proporciona información sobre el tipo de archivo. Sistemas como UNIX
ignoran las extensiones y otros como Windows las reconoce e interpretan asociándolas con el
programa que los genera.

Atributos de un archivo
La lista de atributos varía en función del sistema de archivos pero en general se tiene:
• Tipo de archivo.
• Tamaño, en bytes, palabras o bloques.
• Localización, ubicación en memoria secundaria.
• Creador y propietario. Identifica al usuario que lo creó y su actual propietario.
• Permisos de acceso. Para determinar quién puede acceder y qué puede hacer con el archivo.
• Información asociada al tiempo. Como fecha y hora de creación, modificación, último
acceso, etc.

Estructura interna de un archivo


La información contenida en un archivo se puede estructurar de tres formas posibles:
• Secuencia de bytes. Las operaciones de lectura y escrituras se realizan a nivel de byte. El
sistema operativo no tiene que interpretar la información contenida en cada byte; esa
responsabilidad recae en los programas de aplicación que se ejecutan a nivel de usuario.
• Secuencia de registros. Cada registro, de igual longitud, posee su propia estructura interna.
Las operaciones de lectura y escritura también se realizan a nivel de registros.

Apuntes por Demetrio Quirós – Fundamentos básicos de los Sistemas Operativos 67


• Registros indexados. Cada registro, de longitud variable, contiene un campo índice que
permite identificarlo. Se organiza en función de la clave de los registros que lo componen.
En una operación de lectura o escritura debe especificarse la clave de registro que se desea
leer o escribir. Al añadir un nuevo registro es necesario indicar su clave.
De forma general, un archivo está formado por bloques lógicos o registros de igual o distinto
tamaño. En el caso de secuencia de bytes el tamaño del bloque es de un byte.
Idependientemente de la estructura, las operaciones de E/S en memoria secundaria se realizan en
unidades de bloques físicos de igual tamaño. Un bloque físico, que comprende varios sectores, tiene
asignada una dirección física BF o número de bloque. Un archivo ocupará N bloques lógicos,
exisitendo fragmentación interna ya que el último bloque probablemente no sea ocupado al
completo.

Métodos de acceso a un archivo


• Acceso secuencial. Los bytes o registros se leen o escriben en orden comenzando desde el
principio. El sistema mantiene un puntero de lectura/escritura que indica la posición donde
debe comenzar la siguiente operación. Compiladores y procesadores de texto la utilizan.
• Acceso aleatorio. También llamado acceso directo. Los bytes o registros pueden ser leidos
en cualquier orden. Las operaciones de lectura/escritura pueden implementarse
especificando el número de byte o registro al que se desea acceder en la misma instrucción o
bien realizando primero una búsqueda y posteriormente realizar la operación de manera
secuencial.

Operaciones sobre archivos


• Crear archivo. Crea un archivo sin datos, vacío, en la estructura de directorios y crea las
entradas necesarias en el directorio correspondiente.
• Abrir archivo. Se busca en un directorio la entrada asociada al archivo y se carga en
memoria principal toda la información que necesite sobre el archivo: atributos, posiciones
de memoria secundaria donde se aloja, etc. Si la operación se realiza con éxito se devuelve
un entero positivo denominado identificador de archivo, que lo identifica en el conjunto de
archivos abiertos por el proceso o por el conjunto de procesos.
• Posicionamiento o búsqueda, seek. Permite configurar el puntero de lectura/escritura para
que apunte al comienzo del byte o registro donde se desea leer o escribir.
• Leer archivo. Permite la lectura del archivo desde la posición actual del puntero. La llamada
al sistema incluye como argumentos el identificador del archivo, el número de bytes o
registros que se desean leer y la dirección de memoria del espacio de usuario del proceso
donde colocar los datos leídos.
• Escribir archivo. Permite la escritura del archivo desde la posición actual del puntero.La
llamada debe incluir el identificador de archivo, el número de bytes o registros a escribir y la
dirección de memoria del espacio de usuario del proceso desde el que tomar los datos. Si los
datos se escriben al final del archivo se provoca su aumento de tamaño.
• Renombrar archivo. Cambia el nombre del arhivo.
• Cerrar archivo. La información que se mantiene en memoria principal asociada al archivo
se descarta. Si el archivo ha sido abierto por varios procesos no se cierrra hasta que lo hace
el último de los procesos.
• Borrar archivo. Libera el espacio en memoria secundaria y elimina su entrada en el
directorio.

68 Capítulo 9. Gestión de archivos


Directorios

Estructura de los directorios


Un directorio almacena una lista de archivos y subdirectorios. En cada entrada se almacena el
nombre y otras informaciones. Las estructuras de directorios más comunes son:
• Estructura de directorios de un único nivel. Consta de un único directorio donde se
almacena una lista con todos los archivos existentes, tanto de usuario como del sistema.
Todos los archivos deben tener nombres distintos.
• Estructura de directorios de dos niveles. Consiste en un directorio raíz, o directorio de
archivos maestro, que almacena una lista de directorios, uno por usuario. En su
implementación más sencilla, un usuario sólo tiene acceso al contenido de su directorio.
Para poder utilizar archivos de otros usuarios, además de que el usuario posea los permisos
necesarios, el sistema debe manejar nombres de ruta. Así, un archivo queda definido por la
ruta del directorio donde se encuentra y su propio nombre.
Este método también permite evitar la duplicidad de los archivos del sistema y de
aplicación. El sistema crea un usuario ficticio especial y en su directorio almacena todos
esos archivos. Cuando un usuario invoca un archivo primero se busca en su directorio de
usuario y si no se encuentra se acude al directorio especial.
• Estructura de árbol de directorios. La lista almacenada en cada directorio puede contener
entradas de otros directorios y archivos, pudiendo crearse múltiples niveles de directorios.
Para acceder a un determinado archivo debe especificarse su ruta completa.
La ruta puede ser absoluta, indicando el camino desde el directorio raíz, o relativa, desde el
directorio actual o directorio de trabajo.
Los sistemas que soportan una estructura de árbol crean dos entradas de directorio
especiales: la entrada punto “.”, que hace referencia al directorio actual, y la entrada dos
puntos “..”, que hace referencia al directorio padre.
• Estructura de directorios de gráfica acíclica. Con el fin de implementar la compartición de
archivos y directorios se emplea la estructura de directorios de gráfica acíclica, que permite
que el mismo directorio o archivo pueda ser referenciado por dos o más directorios
diferentes, siempre que no se produzcan ciclos.
Normalmente se realiza mediante el uso de enlaces, links. Un enlace puede implementarse
creando en el directorio origen una entrada que sea copia de la entrada del directorio destino
asociada al archivo compartido. Esta nueva entrada tendrá un atributo especial que indique
que es un enlace. Este tipo de implementación se conoce como enlace duro. Si la entrada
original se modifica, todas las entradas “copia” deben ser modificadas; el sistema debe
mantener una lista con los enlaces de cada archivo. Para evitar esto algunos sistemas utilizan
un nodo índice, o nodo-i, para almacenar las estructuras de datos con los atributos del
archivo y en la entrada del directorio se hace referencia a este nodo-i.
Otra forma de implementar un enlace es con un tipo especial de archivo que contiene la ruta
absoluta o relativa del archivo o subdirectorio compartido. Estos enlaces se denominan
enlaces simbólicos. Los enlaces simbólicos permiten enlazar con cualquier archivo de la
estructura de directorios local o remota. El uso de enlaces simbólicos consumen más espacio
que los enlaces duros, ya que ocupan una entrada de datos. Su utilización aumenta el
número de operaciones de E/S y la sobrecarga del sistema ya que es necesario buscar la
entrada del enlace en el directorio correspondiente para conocer su ubicación en disco, leer
del disoc el archivo del enlace para conocer la ruta del elemento compartido y después

Apuntes por Demetrio Quirós – Fundamentos básicos de los Sistemas Operativos 69


seguir esa ruta para encontrar la entrada del directorio que le permita conocer la ubicación
del elemento compartido.

Operaciones sobre directorios


• Crear directorio. Cuando se crea no contiene ninguna entrada, salvo “.” y “..”, si el sistema
operativo las soporta.
• Borrar directorio. En algunos casos sólo se permite si el directorio se encuentra vacío. Si se
permite, se eliminan también todos los elementos que contiene.
• Abrir directorio. Consiste en encontrar en el directorio padre la entrada que se desea abrir y
cargarla en memoria principal.
• Cerrar directorio. Se libera la memoria principal que almacenaba la información del
directorio.
• Leer directorio. Permite leer el contenido de una entrada del directorio, necesario para
operaciones de búsqueda y listado de contenido del directorio.
• Renombrar directorio. Permite modificar su nombre.
• Enlazar. Permite crear una entrada para enlace duro o simbólico.
• Desenlazar. Permite eliminar un enlace.

Sistemas de archivos

Estructura de un sistema de archivos


Un sistema de archivos define un esquema de almacenamiento de la información relativa a los
archivos en un dispositivo de almacenamiento secundario. En un disco puede haber tantos sistemas
de archivos distintos como particiones tenga.
De forma general se pueden distinguir las siguientes áreas:
• Bloque de arranque. Se sitúa al comienzo de la partición y puede contener el código
necesario para arrancar el sistema operativo.
• Estructura de datos con metadatos del sistema de archivos. Contiene información
administrativa y estadística del sistema de archivos, como por ejemplo el identificador del
tipo de sistema de archivos, número de bloques, número de bloques libres, etc. En algunos
sistemas se denomina superbloque. Es copiado a memoria principal cuando se accede por
vez primera al sistema de archivos.
• Estructura de datos con información sobre los bloques libres en el sistema de archivos.
Generalmente denominada lista de bloques libres. Puede implementarse como mapa de bits
o como lista enlazada.
• Estructura de datos con información sobre bloques asignados a los archivos. Algunas de las
más utilizadas son:
◦ Lista de nodos índice. O nodo-i, estructura de datos utilizada para almacenar los
atributos de un archivo y su ubicación en disco. Una entrada del nodo-i contiene la
dirección física o el número de bloque donde se encuentra el nodo-i asociado a un
determinado archivo.
◦ Tabla de asignación de archivos. (File Allocation Table, FAT). Tiene una entrada por
cada bloque físico existente en la partición del sistema de archivos. La entrada j de la
tabla hace referencia al bloque físico j. Si el bloque físico j está asignado a un archivo, la

70 Capítulo 9. Gestión de archivos


entrada j en la FAT contiene la dirección física del siguiente bloque del archivo. En este
caso no es necesario mantener información sobre bloques libres.
• Área de datos. Contiene los bloques libres y bloques asignados a los archivos y directorios.

Montaje de un sistema de archivos


Para poder acceder a los contenidos de un determinado sistema de archivos ubicado en memoria
secundaria este debe ser montado en algún punto dentro de la estructura de directorios. A dicho
punto se le denomina punto de montaje. El sistema operativo realiza el montaje de los sistemas de
archivos en el arranque o cuando se detecta un nuevo dispositivo de memoria secundaria conectado
al computador.
En sistemas Windows se trata cada sistema de archivos como un volúmen o unidad lógica, cada una
de las cuales tiene su propia estructura de directorios. Se asigna una letra a cada unidad.
En sistemas Linux cada sistema de archivos se monta como un directorio del sistema de archivos
principal, luego todos los sistemas de archivos quedan integrados dentro de la misma estructura de
directorios.

Asignación de espacio
Un aspecto importante es la forma en que se asignan los bloques físicos del área de datos del
sistema. Los métodos más utilizados son la asignación contigua, la asignación enlazada y la
asignación indexada.
Asignación contigua
Se asigna a un archivo un conjunto de bloques físicos contiguos. Así, si un archivo consta de N
bloques y el primer bloque se almacena en BF0, el segundo lo hará en BF0 + 1, y el último ocupará el
bloque físico BF0 + N - 1.
Este método minimiza las operaciones de búsqueda en disco y soporta tanto archivos de acceso
secuencial como aleatorio.
Presenta la desventaja de producir fragmentación externa. Sucesicos procesos de creación y borrado
de archivos provocará la aparición de huecos cada vez más pequeños, siendo necesario compactar
el disco, esto es, trasladar todos los archivos a un lado de la partición y todos los huecos al otro.
Otro inconveniente es que el sistema operativo debe conocer de antemano el espacio que va a
ocupar el archivo. Si se le asigna un hueco de tamaño superior al necesario se producirá
fragmentación interna. Si se le asigna un espacio inferior al que podría alcanzar tendrá que
recurrirse a alguna estrategia cuando necesite más espacio.
Asignación enlazada
El método de asignación enlazada consiste en almacenar al principio de cada bloque físico asignado
a un archivo la dirección física del siguiente bloque físico del archivo. Así, se organiza como una
lista enlazada de bloques físicos.
Permite usar cualquier bloque, por lo que no produce fragmentación externa y evita conocer por
adelantado el tamaño del archivo.
Resulta muy lento para su utilización con archivos de acceso aleatorio ya que para localizar un
bloque hay que pasar por todos los anteriores.
Además, la utilización de algunos bytes del bloque para almacenar la dirección del bloque siguiente
provoca que haya menos espacio disponible para datos y que este espacio no sea potencia de dos,
dificultando el procesamiento y la eficiencia.

Apuntes por Demetrio Quirós – Fundamentos básicos de los Sistemas Operativos 71


Una solución bastante utilizada es asignar el espacio en agrupamientos (clusters) de bloques físicos
contíguos, almacenándose al comienzo la dirección del siguiente agrupamiento. Esta solución
aumenta la fragmentación interna y produce fragmentación externa, dado que huecos de tamaño
inferior al del cluster no pueden ser asignados.
Otra desventaja es que si se daña o pierde uno de los punteros de la cadena el resto de los bloques
no estarían accesibles.
Para eliminar todas las desventajas del métido de asignación enlazada se puede utilizar una FAT,
ubicada en sectores contiguos después del sector de arranque. La FAT tiene una entrada por cada
bloque físico de la particición. La entrada j de la tabla hace referencia al bloque j del disco. Si el
bloque físico j está asignado a un archivo, la entrada j de la FAT contiene la dirección del siguiente
bloque. Si el bloque es el último del archivo, la entrada de la FAT contendrá un valor especial para
indicarlo. Lo mismo ocurre en caso de que el bloque esté libre.
Una copia de la FAT debe estar en memoria principal para optimizar su uso. Este espacio puede
llegar a ser muy grande si la partición del disco también lo es.
Asignación indexada
En este método se almacena en un nodo-i los atributos de un archivo y las direcciones físicas de los
primeros ocho o diez bloques de un archivo. También se almacenan las direcciones físicas de uno o
varios bloques de indicrección simple, doble o triple.
Un bloque de indirección simple almacena direcciones físicas de bloques de archivo.
Un bloque de indirección doble almacena direcciones físicas de bloques de indirección simple.
Un bloque de indirección triple almacena direcciones físicas de bloques de indirección doble.
Cada archivo tiene asociado un número entero positivo denominado número de nodo- i. Al principio
de la partición se mantiene una lista con todos los nodos-i existentes. El número de nodo-i asociado
a un archivo se almacena en la entrada de directorio que contiene al archivo.
Este método se puede usar tanto para archivos de acceso secuencial como aleatorio. No produce
fragmentación externa y permite que el espacio de los bloques físicos que contienen datos puedan
ser utilizados totalmente. Su implementación requiere de menos memoria principal que la FAT, ya
que solo es necesario mantener en memoria los nodos-i de los archivos abiertos.
La principal desventaja es que el tiempode acceso a un bloque de archivo depende de la estructura
interna del nodo-i. En el mejor de los casos y suponiendo que el nodo-i del archivo ya ha sido
cargado en memoria principal, si se desea acceder a uno de los primeros bloques del disco sólo hay
que hacer una lectura para acceder a dicho bloque, pero si se trata de bloques a los que se accede a
través de bloques de indirección simple, doble o triple, habrá que hacer una, dos o tres lecturas
adicionales en disco.

Gestión del espacio libre


Para esta función se suele utilizar una estructura de datos denominada lista de bloques libres,
aunque a veces no se implementa como una lista.
Mapa de bits
Cada bloque de disco tiene asignado un bit. Si el bloque está ocupado se marca con un 0 y si está
libre con un 1 (o viceversa). Si la partición ocupa N bloques, serán necesarios N bits.
Su principal ventaja es la sencillez para encontrar el primer bloque libre o el primer conjunto de k
bloques libres consecutivos. El principal inconveniente es que se precisa tener el mapa completo en
memoria principal.

72 Capítulo 9. Gestión de archivos


Lista enlazada
Si un bloque de disco puede almacenar ND direcciones de bloque, en cada bloque de la lista
contendrá la dirección del siguiente bloque y ND - 1 direcciones de bloques libres.
La principal ventaja es que sólo es necesario mantener en memoria un bloque de la lista enlazada.

Implementación de directorios
Un directorio es un archivo que almacena una lista de los archivos y subdirectorios que contiene.
Algunos sistemas, como FAT-32, almacena en cada entrada de un directorio el nombre del archivo o
subdirectorio y sus atributos, entre los que se encuentra la información para localizar los bloques de
datos que lo contiene.
En UFS (UNIX) o ext2 de Linux, se almacena en cada entrada el nombre del archivo o
subdirectorio y un puntero (número de nodo-i) a la estructura de datos (nodo-i) donde se almacenan
los atributos del archivo. Esta organización precisa de un acceso más a disco para copiar el nodo-i a
memoria principal.
Entre las implementaciones más comunes de directorios se encuentran:
• Directorios con entradas de igual tamaño. En cada entrada se almacenan las informaciones
asociadas al archivo y a continuación el nombre del archivo. Es sencilla de gestionar pero
para dar soporte de nombres largos cada entrada debe tener ese máximo, lo que supone un
derroche de espacio.
• Directorios con entradas de tamaño variable. Primero se almacena el tamaño que ocupa la
entrada, a continuación la información asociada a la entrada (atributos o nodo-i y finalmente
el nombre de archivo (hasta un cierto tamaño) al que se le añade un carácter especial para
marcar el final del nombre. Cada entrada se rellena para que coincida con un entero positivo
de palabras de memoria principal. Como máximo se despercicia casi una palabra. Cuando se
eliminan entradas quedan huecos de longitud variable, generando fragmentación externa que
puede precisar de una compactación del directorio.
• Directorios con entradas de igual tamaño y montículo (heap) para almacenar los nombres
de los archivos. Se almacena un puntero al comienzo del nombre de archivo dentro de l
montículo y sus atributos o nodo-i. Elimina la fragmentación externa y no es necesario
incluir caracteres de relleno, pero es de administración más complicada al tener que
gestionarse el montículo.
Otro aspecto a considerar está relacionado con la forma en que se realiza la búsqueda de un archivo
en un directorio, por ejemplo, buscando las entradas una a una.
Para ahorrar tiempo se puede mantener una cache de directorios con las entradas recientemente
accedidas o implementar cada directorio con una tabla hash y su lista de archvos y subdirectorios.
Cuando se desea realizar una búsqueda se introduce el nombre en la función hash que devolverá qué
entrada de la tabla hay que leer. Si la entrada está vacía, el archivo no existe. Para evitar las
colisiones cada entrada se puede implementar como una lista enlazada.

Consistencia
Para verificar la consistencia del sistema de archivos se suele incluir en los sistemas operativos un
verificador de consistencia. las inconsistencias más frecuentes que pueden presentarse en el sistema
de archivos son:
• Un bloque no aparece en la lista de bloques libres ni está asignado a ningún archivo. Se
soluciona añadiendo el bloque a la lista de bloques libres.

Apuntes por Demetrio Quirós – Fundamentos básicos de los Sistemas Operativos 73


• Un bloque figura en la lista de bloques libres y también está asignado a un archivo. Se
elimina el bloque de la lista de bloques libres.
• Un bloque figura varias veces en la lista de bloques libres. Solo aparece si se implementa
mediante lista enlazada de bloques libres y se soluciona reconstruyendo la lista.
• Un bloque está asignado a N archivos, siendo N > 1. Es la peor situación y puede
solucionarse copiado ese bloque a N - 1 bloques libres. Se recupera la consistencia, pero
probablemente después existan N - 1 archivos con errores.
Para evitar el uso de verificadores los sistemas de archivos modernos (NTFS, ext4, HFS+)
implementan la técnica del registro diario o journaling, que consiste en almacenar un informe de las
operaciones a realizar antes de hacerlas y eliminar el informe una vez realizadas con éxito. Si al
reiniciar el sistema el informe sigue exisistendo significa que ha exisitido un error y vuelve a
repetirse las operaciones pendientes para dejar el sistema de archivos en un estado consistente.

Recuperación de archivos

Copias de seguridad
Existen dos tipos de copias de seguridad:
• Copia de seguridad lógica. Únicamente contiene los directorios y archivos que el
administrador o el usuario desea copiar al medio de respaldo. Permite acceder a los
contenidos de forma individualizada. Estas copias pueden ser de tres tipos:
◦ Copia completa, con todos los archivos seleccionados.
◦ Copia diferencial, únicamente los archivos nuevos o modificados desde la última
completa determinada.
◦ Copia incremental, únicamente los archivos creados o modificados desde la última
completa o incremental.
• Copia de seguridad física. También conocida como imagen de disco. Consiste en copiar
bloque a bloque la partición de disco. Son más simples de realizar pero requieren montar la
imagen para iniciar la recuperación.

Instantáneas
ZFS, de Solaris, utiliza la técnica de copiar al escribir, copy-on-write. En esta técnica si el sistema
operativo precisa modificar el contenido de un bloque en el disco se localiza un bloque libre y se
copia el contenido modificado en ese bloque, modificando los punteros para que apunten a ese
nuevo bloque.
El sistema agrupa las modificaciones y las realiza cada cierto tiempo (valor típico 30 segundos).
Cada modificación se etiqueta con un número de versión diferente. La versíón actual coexiste con
versiones anteriores del sistema de archivos. Cada nueva versión se denomina instantánea
(snapshot). Cada instantanea puede montarse como un archivo de solo lectura para reacuperar datos
individualmente o en modo de escritura para restaurar el sistema completo a un estado anterior.
Las instantáneas no son una copia de seguridad. Las diferencias fundamentales son:
• Las instantáneas se toman de forma prácticamente inmediata y no ocupan espacio en el
momento de su creación. Sólo se requiere cambiar el número de versión actual.
• Las instantáneas pueden ser restauradas con gran rapidez. Tan solo es necesario volver a
montar el sistema de archivos a partir de la versión anterior.

74 Capítulo 9. Gestión de archivos


• Las instantáneas residen en el mismo disco físico que los datos que respaldan, por lo que no
son eficaces frente a daños físicos en el disco y deben complementarse con algún método de
copia de seguridad.

Eficiencia
La eficiencia del sistema aumenta notablemente si se reduce al mínimo imprescindible el número de
accesos de E/S a disco. Para lograr ese objetivo algunos sistemas operativos implementan en
memoria principal una caché de bloques de disco.
Para mejorar la tasa de aciertos de caché se utiliza la estrategia de lectura por adelantado de
bloques, que consiste en copiar en la caché no solo el bloque que ha dado el fallo sino varios
bloques contíguos a éste.
También puede intentarse que los accesos a disco consuman poco tiempo, por ejemplo almacenando
en el mismo cilindro los bloques a los que se espera acceder de forma secuencial.
En sistemas con nodo-i sería conveniente que éstos estuvieran lo más cerca posible de los bloques
de datos del archivo, por lo que el mejor sitio para almacenarlos sería la zona central del disco.
Otro aspecto a considerar es el tamaño de bloque de disco, en un compromiso entre un bloque
pequeño que reduce la fragmentación interna pero aumenta el número de accesos o un bloque
grande que desaprovecha espacio pero con menor número de accesos. Distintas pruebas demuestran
que un tamaño óptimo de bloque está en unos pocos KiB.

Apuntes por Demetrio Quirós – Fundamentos básicos de los Sistemas Operativos 75

También podría gustarte