Subido por Exequiel Lloréns Barello

Introducción a los Sistemas Operativos

Anuncio
Introducción a los Sistemas Operativos:
¿Qué son los SO?
Los SO son el corazón de toda computadora. El mismo proporciona servicios a
usuarios y programadores que permiten utilizar una computadora sin tener que
tratar con los comandos de hardware de bajo nivel difíciles de usar. Proporciona
interfaces relativamente uniformes para acceder a la amplia variedad de dispositivos
con los que interactúa una computadora. Además, la mayoría de los SO modernos
proporcionan interfaces gráficas de usuario (GUI, Graphical User Interfaces).
¿Qué debe hacer un SO?
● Proporcionar una interfaz de alto nivel del hardware al usuario y a los
programas.
● Administrar los recursos físicos (hardware, memoria principal, procesador,
E/S, redes, comunicaciones) y lógicos (archivos, directorio, semáforos) de la
computadora.
El desfasaje o a sincronicidad se puede definir informalmente como la ocurrencia
de eventos al azar o en momentos inesperados.
Vista del Usuario contra la del Sistema en un SO:
Para un SO las dos perspectivas más importantes son la vista del usuario
y la
vista del sistema. La vista del usuario consiste a cómo los usuarios o los
programas utilizan el SO, por ejemplo, la forma en que un programa lee la pulsación
de una tecla. A la vista del sistema concierne la forma en que el software del SO
ejecuta realmente la acción requerida.
A todo SO lo podemos ver de dos niveles, nivel de usuario
(usuario final y
programadores de aplicaciones) y nivel de sistema (programadores de sistemas y
administradores de sistemas).
Vista de los Usuarios y tipos de Usuarios:
Hay que distinguir entre los usuarios finales, los programadores de aplicaciones, los
programadores de sistema y los administradores del sistema.
● Usuarios de Aplicaciones (o usuarios finales): este grupo nos incluye a todos,
gente que usa o ejecuta programas de aplicación o del sistema. Como
usuarios esperamos una respuesta rápida y confiable.
● Programadores de Aplicaciones: este grupo incluye a quienes escriben
programas de aplicaciones, como procesadores de palabras o sistemas de
correo electrónico. Los programadores son muy exigentes con el SO. Las
facilidades con que cuenta el SO son la vista de los programadores acerca
del SO, y se denomina interfaz de programación de aplicaciones (API). Los
programadores también desean que el software que desarrollan sea
fácilmente transferible a otras plataformas.
● Programadores de Sistemas: se trata de quienes escriben software
estrechamente relacionado con el SO. Necesitan comprender en detalle el
funcionamiento interno del SO. Requieren acceder a estructuras de datos
especiales en el SO o a las llamadas privilegiadas del sistema.
● Administradores del Sistema: este grupo incluye a las personas que
gestionan facilidades de la computadora, y por lo tanto son responsables de
instalar y actualizar el SO, así como otros programas y facilidades del
sistema. También son responsables de crear y mantener las cuentas de los
usuarios, así como de proteger el sistema. Deben comprender cómo el SO
interactúa con otros programas y utilidades.
Vista del Sistema:
La vista del sistema se refiere a cómo el SO proporciona realmente los servicios. En
otras palabras, se refiere a los trabajos internos del SO. Esta vista es menos común,
que sólo les incumbe a los diseñadores y los implementadores del SO. Esta
información a menudo es considerada secreta por las compañías que producen y
venden SO, en caso contrario, estos sistemas se denominan sistemas de fuente
abierta.
Ejemplo del movimiento del mouse:
( No es importante)
Aunque el movimiento del cursor de un mouse sobre una pantalla parece directo,
ilustra las muchas vistas de un SO. Cuando el dispositivo apuntador se mueve,
genera un evento de hardware denominado interrupción, que manipula el SO. El SO
observa los movimientos del mouse en términos de algunas unidades específicas
del hardware, es decir, las lecturas son en número de pulsos generados, en lugar de
serlo en milímetros o pulgadas. Esta es la visión de bajo nivel del sistema. El
controlador del dispositivo del mouse lee la información de bajo nivel del movimiento
del ratón y otra parte del SO la interpreta, de modo que pueda ser convertida en una
visión de nivel superior del sistema, como coordenadas en la pantalla que reflejan
los movimientos del ratón.
En el “otro lado” la vista del usuario es que el cursor se desplaza de manera
continua sobre la pantalla.
Otro ejemplo para vista del sistema: copiar de un CD a Disco
1. Comprobar que el archivo esté en el CD.
2. Ver si el archivo existe en el disco rígido.
3. Crear el nombre de archivo en el directorio 4. Buscar espacio libre en el disco
para el archivo.
5. Leer los sectores de datos del CD.
6. Escribir los sectores de datos en el disco.
7. Actualizar la entrada de directorio en el disco 8. Actualizar la información de
espacio libre en disco
9. Ejecutar todo esto en segundos.
El SO depende de quien lo use y para que se usa
BIOS (sistema básico de E/S): el BIOS abstrae el hardware, gestiona dispositivos
comunes, como teclados, video básico y el reloj del sistema.
Recursos gestionados por el SO: (Orden Jerárquico)
Un papel fundamental del SO es la gestión de los recursos del sistema:
● CPU: el SO necesita planear cuál proceso ejecutar en la CPU en cualquier
instante. En sistemas monotarea sólo un proceso reside en memoria en cada
instante, pero en un sistema multitarea la gestión es más complicada ya que
hay más procesos en la memoria, así que deben utilizarse estrategias más
complejas para asignarle un tiempo a cada proceso en la CPU
eficientemente.
● Memoria Principal y Caches: el SO necesita asignar espacio de memoria a un
proceso antes de poder ejecutarlo. El código ejecutable de un programa
suele almacenarse en el disco duro. Cuando un usuario o un programa desea
ejecutar un programa que se encuentra en un disco, el SO debe localizar el
archivo de código del programa y asignar suficiente espacio de memoria para
mantener una parte inicial del programa. Debido a que muchos programas
son bastante grandes, el SO debe cargar solo parte del programa desde el
disco.
● Almacenamiento Secundario: este suele ser el disco duro, la mayoría de los
archivos de código y los archivos de datos están almacenados en el disco
duro hasta que hay una petición para cargar algunas partes de estos en la
memoria principal.
● Dispositivos de E/S: el SO incluye módulos denominados controladores de
dispositivos que vigilan el acceso a estos dispositivos. Estos
manipulan la interacción a bajo nivel con el hardware, y presenta una vista de
nivel superior de dispositivos de E/S al resto del SO. Debido a que hay
muchos tipos de dispositivos de E/S, y a que los usuarios a menudo agregan
nuevos a sus sistemas, los SO modernos cuentan con la capacidad de
detectar nuevo hardware e instalar dinámicamente los controladores de
dispositivos idóneos.
● Sistemas de Archivos: uno de los recursos de nivel superior que gestiona el
SO más importantes es el sistema de archivos
. Este sistema es un
módulo
del SO que proporciona una interfaz de nivel superior que
permite que los usuarios y los programas creen, borren, modifiquen, abran,
organicen, protejan archivos y accedan a estos usando diversas operaciones
de archivos.
● Interfaces de Usuarios: esto incluye la funcionalidad para crear y gestionar
ventanas en la pantalla de una computadora a fin de permitir que los usuarios
interactúen con el sistema. Al tener este componente, el usuarios puede
acceder a varios recursos en forma uniforme.
● Acceso a Redes: este recurso del SO permite que los usuarios y programas
accedan a otros servicios y dispositivos en una red de computadores. Un SO
es capaz de proporcionar funcionalidad tanto de bajo nivel como de alto nivel
para el acceso a redes.
● Suministros de Protección y Seguridad: el SO también cuenta con
mecanismos para proteger los diversos recursos de algún acceso no
autorizado. Estos mecanismos de protección y seguridad hacen que el
usuario no le cause daño a la máquina.
Componentes de un SO:
Los módulos proporcionan funciones a las que acceden usuarios y programas del
sistema, así como los otros módulos del SO. Los tipos de interacción dependen de
la arquitectura particular usada para implementar el SO. Por ejemplo:
● Arquitectura por capas
● Arquitectura orientada a objetos: cada módulo está implementado con uno
o más objetos con servicios, y cualquier objeto puede invocar los
servicios proporcionados por otro.
● Arquitectura monolítica
Concepto de Proceso:
Para cada acción que desee realizar un usuario
en su computadora se crea un proceso. Un
proceso, es un programa más su contexto (valor
de las variables, los archivos que puede tener
abierto, los punteros de los archivos, etc.). Sin
embargo, un proceso no necesariamente está
en ejecución todo el tiempo durante su
existencia. Un programa desde que se ejecuta
hasta que termina tiene diferentes estados. Hay
modelos con diferentes números de estados, en
este caso hay cinco. Al principio está en el
estado nuevo
, buscando los recursos
necesarios para ejecutarse y cargarlos en
memoria. Una vez que ya tengo todos los recursos asignados (menos la CPU),
pasa al estado listo
. Luego pasa al estado
ejecutarse o correrse
,
hasta que
termine, haga una llamada al sistema, o hasta que sea interrumpido.
Luego pasa a un estado finalizado
mientras el SO cierra todos los recursos
que había
recolectado.
Ahora, no todos los programas empiezan y terminan en una pasada, puede ser que
tengan que esperar a que el SO haga algo por medio de llamadas al sistema,
también conocido como instrucción trampa, el programa deja de correr, se guarda el
estado en memoria (pasa al estado espera o bloqueado , hasta que el SO haga
lo
que tenga que hacer) y se carga el SO para satisfacer esa llamada, luego
que pasa eso el proceso vuelve a estado listo. Estas llamadas al sistema están
documentadas por una API.
Información del Proceso:
Para seguir el camino del proceso, el SO suele asignarle un identificador único de
proceso ( o ID del proceso
) . También crea una estructura de datos
denominada Bloque de Control de Procesos (o
BCP ) . En el BCP como
mínimo guardan:
● Un identificador Único del Proceso (ID del proceso)
● Información de Prioridad (que tan importante es este
proceso)
● Estado del Procesador.
● Puntero a las estructuras de datos
● Punteros a los archivos que tenga este proceso (que
archivos tiene abiertos)
● Información de seguridad y autorización.
● Otros datos que dependen de cada SO particular.
Tipos de procesos y modos de ejecución:
Los procesos pueden clasificarse en varios tipos:
1. Procesos del usuario: procesos que se encuentran ejecutando programas de
aplicación en representación de un usuario.
2. Procesos del sistema: son otros programas de aplicación que efectúan un
servicio del sistema común en lugar de un servicio específico de usuario final.
Procesos del SO: también se les conoce como demonios , y se trata de
procesos que se encuentran ejecutando servicios y funciones del SO. Por
ejemplo, gestión de la memoria, planificación de procesos, control de
dispositivos, etc.
Casi todos los procesadores cuentan con dos modos de ejecución para los
procesos: el modo privilegiado (o kernel) y el
modo usuario
. Los
procesos del núcleo del SO por lo regular se ejecutan en modo privilegiado,
permitiéndoles ejecutar todos los tipos de operaciones de hardware y acceder a
todos los dispositivos de memoria y de E/S. Otros procesos se ejecutan en el modo
del usuario, que le prohíbe ejecutar algunos comandos, como los comandos de E/S
de bajo nivel. El modo del usuario también introduce el mecanismo de hardware de
protección de la memoria, de modo que un proceso solo puede acceder a la
memoria dentro de su espacio de memoria predefinido. Esto protege el resto de la
memoria de acceso erróneo o malicioso a su espacio de la memoria que puede
dañar sus datos o el código del programa.
Tipos de SO:
Hay muchos tipos de SO, los siguientes son seis tipos comunes:
● Monotarea - Monousuario: este SO ejecuta un solo programa la vez y solo
para un usuario a la vez. Los primeros SO era de este tipo, así como los SO
de las primeras computadores personales (como CP/M o MS-DOS).
● Multitarea - Monousuario: un SO así controla la ejecución simultánea de
múltiples procesos. Por lo tanto, debe contar con un componente de
planificación de la CPU que escoja cuales de los procesos listos ejecutar a
continuación. Al tener varios procesos listos en la memoria para ejecutar, la
CPU puede cambiar de la ejecución de un proceso a la ejecución de otro esto
se denomina cambiar de contexto
. Pero hay un costo elevado para
hacer esto, es necesario guardar todo el estado del proceso que está siendo
ejecutado, de modo que sea posible restaurarlo una vez que el proceso se
reanude más tarde.
● De tiempo compartido: el tiempo de la computadora era “compartido” por los
múltiples usuarios simultáneos. A medida que el precio del hardware y de los
procesadores se reducía en forma dramática, la necesidad por tiempo
compartido declinaba.
● De red: hoy en día las computadoras cuentan con una funcionalidad extra en
la cual están conectadas permanentemente a una red o están equipadas de
modo que puedan conectarse y desconectarse de algún tipo de red. Esta
funcionalidad puede clasificarse en dos niveles principales:
○ Servicios de bajo nivel: el SO incluye una funcionalidad para
establecer conexiones a redes, para enviar y recibir mensajes entre las
máquinas conectadas.
○ Servicios de alto nivel: los usuarios desean conectarse a otras
máquinas para buscar información, descargar archivos o programas, o
para acceder a bases de datos. (los routers o access points)
● SO distribuidos: estos pueden permitir que un usuario que inicio sesión en la
máquina de un cliente acceda en forma transparente a todos los servicios y
archivos posibles a los que está autorizado sin siquiera saber donde reside.
(la nube)
● De tiempo real: hay dos tipos:
○ Plazos duros: en caso de no completarse la tarea en el tiempo dado,
pueden haber consecuencias catastróficas para el sistema.
○ Plazos blandos: debe completarse en el tiempo dado, pero en el caso
de no hacerse no hay consecuencias.
● Para Dispositivos Móviles: (Teléfonos)
Enfoques Arquitectónicos para construir un SO:
● Enfoque Monolítico: los primeros SO se escribieron como un programa único.
A medida que los sistemas fueron creciendo, aumentaron los errores y
eran difíciles de mantener, por lo que se debió encontrar otro enfoque más
modular.
● Enfoque Micronucleo o Microkernel: en el micronucleo solo se incluye
funcionalidad básica. Específicamente, el único código en estos módulos
debe ejecutarse en modo supervisor, porque usa recursos privilegiados,
como instrucciones protegidas, o accede a la memoria que no está en el
espacio del núcleo. El resto de las funciones del SO se sigue ejecutando en
modo de usuarios. El código que se ejecuta en el modo kernel literalmente
puede hacer cualquier cosa, por lo que un error en este código puede
ocasionar más daño del que se ejecuta en el modo de usuario. Entonces los
beneficios de este enfoque surgen del hecho que la cantidad de código que
se ejecuta en el modo supervisor es más pequeña, lo cual lo robustece más.
● Enfoque por Capas: el SO se divide en módulos que están limitadas a una
función específica, como la planificación del procesador o gestión de
la memoria. Los módulos están agrupados en capas de abstracción creciente
(cada capa proporciona una vista más abstracta del sistema). Los SO más
modernos están construidos con base en una arquitectura por capas. ●
Enfoque Cliente-Servidor
Enfoque Monolítico vs Micronúcleo:
Arquitectura
en Capas:
SO Monotarea o Monoproceso:
Planificación de Procesos (Planificación de la CPU);
Cuando un proceso se coloca en el estado listo, es necesario decidir cuándo debe
ejecutarse en relación con los procesos que ya están en el estado listo. Esta
decisión la toma un módulo del SO denominado planificador a corto plazo
.
Hay varias formas de otorgarle la CPU a un proceso:
● (FCFS: First Come, First Served): es el método más simple y utilizado por
muchos SO, consiste en ejecutar un programa primero en entrar, primero en
salir (una cola FIFO, first-in, first-out). Sus ventajas son que es fácil de
implementar, fácil de comprender por parte de diseñadores y usuarios. Por
último es el más justo ya que no favorece a un proceso por sobre otro, y
económico en recursos.
● Por Prioridades (le va a dar la CPU al más importante): en un algoritmo por
prioridad damos precedencia a cada proceso. Siempre que permitimos que
algunos trabajos tengan prioridad mayor sobre otros se presenta un
problema; es posible que los procesos con más prioridad están postergando
un proceso de baja prioridad hasta el punto en que este último jamás sea
ejecutado. Este problema se denomina inanición
. En general, para
solucionar este problema monitoreamos los procesos que se han postergado,
y siempre que un proceso se pospone demasiadas veces, simplemente
elevamos temporalmente su prioridad. En algún momento este proceso se
ejecutara y luego hacemos descender la prioridad a donde estaba
originalmente.
● Garantizada: a un proceso se le asigna una parte de tiempo de la CPU, lo
utilice o no. El problema es que desperdicia mucha CPU, y tampoco se sabe
si va a alcanzar este tiempo para otros procesos.
● SRTF (shortest runtime first): esto se traduce a, el siguiente trabajo más
corto. Simplemente selecciona el siguiente trabajo a ejecutar tal que se
ejecute en la menor cantidad de tiempo posible. No se suele usar este ya que
hay que saber el tiempo que va a llevar ejecutar cada proceso.
● HRRN (highest response ratio next): se traduce a, siguiente mayor tasa de
respuesta. Tiene en cuenta los programas más interactivos, para darles más
prioridad. Esta variante se usa principalmente porque disminuye la
probabilidad de inanición.
Planificación de la memoria principal:
Es necesario administrar la memoria principal porque es un recurso escaso y caro,
además para:
● Cargar la mayor cantidad de procesos que hagan falta.
● Llevar registro de que está libre, asignado y a quien, en casos si no hay
suficiente memoria, le puede quitar memoria a algún programa para darle a
otro más importante.
● Brindar de manera transparente la memoria que requieren las aplicaciones.
El objetivo básico de la gestión de la memoria es permitir la ejecución de la
mayor cantidad de procesos posibles. Creación de programas:
1. Escribir código fuente
2. Compilación/traducción
3. Enlazamos este módulo con módulos semejantes creados por separado, ya
sea en estático o en dinámico.
4. Carga en Memoria (lee las variables, tamaños, recursos, todo del ejecutable y
se fija cual es la primera instrucción)
5. Ejecución
Un solo proceso:
En el entorno del CP/M, el SO residía en la parte superior de la memoria. Los
programas de aplicación empezaban en la ubicación 100. Desafortunadamente, a
medida que el SO crecía podía volverse tan grande que un SO actualizado podía
utilizar la memoria que necesitaba un programa que estaba ejecutándose bien antes
de la actualización del SO. En la siguiente figura se ve la arquitectura típica de uno
de los primeros SO para una computadora que sólo ejecutaba un proceso único.
Estos sistemas siguen presentando el problema de que, si el SO crece, los
programas deben ligarse con nuevas direcciones. La solución a este problema era
modificar de alguna manera la función del registro base.
Reubicación dinámica:
Cambia el nombre, lo que antes se llamaba registro base, ahora se denomina
registro de reubicación, como se muestra en la figura siguiente. Ahora el programa
no tenía que volver a ligarse cada vez que el SO se actualizaba o crecia, puesto que
toda referencia a la memoria se ubicaba de manera automática a medida que se
ejecutaba el programa.
Espacio
RAM
físico vs
RAM
lógico:
Esta nueva función de reubicación introduce un concepto importante: la diferencia
entre el espacio de dirección lógico y el espacio de dirección físico. Originalmente,
cuando se compilaba un programa, se creaba un programa que había que cargar en
la RAM en la dirección que se le asignaba. El programa se compilaba refiriendo un
rango de direcciones que corresponden uno a uno con las direcciones de memoria
física real. En realidad había dos espacios de direcciones, el primer espacio de
direcciones es el conjunto de direcciones que genera la CPU a medida que se
ejecuta el programa, este espacio se denomina espacio de direcciones lógicas.
El programa ejecutable se
cargaba en la memoria primaria. El conjunto
de direcciones usado para acceder a esta memoria se denomina espacio de
direcciones físicas.
Con el nuevo concepto
de reubicación dinámica, se
hace evidente que el espacio de direcciones lógicas y el espacio de direcciones
físicas del programa son diferentes.
Super Posiciones (Overlays):
A menudo los programadores requieren agregar funciones a programas que pueden
ejecutarse en memorias pequeñas. Es bastante común tener un programa integrado
por tres partes: una fase de inicio, un bucle principal y una fase final de reporte.
Estas partes de un programa no necesitan estar en la memoria al mismo tiempo, de
modo que se superponen
entre si en la memoria.
Intercambio es espacio (Swapping):
Esto consiste en mantener varios programas en ejecución al intercambiarlos, lo que
funciona como se muestra en la siguiente figura (muestra el programa A en
ejecución en la memoria principal).
Archivos:
Los sistemas de archivos suelen tener diseños por capas, donde cada una
proporciona servicios a la capa que está arriba de ella. Hay dos cuestiones que son
claras, la capa superior, la API, es una abstracción del concepto de archivos y la
capa inferior interactúa directamente con el hardware.
Directorios:
El SO requiere contar con algún tipo de índice de los archivos que el programa
puede buscar, estos índices se denominan directorios
(folders o carpetas). Los
directorios deben almacenar el nombre del archivo, pero además otros datos
sobre el mismo. La información sobre el archivo que no forma parte de los datos del
mismo se denomina metadatos del archivo.
Estructura lógica:
Hay varias estructuras lógicas diferentes que pueden usarse a fin de almacenar una
estructura de directorio para un sistema de archivos.
De un solo nivel: la forma de organizar lógicamente el directorio en un disco
depende del tamaño de este.
Estructura de árbol: un desarrollo importante en la organización de la estructura
lógica de los directorios del disco fue permitir directorios múltiples. El truco principal
consistió en permitir simplemente que los directorios se refieran a otros, además de
referirse a otros archivos. Con esta organización jerárquica de directorio es posible
dividir los archivos en varias categorías. En maquinas con mas de un usuario,
podemos asignar a cada usuario un directorio “de inicio”, que contiene todos sus
archivos de datos en subdirectorios.
Grafos acíclicos: Con un
solo directorio estructurado
como un árbol, estamos en
un problema sobre cómo
clasificar algún archivo.
Además, a veces no podemos recordar en qué directorio decidimos colocarlo. Una
solución que se usa algunas veces para resolver este dilema consiste en permitir
que los directorios formen grafos acíclicos dirigidos
. Estos es
una
entrada que no apunta directamente a un archivo, sino a otra entrada del directorio.
Métodos de acceso:
Los programas necesitan diferentes maneras de acceder al contenido del archivo:
● Acceso secuencial: para el procesamiento secuencial en almacenamiento
de disco, el SO debe contar con alguna definición del tamaño del registro
para cada archivo y luego debe seguir la pista de la posición actual
para
cada aplicación que tuviera abierto el archivo. Además, el SO
incrementa el apuntador de registro actual cada vez que hay una lectura o
una escritura.
● Acceso aleatorio: en este modelo, la aplicación indica al SO que registró en
el archivo necesita y el SO se mueve directamente a ese registro para leer o
escribir. Esto requiere asignación simple de un valor clave al número de
registro. Cuando la aplicación tiene acceso aleatorio a un archivo, esto coloca
el apuntador de registro en el registro siguiente, ahora la aplicación puede
emitir una operación read next y el SO regresa el siguiente registro e
incrementa el apuntador de registro actual. Por ejemplo, en una empresa
pequeña podría simplemente asignar secuencialmente los números de
empleado y usar el número de empleado como número de registro.
● Métodos de acceso de alto nivel: la mayor parte de los SO cuentan por lo
menos con los dos métodos de acceso mencionados anteriormente. Algunos
SO tienen uno o más métodos de acceso de nivel superior:
○ Acceso Indexado: El acceso aleatorio a veces no funciona para un
archivo grande, ya que después de un tiempo, muchos registros
se no serán utilizados, quedarán anticuados, etc. El resultado es que
un archivo maestro con acceso aleatorio habrán muchos registros que
ya no representan nada. Para esto se utiliza el método de acceso de
alto nivel indexado. Tiene tres áreas, el área de datos primarios ,
donde se guardan los datos; el área de clave única o clave principal
, que es
un índice para el campo clave principal en el
registro, y un área de clave secundaria, que es un índice para una
variable diferente. A
medida que se agregan registros al archivo,
estos se escriben secuencialmente en el área de datos primarios. Sin
embargo, para cada archivo escrito en el área de datos primarios, en
el área de clave principal se escribe un registro adicional y en el área
de clave secundaria se escribe otro registro. Un método de acceso así
está próximo a ser una base de datos, pero es algo más simple. Estas
tres áreas que se analizan pueden ser porciones de un archivo único o
pueden almacenarse por separado como archivos ajenos.
○ Acceso hash: puede aplicarse la técnica hash a un campo para crear
un valor clave aleatorio para tener acceso a un archivo de
acceso aleatorio cuando no se usan todos los valores clave.
● Acceso en bruto (raw): en este caso, el SO no proporciona ninguna
estructura de archivos, sino que reserva un área de disco donde las
aplicaciones pueden proporcionar su propia estructura.
Gestión de espacio libre:
El SO almacenará los datos de los archivos y directorios de bloque del disco. Para
ello debe saber cuáles bloques no han sido utilizados aún:
Lista enlazada: hay bloques en una unidad de disco, el SO debe seguir la pista del
primer bloque en la lista. Cada bloque contiene entonces un apuntador hacia el
siguiente bloque libre. La lista no está en cualquier orden. Podemos empezar
inicialmente con una lista ordenada, pero cuando una aplicación libera un bloque es
necesario poder colocarlo en la parte frontal de la lista, de modo que no tengamos
que preocuparnos por cambiar cualquier otro sector en el disco para apuntar a este
nuevo bloque recientemente liberado. Tomamos el apuntador hacia el bloque que
se encuentra en la cabeza de la lista y lo colocamos en el nuevo bloque liberado.
Escribimos el sector del bloque que contiene el apuntador del siguiente bloque libre
al disco y registramos el bloque recientemente liberado como el primer bloque en la
lista. Un buen aspecto de este mecanismo es que el único espacio extra necesario
es el apuntador único a la cabeza de la lista. Un mal aspecto es que resulta difícil
asignar bloques de espacio contiguos.
Listas enlazadas mejoradas: las listas
enlazadas para trabajar mejor
requieren contar con algún medio
para que no tengamos que leer
cada sector antes de usarlo. Hay
varias maneras de hacer esto, dos
comunes incluyen agrupamiento
e
indexación. Con la indexación
almacenamos varios apuntadores
de espacio libre
en un solo
bloque, este primer bloque se
denomina bloque índice
.
Otro mecanismo es el
agrupamiento, en esta técnica, el
SO aprovecha todas las
oportunidades para determinar
que dos o más bloques en la
cadena son adyacentes . En
este caso, el primer bloque en
este grupo contiene no solo un
apuntador al siguiente bloque
libre, sino que también una
indicación de cuántos de los
siguientes bloques en la lista son
adyacentes entre si. Esto permite que
el mecanismo coloque bloques
contiguos más fácilmente. Pero
también el primer bloque puede leerse
y luego el resto de los bloques del
grupo pueden manipularse sin
necesidad de leer nuevamente el
disco.
Mapa de bits:
Otro enfoque es contar con un mapa de bits en el que cada bloque en el sistema de
archivos esté representado por un solo bit en una gran cadena. Con un mapa de
bits es más fácil asignar múltiples bloques contiguos, basta con encontrar una
cadena de bits contiguos del tamaño requerido. Este mecanismo ocupa más
memoria que el de las listas enlazadas, ya que debemos mantener en memoria una
porción del mapa de bits.
Gestión de Espacio Ocupado:
Asignación contigua: significa que los bloques fijados a un archivo tienen números
en una secuencia estrictamente creciente por 1. Estos bloques no necesariamente
comienzan en el límite de una pista. Este esquema de asignación de espacio de
archivos presenta varias ventajas: para encontrar todos los datos se requiere muy
poca información, basta con la dirección del sector del primer bloque y la longitud
del archivo en los bloques. Un problema con la asignación contigua es que una vez
que se ha asignado un archivo, puede ser difícil hacerlo más grande porque es
probable que algún otro archivo sea asignado después del que queremos hacer
más grande. Para evitar este programa, lo que se suele hacer es asignar más
almacenamiento para el archivo que está siendo requerido por los datos. Esto se
denomina fragmentación del programador . Esto desgraciadamente es
desperdicio de almacenamiento, además, si hay suficiente espacio libre en el
disco para asignar otra copia del archivo, la operación es bastante simple, aunque
puede consumir tiempo si el archivo es grande. Si no hay suficiente espacio para la
nueva copia, es necesario hacer un proceso tedioso, por lo tanto surgieron las
extensiones . En este
esquema, un archivo no está limitado a una asignación
contigua única, la asignación inicial es un bloque contiguo, pero si esta lleno, en
lugar de hacer una nueva copia, se efectúa la asignación secundaria, no
necesariamente contigua a la asignación inicial.
Hay varias instancias de desperdicio en el esquema de la asignación contigua. La
primera es provocada por el hecho de que la porción más pequeña del espacio al
que podemos tener acceso, es un sector. Este espacio sin usar provocado por la
granularidad de la asignación se denomina fragmentación interna
.
Igualmente, un
problema mayor es el de la fragmentación externa , este
problema surge cuando
estamos a punto de llenar el disco, a medida que vamos
asignando archivos contiguos, tendemos a cortar el espacio libre porque sacamos
una parte del espacio libre más grande. Finalmente los huecos que quedan se
vuelven demasiado pequeños para la siguiente asignación. La solución al problema
se denomina desfragmentación/compactación y es complicada, la idea básica es
mover algunos archivos hacia huecos donde quepan dejando huecos más grandes
para los archivos que queremos asignar.
Asignación enlazada: este mecanismo es como una estructura de lista enlazada
en memoria primaria, pero aquí los elementos vinculados siempre son del mismo
tamaño: un bloque de disco. Cada bloque contiene la dirección del sector de inicio
del siguiente bloque en el archivo. Un inconveniente del mecanismo enlazado es
que en este vínculo se desperdicia una parte de cada bloque. Un archivo enlazado
contiene un apuntador hacia el primer bloque del archivo y la longitud del archivo en
bloques.
El lado bueno es que con asignación enlazada no hay fragmentación del
programador.
Entrada/Salida:
Hay diferentes categorias de E/S, que los SO tratan de maneras diferentes.
Dispositivos:
El SO debe tener en cuenta las características de los dispositivos:
● Acceso Aleatorio o secuencial: cuando hablamos de dispositivos de
almacenamiento secundario, específicamente unidades de disco, estas
unidades podemos tomarlas como si fueran de “acceso aleatorio”, sin
embargo, esto no significa que el tiempo para tener acceso a los datos sea
independiente de la ubicación de los mismos.
● Clases de Dispositivos: la mayoría de los SO dividen de manera amplia los
dispositivos en tres clases: de bloques, de caracteres y de red.
○ Dispositivos de Bloque: un dispositivo de bloque lee o escribe un
bloque a la vez. El tamaño de un bloque está determinado
parcialmente por el hardware, pero también por los administradores
del sistema, cuando se establece el sistema de archivos. Estos
dispositivos a menudo tienen acceso aleatorio directamente a
cualquier bloque en el dispositivo; es decir, en el bloque es posible leer
o escribir en cualquier orden. A veces, algún software requiere acceso
a estos dispositivos directamente en lugar de hacerlo mediante el
empleo del sistema de archivos, a esto se le denomina E/S en bruto
.
○ Dispositivos de Caracteres: estos dispositivos transfieren datos a
razón de un solo byte a la vez. Incluyen por ejemplo, impresoras,
ratones, teclados, etc. Atienden la mayor parte de operaciones básicas
como los archivos en modo de bloques: apertura, cierre, lectura,
escritura. Los dispositivos de caracteres no pueden atender la
búsqueda hacia atrás.
○ Dispositivos de Red: estos dispositivos no se ajustan a la semántica
tradicional de las operaciones con archivos. El problema es que las
aplicaciones que están esperando datos de entrada desde una red
nunca saben cuándo estarán disponibles los datos, o si es que lo
estarán en algún momento. Es por esto que los dispositivos de red
cuentan con una serie de interfaces.
Tecnologías de E/S:
El SO debe tener en cuenta las tecnologías de E/S:
Buffers: cuando introducimos datos en un sistema informático, por lo general
leemos de un dispositivo y escribimos en otro. En este caso usamos una
técnica que se denomina almacenamiento en buffer
. Un buffer es
una porción de la memoria
donde se almacena un registro
que se usará en una operacional
de E/S. Una razón por la cual
puede usarse es si el usuario que
escribe un documento produce un
solo carácter a la vez, sin
embargo, no podemos escribir un
solo carácter en un disco, la
unidad más pequeña de acceso
es un sector. Entonces usamos un buffer para guardar los caracteres que el
usuario escribió, hasta que haya suficientes para llenar un sector, luego
escribimos el sector al disco y empezamos un nuevo sector. Esto funciona
cuando la diferencia de velocidades entre los dispositivos es pequeña, en
cambio, si estas velocidades difieren en un factor de tres o cuatro, hay que
utilizar otra técnica denominada el doble almacenamiento en buffer. En
esta técnica, se asignan dos buffers para el proceso, primero
llenamos
un buffer y luego iniciamos la operación para escribir en el dispositivo de
salida. A medida que empezamos a escribir, comenzamos a llenar el
segundo buffer para los datos de entrada. Para el momento en que el
segundo buffer está lleno, la escritura del primero debe estar terminada y
entonces podemos empezar a escribir en el segundo mientras comenzamos
a llenar nuevamente el primero.
Caches: esta técnica se utiliza tanto en hardware como en software. Su
propósito es hacer parecer que una memoria mas grande, mas lenta pero
más barata se desempeña a la misma velocidad que una memoria más
pequeña, más rápida y por lo tanto, más costosa. Estas memorias funcionan
porque los procesos en realidad no tienen acceso aleatorio a la memoria. En
lugar de ello, operan según el principio de ubicación de referencia, el cual
establece que es más probable hacer referencia a direcciones en la memoria
que estén más próximas a las que ya se ha hecho referencia, que hacerlo a
direcciones que no estén. El otro aspecto del principio del ubicación dice que
una vez que un proceso ha emitido a una ubicación en la memoria es más
probable que vuelva a dirigirse a ella de nuevo a que lo haga a otra ubicación
aleatoria.
Operaciones de Bloque: estas consisten en empacar varios registros lógicos
en un bloque físico para escribir en un dispositivo; es algo semejante al
almacenamiento en buffer. Esta técnica se usa porque los apuntadores al
sistema de archivos no eran suficientemente grandes para direccionar todos
los sectores en algun nueva unidad de disco, de modo que asignamos
múltiples sectores al mismo tiempo.
Organización Física del Disco:
Sectores, Pistas, Cilindros y Cabezas:
En la figura se ven dos platos de disco duro montados sobre un eje, de modo que
pueden girar juntos. Cuatro brazos se extienden sobre los platos, cada uno contiene
una cabeza magnética
para lectura y escritura. Los brazos pueden desplazarse
hacia adentro o hacia afuera; con los brazos estacionarios en cualquier
posición, los platos giran de modo que un anillo de la superficie de un disco pasa
por la cabeza. Ese anillo se denomina pista . Los cuatro brazos están conectados
entre si, de modo que se mueven hacia dentro y hacia afuera como una unidad.
Esto significa que hay cuatro pistas que la unidad puede leer sin mover los brazos,
uno para cada cabeza y superficie. Este grupo de pistas se denomina cilindro .
Una pista está dividida lógicamente en sectores
. Los sectores son la unidad
más pequeña de datos que una unidad de disco puede transferir. Este arreglo del
hardware de la unidad de discos lleva el concepto de dirección de disco, que se
puede especificar mediante el número del cilindro, de la cabeza y del sector, o
direccionamiento CHS. Un disco con C cilindros, H cabezas y S sectores por pista
tiene C x H x S sectores en total y normalmente puede almacenar C x H x S
x 512 bytes.
Zonas de Conteo de sectores y direccionamiento de sectores:
Una unidad de disco gira a velocidad constante. La circunferencia de las pistas
exteriores es más larga que la de las interiores, de modo que puede almacenarse
más información en las pistas exteriores que en las interiores. Se usa una técnica
para la sincronización denominada grabación por
zona de bits
. Esta
técnica divide
las pistas del disco en zonas de pistas de tamaño semejante y
cambian la sincronización para las pistas en cada zona. Como resultado colocan
más sectores en las pistas de las zonas exteriores y menos en las de las interiores.
Velocidades: búsqueda, transferencia y almacenamiento en buffers
Uno de los factores más importantes en el rendimiento del SO es el tiempo de
búsqueda o tiempo de posicionamiento
de la unidad de un disco duro. Es el
tiempo que requiere la unidad para mover el montaje de la cabeza de una
pista a otra.
Organización Lógica del Disco:
Particiones:
Con los SO se proporcionó un programa de utilidad denominado
FDISK que podía usarse para dividir el disco en particiones por
separado. Crear particiones es una técnica útil para varias cosas,
por ejemplo, si se quiere que una máquina contenga dos SO y
que, aún así, permita que cada uno asuma que sólo él tiene el
control sobre la unidad de disco. La información sobre la partición
de un disco duro se almacena en una parte del primer sector
físico del disco, sin importar como se establece la partición. Este
sector se denomina sector de arranque
o
bloque de
arranque
del disco y contiene la tabla de particiones
.
Bloque de arranque:
Cuando una PC se reinicia, normalmente trata de arrancar un SO
desde uno o más dispositivos del sistema.
CP/M: Un SO simple de proceso único
Introducción a los monitores
Los predecesores de los SO se denominaban monitores, y tenían capacidades muy
limitadas. Los programas de aplicación se escribían en lenguaje máquina o
ensamblador. No había ningún SO, si no que había un pequeño programa monitor
que permitía que una aplicación realizará tareas comunes simples como:
● Emitir un carácter a un dispositivo como una pantalla de video o un teletipo.
● Obtener un carácter desde el teclado.
● Guardar el contenido de toda o parte de la memoria a un dispositivo de
almacenamiento.
● Restaurar el contenido de la memoria desde un dispositivo de
almacenamiento.
● Imprimir un carácter en la impresora.
¿Por qué el CP/M? ¿Cuál era la crisis de software?
Como cada fabricante elaboraba programas de monitor de acuerdo a lo que creían
que los programadores necesitaban, se hacía difícil elaborar programas portables, o
sea que sean ejecutables en distintas computadoras. Esto condujo a la creación del
CP/M (Control Program/Monitor), fue escrito para que los desarrolladores y usuarios
posean una interfaz sencilla y estándar. Creado para microcomputadoras con base
en los circuitos CPU Intel 8080&8085, por Gary Kindall.
Componentes del CP/M
Esto se logró mediante una capa de software llamado BIOS
el
que relacionaba
software con el hardware, de esta manera el SO podia ser usado en otras
computadoras, modificando levemente el BIOS de acuerdo al hardware utilizado. El
corazón del SO se llama BDOS , el cual se encarga de llamar a los servicios más
primitivos de la BIOS y es independiente del hardware utilizado. La última
parte del sistema se conoce como CCP , es la interfaz de usuario encargada de
ejecutar los
comandos escritos por los usuarios.
Características de un sistema de PC simple ( No muy importante)
Los primeros PC constaban de una tarjeta madre de circuitos. La misma tenía una
pastilla microprocesadora (CPU), algo de memoria RAM, una ROM que contenía el
BIOS y varios circuitos integrados (CI) que unían todas las pastillas.
La tarjeta madre contaba con “tarjetas” para insertar tarjetas de circuitos adicionales,
como RAM adicional, disquetes. La entrada/salida se realizaba a través de un
monitor de video y un teclado, conectados a la tarjeta madre.
Algunas de las características de este tipo de sistema:
1. El tamaño de la memoria principal era demasiado limitado: Por eso el SO
solo cargaba un programa por vez. Si una App no entraba en la memoria
disponible, se usaba la técnica overlays (superposiciones) para sustituir la
sección antigua con la nueva.
2. El formato de disco se estandarizó. Se fijaron el tamaño y el formato del
bloque del disco tanto para disquetes como para discos duros.
3. La manipulación de interrupciones era prácticamente para dispositivos de
E/S, puesto que solo se ejecutaba una App a la vez.
Gestión de procesos:
Monoproceso, el proceso se carga en la RAM empezando en la dirección 100H, si
un programa era demasiado grande se utilizaba la técnica de overlays. Se les
asigna espacio de pila en la memoria alta antes del S.O. El proceso se ejecuta de
principio a fin, si requiere E/S el procesador permanece ocioso hasta finalizar la
operación (E/S programada). En este SO simple, la gestión de procesos era
limitada, ya que sólo está en ejecución un programa a la vez.
Creación y ejecución de un programa de aplicación
Un programa se escribe, se compila y luego se vincula con las rutinas de la
biblioteca usando un
editor de enlace . El resultado es un archivo imagen
de un programa listo para ser cargado en la memoria y ejecutado (se le llama
programa ejecutable). Para que empiece a correr, debe cargarse en la memoria su
código ejecutable. Este proceso lo hace el CCP, este hace su trabajo haciendo solo
llamadas al BDOS, nunca llama directamente al BIOS. Cuando se introduce un
nombre al CCP, si se trata del nombre de un comando integrado se ejecuta ese
comando. Si el nombre no es el de un comando integrado , el CCP intenta encontrar
un archivo ejecutable en el disco con ese nombre. Si existe uno, el contenido de ese
archivo se carga a la memoria y el programa empieza a correr.
El proceso se ejecuta desde el principio hasta el final.
Si requiere E/S, la CPU permanece inactiva hasta
que se completa la E/S requerida.
En otros SO, el componente semejante al CCP
algunas veces se denomina shell o intérprete de
comandos. Un usuario puede invocar directamente a
los comandos del CCP al escribir un comando del
CCP o el nombre de un archivo con el ejecutable del
programa.
Gestión de la memoria
Al tener una memoria principal muy limitada, se decidió que sólo so cargará un
programa a la vez en memoria. El SO, al ser pequeño siempre se encontraba en la
parte alta de la memoria. Si un programa no cabía en memoria, se debería escribir
la aplicación para que entrara, cuando se necesita una nueva sección se utiliza la
técnica de overlays
para sustituir la antigua por la nueva.
El formato de disco se estandarizó, por lo tanto se fijaron el tamaño y el formato del
bloque de disco, lo que condujo a una estandarización del sistema de archivos.
Las interrupciones sólo se utilizaban para dispositivos de E/S ya que no era posible
ejecutar más de una aplicación a la vez, además de no necesitar una planificación
de la CPU.
El CCP carga los programas en la memoria, dividiéndolos en 2 partes: el código
ejecutable y los datos del programa. En general, los programas utilizan una pila para
sus variables temporales, esta se encuentra en la parte alta de la memoria por
debajo del SO. El software que copia estas dos partes en la memoria se denomina
cargador.
Los programas normales se cargan en la RAM, empezando en la dirección 0100
Hex. Al contar con una dirección fija, facilita a los compiladores y enlaces crear
ejecutables.
No se cuenta con un sistema de protección para evitar que la pila sobreescriba al
programa.
Una cabecera del programa estaba ubicada en la memoria inmediatamente antes
del código del ejecutable. Esta contiene apuntadores a direcciones de la memoria
donde estaban ubicados la pila y datos fijos, también suministraba argumentos al
programa.
El SO estaba localizado en la parte más elevada en la memoria porque no todos los
sistemas CP/M tenían la misma cantidad de memoria (podrían tener 32, 48 o 64 k).
Así el SO se configuraba para ocupar las ubicaciones más elevadas en la memoria,
dejando una dirección fija para cargar programas. Si el SO se volvía más grande,
podía empezar en una dirección más baja en la memoria, pero sin obligar a ningún
programa a cambiar de dirección.
Gestión de Entrada/Salida
La manipulación de E/S era muy limitada,el BIOS estaba especializado para cada
tipo de teclado. Se requerían funciones simples como presionar caracteres, mostrar
caracteres en pantalla, o imprimir. Había un gran debate entre portabilidad vs
flexibilidad, ya que saltándose el BIOS y accediendo directamente al BDOS se
obtiene flexibilidad adicional, a costa de perder la portabilidad hacia otros equipos
diferentes.
Entrada desde el teclado: Portabilidad vs Flexibilidad
Debido a que los teclados hicieron su aparición en varios tipos el BIOS estaba
especializado para cada tipo de teclado, aunque proporcionaba una misma interfaz
al resto del SO. Luego, el BDOS usaría las funciones del BIOS para crear una
interfaz más simple para el teclado. Estas funciones para el teclado eran:
1. Leer un carácter del teclado
2. Comprobar si se había oprimido una tecla
Salida desde el monitor de video: movilidad vs funcionalidad vs desempeño
La pantalla o monitor de video planteaba problemas más importantes . Primero, las
funciones disponibles a través de las funciones de interfaz del BDOS y el BIOS eran
limitadas. Había muchas características de sistemas de video que no era posible
usar directamente por las llamadas simples al sistema del SO. Segundo, la salida
desde la pantalla usando el BDOS era muy lenta. Muchas aplicaciones podían
escribir caracteres directamente en la memoria de la pantalla y tener acceso
directamente al hardware del controlador de video. La razón más importante para
evitar el BDOS era mejorar el desempeño de la aplicación. Escribir directamente en
la memoria de video proporcionaba no sólo más funcionalidad sino que también era
mucho más rápido que ir a través de una llamada al sistema del SO.
Sistema de archivos
Uno de los principales servicios que proporcionaba el SO era un sistema de
archivos estándar y portátil.
Una pista tenía 26 sectores, el primer sector denominado con el 1, y el último con
26, cada sector contiene 128 bytes de datos. El sistema de disco comprendía la
unidad de disco y el
controlador de disco
. La unidad era la que contenía
almacenados los datos y el controlador de disco solía estar integrado en la
Mother, y este se encargaba de leer o escribir en uno o varios sectores en una pista.
Debe controlar que no se haya leído o ido a una pista equivocada. Un disco tenía
512 bytes de datos.
Gestión de Archivos:
El SO contaba con un sistema de archivos sencillo integrado en la parte superior del
BIOS. Una parte de los archivos que pueden almacenarse en un disco contiene el
código binario del SO en sí. Cada disco tiene un directorio que almacena
información acerca de los archivos almacenados; sus tamaños, su ubicación física,
donde están almacenados. Cada disco físico se divide en tres áreas:
01.Área de arranque del disco: pequeña,
simple, contiene el binario del SO para
arrancar la PC. Cuando se reinicia la PC se
ejecuta un pequeño programa en la ROM que
copia la imagen ejecutable del SO desde el
disco hasta la memoria.
02.Área del directorio de archivos: contiene
información sobre cada archivo almacenado.
Tamaño fijo y se registra en una tabla en el
BIOS. Cada entrada en un directorio contiene
lo siguiente:
e. Número de usuario
: va del 0 al 15 permitiendo que varios usuarios
puedan compartir un disco.
f. Nombre de archivo: consta de 1 a 8 caracteres seguidos de 0 a 3
caracteres de tipo de archivo, denominado nombres de archivo
.
g. Contador de extensión : si un archivo toma más bloques de los que
pueden ser apuntados por una entrada, proporciona entradas adicionales.
h. Número de registros : las longitudes de los archivos se redondean hasta
los 128 bytes más cercanos, de modo que las aplicaciones deben saber la
cantidad de datos que hay en el último registro.
i.
Mapa de asignación
: es un grupo de números (o apuntadores) a
bloques de disco que contiene los datos para el archivo.
03.Área de almacenamiento de datos: Contiene los bloques de datos para
los archivos. Para que el sistema tenga acceso a un archivo, el programa
de aplicación del usuario debe proporcionar el nombre del archivo y el
sistema de archivos lo busca en el directorio de disco para determinar si
un archivo con ese nombre fue guardado en el disco. Los sectores están
agrupados entre si en bloques de asignación , que son sectores
consecutivos agrupados entre si. El tamaño del disco determina el tamaño
de estos bloques de asignación.
El BIOS contiene una tabla
integrada que proporciona el tamaño de cada una
de
estas áreas. Además, en el directorio no hay fechas ni horas. Sólo hay un
directorio sin subdirectorio. Un archivo debe almacenarse totalmente en un disco. Si
el directorio está lleno, también lo está el disco. No hay ningún tamaño de entrada
determinado de modo que el tamaño del archivo debe calcularse a partir del número
de apuntadores en esta entrada del directorio y medidas posibles.
Si el directorio está lleno, también lo está el disco. El tamaño del directorio es fijo,
por lo que en un disquete sólo pueden almacenarse 64 archivos o menos.
Procesos y multitarea básica
La idea era hacer un trabajo en un proceso de fondo mientras se hacía un trabajo en
un proceso de primer plano. La solución del CP/M fue un proceso de impresión de
fondo. En lo más alto de la memoria debajo del SO se carga un pequeño programa.
Este programa se iniciaba a sí mismo y luego le devolvía el control al CCP,
permitiendo la ejecución de otro programa. Esto aparentaba que la computadora
hacia dos cosas a la vez, es decir multitarea.
SO Multitarea Monousuario:
Planificación de Procesos:
Concepto de Apropiación: es la facultad del SO de quitarle un recurso a un
proceso, por ejemplo la CPU. Al agregar apropiación las planificaciones para la CPU
que eran para monotarea se pueden modificar para que se conviertan en multitarea:
● FCFS se convierte en Round Robin. En este caso, la apropiación está
basada en un quantum de tiempo, dejamos que cada proceso se ejecute una
cantidad específica de tiempo sin hacer ninguna operación de E/S. Si el
proceso excede ese tiempo, apropiamos la CPU y colocamos ese proceso al
final de la cola de ejecución.
● SRTF (R=Runtime) se convierte en SRTF (R=Remaining).
● Prioridad se convierte en Prioridad apropiativa. Acá podemos aplicar
apropiación cuando un proceso de prioridad superior entra en el estado listo.
Colas multinivel
Como indica su nombre, en lugar de una cola única se tienen varias. Todas las
colas individuales pueden utilizar el mismo algoritmo de planificación, o pueden
utilizar algoritmos distintos. Las colas tienen prioridades diferentes, y la cola con
mas prioridad es la que se atiende primero. La mayor parte de los SO modernos
cuentan con un sistema de retroalimentación
a las colas multinivel. El inicial
es que
un nuevo proceso es interactivo, de modo que se coloca en una cola
de alta prioridad. Si el proceso se ejecuta por más tiempo del permitido por el
quantum para esta cola sin hacer ninguna llamada de bloque al SO, entonces el SO
supone que en realidad no es un proceso interactivo, de modo que lo mueve hacia
la siguiente cola de menor prioridad. Esta cola también puede tener un quantum de
tiempo más largo. Entonces, si el proceso no termina en su quantum de tiempo en
la cola rápida, quizás sea conveniente darle más tiempo a la cola inferior. Por lo
general hay al menos tres de estas colas. La mayoría de estos algoritmos lo que
hacen es quitarle prioridad a los procesos que agotan el quantum y dale prioridad a
los que tienen más interacción con el usuario. Se muestra un ejemplo a
continuación:
Dos colas Round Robin
y una FCFS. Arriba los
procesos de mayor
prioridad. Al agotar el
quantum cae la
prioridad.
Evaluación de los algoritmos:
Existen varios criterios para evaluar los algoritmos:
● Producción: número de trabajos que se ejecutan por hora o por minuto..
● Tiempo medio de retorno: tiempo transcurrido desde el inicio hasta el final
del trabajo.
● Tiempo de respuesta: tiempo transcurrido desde que se presenta el trabajo
hasta el inicio del resultado.
● Utilización de la CPU: porcentaje del tiempo en que la CPU ejecuta trabajos
reales (sin intercambiar entre procesos o hacer alguna otra tarea, es de
interés primordial en la mayoría de los sistemas).
● Tiempo medio de espera: tiempo que el proceso para en la cola de listo.
Otras Consideraciones:
Hay otros aspectos que impactan en la planificación de los procesos:
● Planificación a largo plazo: en un SO PC con una GUI, normalmente no
existe este planificador. La tarea del programador a largo plazo es decidir
cuántos trabajos tratar de ejecutar al mismo tiempo y cuáles trabajos ejecutar
cuando.
● Afinidad con el procesador: es importante saber si un proceso es afín a un
core de un procesador o no. (Hay computadoras con distintos colores o
procesadores, es decir que son mejores para ciertos procesos).
● Modelo de creación de procesos: como se crean los procesos.
Hilos:
Elmasri Pag 93 PDF
Gestión avanzada de memoria:
Múltiples procesos con un número fijo de procesos:
Los diseñadores de SO comenzaron a buscar mejores formas para organizar el
procesamiento. Terminaron por darse cuenta de que el registro de reubicación
podía ejecutar un programa en cualquier parte, y no solo en la parte superior del SO
residente. Se desplazaron a una organización de la memoria del SO como en la
imagen (SO multiproceso con un número fijo de procesos):
Ahora que el SO ejecuta múltiples programas y un programa realiza una operación
E/S hacia algún dispositivo lento, el SO simplemente coloca la dirección de la
memoria del segundo programa en el registro de reubicación y empieza a ejecutar
el segundo programa. La solución para evitar que las aplicaciones no pudieran
dañarse entre si era agregar un registro límite que pudiera establecer una cota
superior más allá de la cual un programa no puede direccionar, justo como no podía
direccionar más abajo del establecimiento del registro de reubicación. Cuando el SO
cambia de la ejecución de un programa a la de otro, ahora debe fijar tanto el registro
de reubicación como el registro límite.
Fragmentación interna:
Cuando se instala este tipo de SO, el administrador debe decidir cuánta memoria
apartar para cada área del programa: una partición. El SO no modifica el tamaño de
estas particiones a medida que el sistema está en operación. Ahora el SO está
tratando de colocar más programas en la misma partición. El problema con esto es
que si hace una partición y se ejecuta un programa de menor tamaño en ella, se
estaría desperdiciando el resto de la partición. Este espacio sin usar se denomina
fragmentación interna.
Podríamos establecer una o dos particiones pequeñas para ejecutar pequeños
trabajos rápidos y una o dos particiones más grandes para las aplicaciones grandes.
Esto haría tender a minimizar el espacio desperdiciado debido a la fragmentación
interna.
Múltiples procesos con un número variable de procesos
Una solución parcial a la fragmentación interna
consiste en no hacer las
particiones de tamaño fijo o en un número; en lugar de ello, usamos tanta memoria
como se necesite para ejecutar el programa. Cuando ejecutamos el programa le
asignamos una cierta cantidad de memoria asignada por el programador. Si este
intenta usar más memoria que la indicada por el programador, entonces el SO
termina con un error. Cuando un programa termina, el SO vuelve a poner a
disposición esa memoria para ejecutar otro programa. Este espacio suele
denominarse hueco o fragmento externo. El SO suele mantener una lista de los
huecos disponibles
Supongamos que tenemos dos huecos, cada uno de 5 MB y que tenemos un
proceso por ejecutar que indica que requiere 8MB. Tenemos 10 MB de bloques de
memoria libre en los dos huecos (Suficiente para ejecutar este proceso). Pero la
memoria libre no está en una pieza, de modo que no podemos ejecutar el programa.
Esta situación se denomina fragmentación externa.
Debido a que nuestros procesos son reubicables, es posible mover un programa en
la memoria aun después que ha comenzado su ejecución. Normalmente el proceso
se suspende, se mueve a otra ubicación y vuelve a empezar. El SO sólo tiene que
modificar el valor colocado en el registro de reubicación de modo que indique el
inicio de la nueva ubicación de la aplicación en la memoria física. Este proceso se
denomina compactación .
Carga dinámica:
El programador decide explícitamente cuando cargar las superposiciones y cuando
llamar a las rutinas que están en la superposición. Cuando el SO carga un programa
en la memoria principal, podría cargar sólo el cuerpo principal del programa en la
memoria. Para acceder a varias subrutinas, podría usar una tabla que muestre
cuáles rutinas ya están cargadas en la memoria y cuáles no. Si no cargamos las
subrutinas cuando el programa empieza por primera vez, quizá jamás se necesite
cargarlas. Si más tarde el programa llama a la rutina, entonces podemos cargarla en
ese instante.
Bibliotecas de enlace dinámico
En este caso la rutina de biblioteca en si no se vuelve parte del programa
ejecutable. Dejamos intacta la referencia simbólica a la rutina de biblioteca que
produjo el compilador. Así como con la carga dinámica, si nunca se hace referencia
a la rutina, entonces no sólo no nos preocupamos por cargarla en la memoria; ni
siquiera vinculamos el símbolo con una dirección lógica. Dejamos las rutinas en
bibliotecas especiales que suelen denominarse bibliotecas de enlace dinámico o
DLL.
Observemos que con este mecanismo se obtienen otros varios beneficios al mismo
tiempo:
● Puesto que las subrutinas no son parte del programa ejecutable, el programa
es más pequeño, de modo que se requiere menos espacio en la unidad de
disco y se cargan más rápido en la RAM.
● Normalmente se tienen muchos programas que usan los mismos módulos de
la biblioteca. Contar con una sola copia de este código puede ahorrar mucho
espacio en el disco.
● Si en uno de los módulos de la biblioteca se ha corregido un error fijo, sólo se
necesita corregir esa biblioteca encaminando y cargándola en el sistema, lo
que corrige automáticamente ese error en todo programa que haga mención
de esa DLL.
Hay un problema con las bibliotecas dinámicas. Cuando el desarrollador de un
paquete de software está usando un conjunto particular de funciones en una
biblioteca de enlace dinámico, su código podría depender también de errores
corregidos en una versión particular de la biblioteca. Este problema se denomina
coloquialmente infierno de las DLL.
Paginación
En lugar de usar el registro base para verificar una dirección, lo utilizamos para
reubicarse. Esto nos permitió la reubicación dinámica. Sin embargo, encontramos
que el hecho de permitir que programas de tamaño variable entren y salgan de la
memoria provocaba fragmentación externa. Desafortunadamente, la compactación
es solo una tarea que hace el SO para que las cosas funcionen mejor en sentido
global.
Finalmente se desarrolló otra solución: dividimos el espacio de la memoria en
bloques de tamaño fijo, y en lugar de asignar a una aplicación todo el espacio que
necesita en un gran segmento, le asignamos una cantidad suficiente de bloques
más pequeños para proporcionarle lo que necesita. Los bloques que asignamos
pueden estar en cualquier parte de la memoria porque solicitamos a la MMU que
reasigne dinámicamente cada bloque por separado. Esta técnica se denomina
paginación.
Dividimos el espacio en direcciones físicas en bloques de tamaño uniforme, que
denominamos marcos
potencia
. El número de bytes en un bloque siempre es una
de 2.
La CPU genera una dirección de la memoria. En general, el programa ignora el
hecho de que la memoria se manipula en páginas separadas. La MMU considera
que la dirección está compuesta por dos partes, mostradas aquí como el número
de página, p , y el
dirección del byte
desplazamiento
, d . El desplazamiento es la
específico dentro del marco. El resto de la dirección lógica es el
número de página.
Tendremos un registro que guarda la dirección de la memoria de la tabla de páginas
para el proceso en ejecución. Se denomina registro de dirección de la tabla de
páginas. La unidad de control de la memoria añade el número de la página
de la dirección lógica que genera el proceso en ejecución en la CPU al valor en el
registro de dirección de la tabla de páginas. El valor almacenado en esa ubicación
de la tabla de páginas es la dirección de reubicación del marco particular al que se
está intentando tener acceso.
Accesos requeridos a la memoria dual
Aunque ya hemos descrito este mecanismo. Para cada referencia a la memoria es
necesario hacer una segunda referencia, a fin de encontrar en la tabla de páginas la
entrada a utilizar como factor de reubicación para esta página.
Nuestra solución es que la unidad de gestión de la memoria guarde en memoria
caché los factores más recientes de reubicación, de modo que podamos usarlos
nuevamente sin necesidad de buscarlos en la memoria. Esto se lleva a cabo con un
dispositivo especial de hardware denominado búfer duplicado de traducción , o
TBL (translation lookside buffer). La esencia de estos circuitos es que
cuando
intentan verificar si ahí hay un número de página, todas las entradas
se buscan en paralelo. Las entradas en el TBL no tienen que mantenerse en ningún
orden.
Control de acceso a la memoria
Cuando teníamos accesos a la memoria principal con un registro de reubicación
para todo el programa también teníamos un registro que prohibía que un proceso
accediera fuera del área de la memoria que tenía asegurada. Con hardware de
paginación se requiere un mecanismo semejante.
Se requieren algunos mecanismos para limitar el acceso a la tabla de páginas. Para
este problema hay dos enfoques. El primer enfoque consiste en usar un tamaño
fijo de tabla de páginas. En este caso se requiere un bit válido en cada
palabra de la tabla de páginas para indicar si una dirección de la tabla de páginas es
correcta. El otro enfoque de control de acceso a la memoria consiste en usar una
tabla de
páginas de tamaño variable. En este caso, se tiene un registro de
longitud de la tabla de páginas. Con un solo rastreo de reubicación se tenía un
registro que especificaba la longitud del proceso en la memoria principal. Es decir,
contiene la dirección del número de página más grande para un proceso. Si una
dirección generada por la CPU contiene un número de página más grande que el
número en el registro de longitud de la tabla de páginas, el hardware genera un
error de interrupción de direccionamiento.
Protección de acceso a páginas
La paginación, permite que el SO restrinja los tipos de acceso posibles a las
diversas páginas. El hardware puede fijarse para sólo permitir acceso de lectura a
una página, o para ejecución.
Tablas de páginas grandes
En máquinas modernas con SO, los programas se están volviendo muy grandes.
Esto significa que las tablas de páginas también son muy grandes. Se ha vuelto
cada vez más difícil gestionar la memoria asignada a las tablas de páginas en sí.
Para tratar con estas grandes y dispersas tablas de páginas se han adoptado varios
enfoques.
La primera técnica consistió en hacer una tabla de páginas multinivel. En una
tabla de páginas de dos niveles (Imagen insertada abajo): esencialmente se
página la tabla de páginas. La MMU considera la dirección lógica generada por la
CPU como si estuviese compuesta por varias partes; en este caso, tres. Tenemos el
desplazamiento de páginas, que será llevado y usado como el marco de
desplazamiento. Consideramos los números de página como p1 y p2; p1 será
utilizado por el hardware para tener acceso al nivel superior de la tabla de páginas.
Los bits restantes del número de página, mostrados como p2, se usan para tener
acceso a la tabla de páginas de segundo nivel seleccionada. Esta entrada es el
número de marco para el número de página representado en la dirección original
por p1 y p2 juntas. Este número de marco se usará con el desplazamiento original
para tener acceso a la ubicación de la memoria deseada en la memoria física.
Tabla de páginas invertida
Un enfoque ligeramente diferente al problema de la memoria externa consistió en
invertir el problema. La idea era asignar lo marcos físicos en páginas lógicas. La
tabla se mantiene en orden a través del número de marco físico. Se busca en la
tabla en sí para encontrar una referencia. Puesto que sólo hay una tabla, los
números de página de los diversos procesos no son suficientes para especificar el
mapeo. El tiempo para buscar una tabla de páginas invertida a menudo es más
lento que para una tabla de páginas normal. El SO puede acelerar esta búsqueda al
usar una función hash o de distribución para tener acceso a la tabla. Dependemos
bastante de la búsqueda en TLB. Las tablas de páginas invertidas requieren mucho
menos RAM que las tablas de páginas normales.
Tablas de páginas con múltiples tamaños de página
En sistemas posteriores se volvió común tener más de un tamaño de tabla de
páginas. La razón de esto es que el núcleo del SO puede mapearse en la tabla de
páginas. La mayor parte de las páginas del núcleo serán las mismas en todo
proceso; nunca mueven de su lugar, causan fragmentación y siempre están ahí, de
modo que no es necesario dividirlas en páginas pequeñas. Algunas veces las
páginas ni siquiera están en la memoria. Este no suele ser el caso con el núcleo. En
consecuencia, tener una sola página para mapear el núcleo es una gran ventaja
puesto que puede fijarse y manipularse más fácilmente y sólo se requiere una
entrada del TLB para mapearlo.
Segmentación
La segmentación sería una pista de desarrollo diseñada principalmente para ayudar
a resolver los mismos problemas que solucionaba la paginación, además de
algunos otros. Esta técnica se denomina segmentación. La segmentación surgió de
la observación de que un programa puede considerarse como si estuviese
compuesto por varias partes. Se tiene una rutina principal y a menudo se cuenta
con subrutinas y funciones que son reconocidas por el compilador como elementos
por separado. Algunas veces se compilan por separado y se colocan en bibliotecas.
Cada una de estas partes puede considerarse independiente de las otras y puede
tener un espacio de direcciones lógicas por separado. Consideramos que el espacio
de dirección está separando en: número de segmento
(s) y un
desplazamiento
(d). Con la segmentación tenemos un número más o
menos pequeño de segmentos, cada uno de los cuales puede ser razonablemente
grande en sí, de modo que el número de segmentos en general es un número más
pequeño de bits y el desplazamiento dentro del segmento es de tamaño más
grande. Normalmente el programador no ejerce ningún control manifiesto sobre la
segmentación. Los compiladores generan segmentos por separado para las
porciones más importantes del módulo que se está compilando, y colocan
referencias simbólicas en los módulos de objeto. El ligador asigna número de
segmentos reales para ser usados cuando se combinan los módulos objeto en el
programa binario ejecutable y para que el SO los use cuando se cargue
dinámicamente módulos de bibliotecas.
La subrutina usará la entrada de la tabla de segmentos especificada por el número
en la parte del segmento de la dirección. Tomará el apuntador que se encuentra en
esa entrada de la tabla de segmentos y lo añadirá a la parte de desplazamiento de
la dirección lógica. Hardware de paginación sustituyó el número de página con un
número de marco.
Puesto que los segmentos son de variable, también pueden ubicarse en cualquier
parte, de modo que para obtener la dirección de la memoria física usamos el
apuntador de la tabla de segmentos más el desplazamiento.. Así, los sistemas con
segmentación también usan TLB para acelerar el acceso. Esta no es una solución
óptima para evitar fragmentación externa. Sigue siendo necesario seguir la pista de
los huecos de la memoria. En consecuencia, se tendrá algo de fragmentación
interna. Pero ahora la variación del tamaño de los huecos es menor que la variación
que se tenía que considerar al seguir la pista de procesos enteros. En
consecuencia, tendremos menos problemas con fragmentación externa.
Puesto que los segmentos son de tamaño variable, es necesario contar con un
mecanismo para que el sistema verifique las direcciones de modo que sea posible
tener la certeza de que el proceso no se está direccionando fuera de los límites del
segmento. Es posible incrementar la protección que se está proporcionando al
sistema al limitar los tipos de accesos que se hacen a los diversos segmentos. Cada
segmento es común tener un conjunto de banderas grandes que controlan los tipos
de accesos que pueden hacerse.
En algunos SO es posible que los procesos compartan segmentos. La gestión de
los número de segmentos a través de múltiples procesos puede ser bastante
engorroso para el SO. Los programadores de lenguajes de alto nivel en general no
está enterados de que un SO está usando segmentación. Los programadores en
lenguaje de nivel bajo deben estar enterados de la segmentación y la forma en que
el SO la usa y pueden controlar la segmentación en caso necesario.
Segmentación con paginación
Hay una diferencia fundamental entre paginación y segmentación. La paginación es
transparente para el proceso en ejecución. Un programa de aplicación que fue
creado para su ejecución en un SO donde el proceso asignado es una gran
partición única puede ejecutarse sin modificación en un sistema que use una
arquitectura de memoria paginada. La segmentación, por otra parte, requiere que de
alguna manera los programas están estructurados de modo que puedan dividirse en
partes lógicas con diferentes espacios de dirección. Con un diseño de hardware
idóneo es posible ejecutar una arquitectura de programa segmentado en
combinación con una arquitectura de memoria paginada.
Hay dos formas en que es posible combinar segmentación y paginación. En el
primer diseño se tiene una tabla de páginas para cada segmento, en lugar de una
sola tabla de páginas para el proceso.
El segundo diseño sigue habiendo una tabla de segmentos pero, en lugar de
apuntar a tablas de páginas separadas para cada segmento, las direcciones en la
tabla de segmentos están dentro de un espacio de dirección lineal, que luego se
mapea a la memoria física de la misma manera en que funciona un sistema
paginado.
La mayor parte de los SO modernos usan este último mecanismo de una u otra
forma aunque limitan el uso de los segmentos. Los segmentos se usan para
restringir el direccionamiento y controlar el acceso.
Paginación por Demanda:
A medida que los programas se ejecutan no requieren tener acceso aleatoria mente
a las direcciones en todo su espacio de direcciones lógicas. A las instrucciones en
el segmento de código se accede secuencialmente, de modo que para alrededor de
mil instrucciones podría accederse a una sola página en la porción del código del
espacio de direcciones lógicas. O bien, el programa podría entrar en un bucle,
algunas veces durante un largo lapso y permanecer en una sola página de código.
Cuando dividimos la ejecución de un programa en pequeñas porciones de tiempo,
normalmente encontramos que el proceso sólo accede a unas cuantas páginas en
cualquier porción de tiempo dada. Este fenómeno es muy importante en el diseño
del SO. Denominado localidad de referencia.
El truco para aprovechar este fenómeno se denomina paginación por demanda
. Se modifica ligeramente el significado del bit válido en la tabla de páginas.
Ahora el bit indica que no hay marco asignado a esta página. Cuando cargamos la
primera página fijamos su bit válido en verdadero para indicar que está en la
memoria. Marcamos el bit válido de cualquier otra página para mostrar que está
página no está en memoria. Luego se inicia la ejecución de un programa. El SO
puede conectarse con el proceso en la memoria y dejar que el mecanismo de fallo
de página traiga incluso la primera página del programa. Esto se denomina carga
perezosa.
Si la referencia es una página que no está en el espacio de direcciones lógicas del
proceso, el programa ha cometido un error y se origina una excepción de
direccionamiento, con lo cual es muy probable que aborte el proceso.
Si la dirección que ha provocado un fallo está en el espacio de direcciones lógicas
del proceso, simplemente la página no se ha asignado en la memoria física, ya sea
porque nunca ha sido llevada a ésta o porque ha sido sacada de ahí. Esta condición
se denomina fallo de página
.
EAT con Paginación por Demanda:
Consideremos lo que ocurre cuando tenemos acceso a una página que no está en
la memoria. Nuestro tiempo de acceso efectivo consta de cuatro componentes.
La tabla E/S del disco rebasa ampliamente las velocidades de la memoria. Esta
dominación conduce a varios mecanismos que parecen complicados que se han
desarrollado simplemente para evitar efectuar una operación de E/S en un sólo
disco para paginación por demanda.
El conjunto de trabajo y reemplazo de página:
A medida que se ejecuta un programa, este hace referencia a algún conjunto de
páginas, este grupo al que hace referencia un proceso en un breve lapso se
denomina conjunto de trabajo . Este conjunto se lo mide sobre un intervalo fijo
denominado ventana deslizante
proceso tiene
. Resulta normal encontrar que un
varias páginas en la memoria a las que ya no hace referencia.
Lo que sería lógico es identificar esas páginas y eliminarlas de la memoria una vez
que ya no sean necesarias. Desafortunadamente, el no haber referenciado alguna
página durante un tiempo no significa que la siguiente instrucción no lo haga. Por
suerte, eliminar una página que será necesaria más tarde no causa ningún
problema, sólo que no es eficiente, la siguiente referencia a la página originaria un
fallo de página , de modo que la buscaría de nuevo.
Existe una estrategia de reemplazo muy simple:
1. FIFO ( primera en entrar, primera en salir
): El SO mantiene una cola con
los números de páginas de acuerdo a cómo estas van entrando para cada
proceso y simplemente se expulsa la más antigua. El algoritmo es de baja
sobrecarga (poca carga de parte del SO), es barato y fácil de comprender e
implementar.
2. Algoritmo de reemplazo de página óptimo: Cuando es necesario
reemplazar una página, el SO sustituye la página cuyo uso siguiente será el
más alejado en el futuro. Imposible de implementar ya que necesita saberse
si una página será usada en un futuro.
3. Página menos usada recientemente: Se establece la hipótesis de cual
pagina es la que tiene mayor probabilidad de no ser usada nuevamente, de
modo que se la quita.
4. Algoritmo del reloj: Es el más sencillo, el hardware puede asegurar cuando
se hace referencia a una página, en una entrada de la tabla de páginas se
establece un bit, denominado bit de referencia a la página
de acceso
o
bit
o bit de uso , el hardware verifica ese bit. Si ya está
establecido, no se hace
nada. Caso contrario es encendido. El SO puede
limpiar estos bits para las páginas que están actualmente en memoria.
El hardware enciende a los bits para todas las páginas a las que se está haciendo
referencia. Cuando se requiere hacer una página se busca en la tabla y si se
encuentra una página con un bit válido encendido y un bit de referencia que se
limpia, podrá ser reemplazado.
Paginas sucias:
Cuando una parte de un programa se carga en una página y se sustituye por otra
cosa, no es necesario guardarlo, porque es posible volver al programa original y
obtener la página se de nuevo se hace referencia a ella. Sin embargo, si una página
contiene datos y se ha modificado parte del contenido, entonces no es posible
reemplazarla.
Las páginas que han sido modificadas se denominan páginas sucias
se
, las cuales
escriben en un sitio especial del almacenamiento secundario, denominado
archivo
de intercambio (swap) o almacenamiento de respaldo
(backing
store). En
consecuencia, este archivo de intercambio actúa como una extensión
de la memoria primaria del sistema, dando origen a la expresión memoria virtual
.
Más algoritmos de reemplazo de páginas:
1- Algoritmo de segunda oportunidad: Modificación del algoritmo de reloj,
busca a través de la tabla de páginas, si el bit de referencia está establecido,
entonces lo limpia. Actualiza los bits de referencia. A medida que se desplaza
a través de la tabla, si no encuentra ninguna que esté libre en la primera
revisión, encuentra algo en la segunda.
Las operación de fondo
no
son tareas que se efectúan cuando en el estado de listo
hay procesos de alta prioridad. Así, las instrucciones que se ejecutan en una
tarea de fondo no lo hacen a costa del proceso de cualquier usuario, de modo que
son más o menos libres.
4. Algoritmo no utilizado recientemente (NRU) o Algoritmo no utilizado
(NUR): Las páginas se dividen en cuatro clases según las posiciones de
estos dos bits:
4.3Limpio y sin referencia
4.4Sucio pero sin referencia
4.5Limpio pero con referencia
4.6Sucio con referencia
En la primera clase se busca encontrar páginas sin referencia y limpia para poder
usarse de inmediato. Si no se encuentra, vuelve a buscarse de nuevo en la clase
dos y así sucesivamente.
Cuantas paginas por cada proceso?
Podemos estudiar programas en ejecución en un sistema prototipo y fijar algún
límite arbitrario. Pero si no se cuenta con los suficiente procesos en ejecución para
llenar con páginas toda la memoria, se producen fallos de páginas cuando no se las
desea. Por lo que no es buena idea. Es posible hacer que el sistema sea un poco
más dinámico.
1- Asignación equitativa: Dividir el número de páginas disponibles entre el
número de procesos en ejecución.
2- Asignación proporcional: Deducir que programas puedan utilizar más
páginas comparar sus tamaños.
Balance automático del límite de páginas:
La mayor parte de los SO usan este mecanismo. Alguno de estos son variantes del
algoritmo de la frecuencia de fallo de página y depende de la ide de que la tasa
de fallo de un proceso es un buen indicador de si se tiene el número correcto
de páginas. Si hay muy pocas páginas, la tasa de fallo de página aumenta
rápidamente. Si no se está generando ningún fallo, también puede tener páginas en
la RAM que no se utilicen. Este mecanismo establece un límite superior y un límite
inferior para la tasa de fallo.
Este mecanismo tiende a mantener a todos los procesos del sistema que están
ejecutándose a una tasa de fallos de página semejantes y sólo asigna tantos
marcos a un proceso como sea necesario para permanecer en ese intervalo.
Hiperpaginación:
La hiperpaginación
es un fallo generado por la sustitución de páginas en un
proceso ya asignado dando como consecuencia poco trabajo real y
reflejando en el sistema una excesiva cantidad de E/S en el disco. Si la suma de los
conjuntos de trabajo de todos los procesos en ejecución es mayor que la memoria
principal real, todo el sistema dedica más tiempo reemplazando páginas que el que
dedica para la ejecución de procesos y entonces se dice que el sistema está
efectuando hiperpaginación.
Bloqueo de Página:
Un SO que está haciendo paginación por demanda debe permitir que una aplicación
asegure una página de modo que el mecanismo de paginación no la seleccione.
Mecanismos de página limpia:
Para el reemplazo resulta importante usar una página limpia, en lugar de una sucia,
para que ésta no tenga que ser escrita en el archivo de intercambio.
Podemos reducir el impacto de usar una página sucia al mantener disponible para
su uso un grupo de marcos libres que estén limpios. Cuando el algoritmo de
reemplazo de página selecciona una página sucia para esta acción, el SO puede
usar uno de los marcos limpios del grupo de marcos disponibles. Luego, en el
fondo, el contenido de la página sucia suele escribirse fuera del disco. Cuando la
página está limpia, el marco puede colocarse en el grupo de marcos disponibles.
Otra tarea que es posible efectuar en el fondo es limpiar páginas que estén sucias.
Temas Especiales de Gestión de la Memoria
Distribución de la Memoria entre Procesos:
Tanto la paginación como la segmentación permiten que porciones de la memoria
sean compartidas entre procesos. Con esto se pueden lograr grandes ahorros de la
memoria.
El mecanismo copiar al escribir
dirección
consiste en compartir todo el espacio de
física entre dos procesos, pero a medida que se ejecutan, los cambios
hechos por un proceso no son vistos por el otro.
Archivos Mapeados en Memoria:
La mayor parte de los SO modernos permiten un modo especial de distribución de la
memoria denominado archivos mapeados en memoria
proceso
. En este modo un
solicita al SO abrir un archivo y asociar todos los datos o parte de ellos
en el archivo con una región del espacio de direcciones lógicas del proceso. Luego,
el proceso puede referir la información en ese espacio como un arreglo o a través
de apuntadores de memoria. Este sistema cuenta con dos ventajas principales. La
primera es que el proceso no tiene que usar declaraciones de E/S para tener
acceso a los datos; el sistema de paginación por demanda se hace cargo de tener
acceso a los datos idóneos desde el archivo. La segunda ventaja es que dos o más
procesos pueden pedir al SO acceso al mismo archivo al mismo tiempo. Los
mismos marcos de la memoria se asignan a los espacios de direcciones lógicas de
ambos procesos, permitiéndoles compartir el acceso a la memoria.
Mac OS:
Gestión de Archivos:
System 1:
Los programas se guardaban en disquete y cargados en la RAM cuando iban a
ejecutarse. Aunque los archivos se guardaban en un directorio único, existían
carpetas virtuales, donde cada archivo podría marcarse con el nombre de
una carpeta. System 3:
Se implementó un Sistema de Archivos Jerárquico
(HFS) reemplazando el
MFS, permitió aumentar cualquier número de sectores que fueran potencia
de dos. Permitiendo mayor almacenamiento, pero se podía desperdiciar mucha
memoria.
Entradas: guardaba metadatos como cuando se creó, quien, etc. Los nombres de
archivos eran hasta 32 caracteres.
System 8:
Utilizaba una versión del Sistema de Archivos Jerárquico Plus
(HFS+),
usaba un apuntador de 32 bits y era capaz de direccionar directamente a
una unidad de disco de 4GB, utilizando un bloque de asignación de 32
sectores.
Gestión de Procesamiento:
System 1:
➔ Tareas únicas: al tener que ser asequible económicamente para los
usuarios, estas deberían correr con una memoria muy limitada, por esto se
tuvo que renunciar a la multitarea. Aunque las ventanas no ocupaban toda
la pantalla, no se podía ejecutar más de una aplicación a la vez, no para
impresión a fondo.
System 2:
➔ Multitarea Virtual:
◆ Swicher creó varias ranuras fijas en
la RAM (donde se cargaban las
aplicaciones). Asigna un montículo
separado para cada para aplicacion
que inicie.
◆ Switcher realiza una interrupción de
contexto para que los SO pueda
empezar a trabajar con la nueva
aplicación (multitarea muy limitada).
System 4:
➔ Multifinder:
◆ Permite ejecutar más de una aplicación a la vez, el usuario puede
elegir entre Multifinder y Finder.
◆ A diferencia del Switcher, este permite que cada programa
continuará su ejecución, dando a cada uno tiempo de la CPU.
◆ Multitarea Cooperativa: un proceso se podía ejecutar todo el
tiempo que quisiera hasta que haga una petición al SO. Si
necesitaba un recurso pasaba a la lista de [Bloqueados], estos
hacen a menudo una llamada especial para ceder la CPU (pero aun
no termino su proceso), pasando a [Listos].
System 7:
➔ CPU:
◆ Debido a que empezaron a utilizar PowerPC, requirió cambios en
el diseño del SO, pasó de utilizar una arquitectura CISC a RISC, lo
que requería menos electrónica, el conjunto de instrucciones son
sencillas pero se requieren mayor cantidad de instrucciones. ◆ Una
parte del código emulaba un nanonucleo gestionado por la CPU,
este se ejecutaba en modo supervisor, proporcionando una interfaz
de bajo nivel para gestionar el hardware. Este iniciaba un emulador
68000 cuando iniciaba el sistema, emulando sólo una instrucción de
usuario del 68000 sin emular la MMU, permitiendo mayor
compatibilidad.
◆ Los programas se podian compilar en módulos ejecutables tanto en
código nativo 68000 como en código PowerPC, a estos se los
denominaba Binarios Gruesos. El intercambio entre ambos
módulos se llevaba a cabo mediante un conjunto de rutinas de
bibliotecas denominado Gestor de fragmentación de código.
System 8:
➔ Procesador:
◆ Una aplicación podia usar mas de una CPU, debido a que se
introdujo la idea de permitir que una aplicación se dividiera en
múltiples hilos independientes (tareas en Mac OS). Para esto se
modificó el nanonucleo para hacer posible el multihilo.
◆ Ahora existen prioridades asociadas a tareas, esto permite que el
SO pudiera diseñar tareas como más importantes que otras.
◆ Contaban con multiples CPU, por lo tanto realmente dos programas
corrían al mismo tiempo. El SO lo soportaba gracias al sistema de
Multiprocesamiento simétrico, en la cual el SO se ejecutaba en
cualquier CPU disponible.
Gestion de Memoria:
System 1:
➔ Memoria:
◆ Tenía una arquitectura plana (espacio de direccionamiento
único), donde en cualquier instante, cualquier instrucción puede
hacer referencia directamente a la memoria.
◆ La CPU 68000 tenia direcciones de 24 bits, no había protección de
la memoria, por lo cual cualquier programa puede modificar
cualquier cosa de ella, incluyendo el SO (modo supervisor
).
◆ A5word tenía un tamaño fijo y contenía los datos estáticos de la
aplicación y algún metadato de ella. El SO carga el registro A5
de la CPU con un apuntador hacia ella de modo que la aplicación
se abría dónde están sus datos.
◆ Para el tamaño del montículo, establece un límite superior cuando
empieza la aplicación, este es controlado por la rutina de
asignación de memoria para controlar el límite. Pero la pila es
controlada por el hardware y debido a que la subrutina y funciones
se llaman y regresan, a la pila se la introduce y extrae datos (no
hay protección de hardware contra la expansión del mismo). Una
vez que la aplicación terminaba, se borra su monticulo.
◆ Un subsistema Stack Sniffer se ejecutaba durante el intervalo
de trazado vertical del monitor (60 veces por segundo),
comprobando el nivel de la pila contra el límite.
◆ Para evitar la fragmentación de la memoria administra bloques
de memoria reasignables, accediendo a estos indirectamente
por medio de un bloque del apuntador maestro . Eran de 24 bits
para el direccionamiento y 8 superiores para banderas
(“bloqueado”, “purgable” o “recurso”). Foto
➔ ROM:
◆ Además de contener la BIOS y el código POST, contenia gran parte
del SO. Principalmente para evitar llenar el almacenamiento
disponible en un disquete, para que el SO cargue más rápido y
además que los clones puedan ejecutar Mac OS.
System 4:
➔ Memoria:
◆ Con Multifinder las aplicaciones pueden comunicar sus
requerimientos de memoria al SO según sus necesidades (a veces
no era suficiente para algunas tareas). El usuario podrá cambiar
este número.
◆ Si un programa corría bajo el único Finder , debía trabajar sin
cambio bajo Multifinder
es bastante semejante.
, ya que la arquitectura de la memoria
System 6:
➔ Memoria:
◆ Maneja el direccionamiento verdadero de 32 bits, debido a la
aparición de la CPU 68020 de Motorolla.
◆ Mantiene compatibilidad para ejecutar aplicaciones de 24 bits.
System 7:
➔ Memoria Virtual:
◆ Es una técnica que utiliza parte del disco duro como para simular
memoria primaria más grande, utilizando cuando se requiere más
memoria de la que posee.
◆ Cuando un programa inicia su ejecución, sólo la primera pagina
(división de bloques de la memoria) se lleva a la RAM.
Cuando hace referencia a una parte que no está en memoria,
como el hardware, provoca una interrupción llamada “fallo de
página
”, y
el SO lee la página faltante del disco y la carga
en memoria.
◆ La computadora debe tener una unidad de gestión de memoria
especial, para traducir las
generadas por el
direcciones lógicas
programa en ejecución en la CPU y
traducirlas en una dirección física.
Gestion de E/S:
System 1:
➔ GUI:
◆ Tenía una zona de escritorio, ventanas, iconos, ratón, menús y
barra de desplazamiento. Este era muy limitado pero se trataba de
una GUI, siendo más amigable que la consola. Las ventanas eran
dibujadas por el SO, lo que facilitaba la adecuación a un nuevo
programa.
System 2:
◆ Finder más rapido.
escoger
Choose Printer
, permite al usuario
una impresora.
➔ GUI:
◆ Switcher, permite al usuario iniciar varios programas.
◆ Los programas en ejecución “tenían foco” (asi se podia cortar y
pegar entre aplicaciones).
◆ Los disquete pueden ser expulsados al arrastrarlo a la papelera.
System 3:
➔ Redes:
◆ Chooser gana importancia gracias al soporte de AppleShare :
protocolo para compartir archivos, AppleTalk
: la capa de redes
y LocalTalk: cada de enlace de datos y física.
System 4:
◆ Soporte para unidades de disco mayores a 32MB.
➔ GUI:
◆ Coexistencia entre ventanas de distintas aplicaciones, cada
aplicación podría tener múltiples ventanas.
◆ Al tener foco, todas sus ventanas pasaban a la primer capa por
tema de compatibilidad con ventanas API existentes.
System 7:
◆ Desapareció el Finder. La multitarea cooperativa sería el modo
normal de trabajar.
➔ GUI:
◆ Mejora en cuanto a la usabilidad y en el área de la GUI. Permite
arrastrar texto de una aplicación a otra.
➔ E/S:
◆ Se introdujo PC Exchange
, un software que permite acceder a
disquetes con formato MS-DOS . Aunque eran físicamente
idénticos, no se podían leer ya que el formato de bajo nivel eran
distintos.
◆ El principal bus del sistema se denominaba NUBUS
, ya que
estaba registrado, sólo Apple podría ejercer el control de la
firma sobre todo el desarrollo del hardware.
◆ Las ranuras para PC Card
permitían la inserción de un
dispositivo que no estaba integrado originalmente en una laptop.
◆ Esta versión era demasiado grande para caber un disquete de
1.44MB, por lo que se necesitaba un disco duro.
System 8:
Agregó soporte para una nueva clases de dispositivos como USB y FireWire.
Descargar