Sistemas Operativos
Les ofrecemos aquí un white paper que estudia los conceptos fundamentales que los componen, dejando para otra oportunidad la historia de su desarrollo, los distintos sistemas de la actualidad como ser Windows, Linux, Solaris, Mac OS X, etc. También dejaremos afuera por esta vez los sistemas distribuidos y de redes.
Los temas expuestos serán los procesos de los sistemas operativos, la administración de memoria, sistema de E/S y sistema de archivos.
Este apunte fue enviado por su autor en formato DOC (Word).
Para poder visualizarlo correctamente (con imágenes, tablas, etc) haga click aquí o aquí si desea abrirla en ventana nueva.
Indice
Introducción
.................... .. 1
Procesos
........................ .. 3
Administración
de la memoria .... .. 11
Sistemas
de E/S ................. .. 16
Sistema
de archivos ............. .. 20
Bibliografía
.................... .. 22
Introducción
En esta oportunidad vamos a enfocar nuestra atención en los sistemas
operativos. Les ofrecemos aquí un white paper que estudia los conceptos
fundamentales que los componen, dejando para otra oportunidad la historia de su
desarrollo, los distintos sistemas de la actualidad como ser Windows, Linux,
Solaris, Mac OS X, etc. También dejaremos afuera por esta vez los sistemas
distribuidos y de redes.
Los temas expuestos serán los procesos de los sistemas operativos, la administración de memoria, sistema
de E/S y sistema de archivos.
Pág. 1
Un sistema operativo es un programa o conjunto de programas que
permiten la utilización eficaz de los recursos hardware. Los sistemas
operativos hacen la conexión entre las
aplicaciones y el hardware, de modo que éstas en general se limitan a usar
funciones provistas por el sistema.
Las
operaciones básicas que se pueden hacer dentro de un sistema operativo son:
•
abrir y cerrar: archivos o directorios
•
crear y borrar: archivos o directorios
•
buscar
•
cambiar nombre
•
copiar, cortar y pegar
•
ejecutar: programa o script
•
formatear: unidades de almacenamiento
•
Entre otras opciones más recientes no tan
básicas tenemos:
•
comprimir - descomprimir: archivos o directorios
•
desfragmentar: unidad de almacenamiento
•
comprobar disco: de errores
•
copia de seguridad
•
restaurar sistema
Los
sistemas operativos se pueden clasificar de muchas maneras, de acuerdo a las
características o maneras de operar que tengan:
• según
la administración de las tareas
○ S O monotarea s: sólo pueden ejecutar una tarea
por vez,
es decir que no son concurrentes. Son los más antiguos y es difícil ver
sistemas modernos monotareas.
○ S O multitarea s: pueden ejecutar varias tareas simultáneamente (o cuasi-simultáneamente), aprovechando los tiempos ociosos
de la CPU. Alternan entre varias tareas, las
que se procesan en partes durante pequeños intervalos de tiempo
(quantums).
• Según
la cantidad de usuarios
○ S O monousuarios : admiten un solo usuario por vez.
○ S O multiusuario : permiten varios usuarios
compartiendo recursos al mismo tiempo. Necesitan dar protección a cada uno (restringiendo accesos, con
claves, con permisos, etc.)
• según
la administración de recursos
○ S O centralizados : se ocupan
los recursos de una sóla
máquina, como ser CPU, memoria, disco, etc.
○ S O de red : permiten compartir datos, dispositivos de E/S. Reduce costos para el trabajo en
equipos.
Pág. 2
Es la opción elegida en los sistemas operativos modernos. ○ S O distribuidos : constituyen una generalización
del
anterior, ya que se comparten recursos y distribuyen los procesos del sistema
entre varios nodos (computadoras). Este tipo de SO son más difíciles de
implementar y necesitan un estudio especial, que trataremos en algún futuro
white paper (manténgase actualizados en www.peiper.com.ar!). Deben contemplar fallos en la
red, problemas de sincronización, diferente hardware en cada nodo, atomicidad,
etc.
Procesos
Una de las tareas fundamentales de los
sistemas operativos
es la administración y planificación de la ejecución de
los procesos. Estos son parte fundamental de
todo sistema,
y básicamente son programas que procesan y devuelven
datos.
Los procesos para funcionar necesitan muchos
recursos: una
recursos de E/S y a veces también servicios
de red.
Hay 2 tipos principales de procesos: procesos
de usuario y
procesos de sistema. El 1ro se ejecuta en modo usuario, y
el segundo en modo supervisor.
Los procesos son (o deberían serlo) internos
del sistema y
transparentes al usuario, de modo que se le
simplifique el
trabajo a éste.
Pero nos podemos preguntar cuál es la necesidad de usar
procesos. ¿Por qué el sistema operativo no es un solo
programa que invoque subprogramas? Las razones para
usarlos radican en
?
simplicidad: para
permitir una estructura modular que facilita la comprensión.
?
velocidad: al tener un
conjunto de procesos estos se pueden ejecutar de manera concurrente y planificar para mejorar
el uso de los recursos.
■ seguridad: para
permitir o no su ejecución y limitar el uso de
los recursos que cada uno hace.
PCB y SCB
Cada proceso se representa en el sistema operativo a través de un PCB
(bloque de control de proceso). Un PCB mantiene información del proceso, de
su estado actual y datos y variables que sirven al sistema operativo para
planificarlos (por ej. prioridad).
Los objetivos del uso de PCBs son almacenar
información de cada proceso que sirve para la planificación que hace el sistema
operativo, para ejecutar cada proceso de una manera correcta, y en general para
almacenar la información de cada proceso que usará el sistema operativo. La
información de un PCB es:
· puntero: locación del proceso en memoria.
· estado del proceso: hay 5 estados básicos.
Pág. 3
· número del
proceso: process id. Sirve para
identificarlo dentro del sistema.
· contador de
programa: la posición actual por donde
va la ejecución.
· datos
de pila
· registros:
usados por el proceso
· variables
· prioridad
· lista
de archivos abiertos
· código
(instrucciones)
Por otra parte, los sistemas operativos disponen de
estructuras para vincular los PCBs, llamadas “bloques de
control del sistema (SCB)”.
Un SCB es similar al PCB pero lo utiliza el sistema
operativo para enlazar los PCB residentes en memoria
principal. Los SCBs contienen PCBs.
Su información es: excepciones, interrupciones, fallos de
CPU, PCB, reloj y consola.
Ejecución de los procesos
Un sistema operativo puede usar alguno de 3 tipos de ejecución, de
acuerdo a los requerimientos del sistema y al ambiente en el que se lo usará.
Cada una de estas clasificación supone una evolución de la anterior, siendo la
más aceptada actualmente el “tiempo compartido”. En orden de aparición tenemos:
· Ejecuciónsecuencial: es característica de los
sistemas por lotes, los más antiguos. Se ejecuta
sólo un proceso a la vez, y no se conmuta a otro
hasta que termina su procesamiento. Maneja la
técnica llamada spooling, que usa buffers para
realizar E/S. Esta técnica de ejecución supone un
derroche de recursos, sobre todo
actualmente que el
hardware comienza a tener una orientación
“masivamente paralela”, con procesadores multi-
núcleo, discos en RAID, placas de video en SLI o
CrossFire, etc.
· Multiprogramación: Permite organizar la ejecución de
los trabajos a fin de mejorar el aprovechamiento de
la CPU. Por ejemplo, al solicitar un trabajo E/S,
mientras ésta se realiza se selecciona otro trabajo
para ejecutarlo.
· Tiempocompartido: Es una extensión de la
multiprogramación. En ésta la ejecución de los
procesos se realiza alternadamente,
conmutando entre
varios procesos. Se ejecuta un proceso durante un
intervalo de tiempo (llamado quantum) y aunque no
haya terminado, al finalizar el quantum se pasa a
ejecutar otro.
Estados de los procesos
Hoy en día la mayoría de los sistemas
operativos manejan los procesos de manera concurrente a través de la multiprogramación.
Este significa que en un intervalo de tiempo
dado el sistema es capaz de atender y dar espacio de ejecución a 2 o más
procesos. Para esto se utilizan distintos algoritmos y estructuras de datos
para organizarlos según su estado.
Pág. 4
Para la planificación y organización de los procesos las estructuras
más comúnmente usadas son las colas, que organizan a los procesos según su
estado. Tenemos:
· coladeprocesoslistos: contiene los procesos que
están listos para ejecutarse y que compiten por la
CPU.
· coladesuspendidolisto: aquí están los procesos
que terminaron su ejecución y no están
compitiendo
por la CPU.
· coladeenesperaobloqueado: contiene los procesos
que están en estado de espera por causa de E/S.
· coladesuspendidobloqueado: los procesos que se
interrumpe
su ejecución.
Planificación
El sistema operativo es el encargado de
conmutar el uso de la CPU con los diferentes procesos. El estado ideal sería tener un
procesador por cada proceso, pero esto es muy poco flexible y conlleva un alto
costo. Entonces, ya que la mayoría de las computadoras poseen un solo
procesador es necesario compartirlo, cambiando de un proceso a otro conmutando
el contexto. La conmutación de contexto es una tarea por lo general costosa en términos de utilización de recursos
y tiempos necesarios, y de ser excesiva el sistema podría pasarse conmutando
sin realizar procesamiento productivo. Por eso, la estructura y técnicas de un
sistema operativo están muy relacionadas con el hardware sobre el que correrá.
Los objetivos de la planificación son:
· equidad
y justicia
· mejorar
los tiempos de respuesta y retorno
· minimizar
los tiempos de espera
· maximizar
la productividad
Para regular el grado de multiprogramación
(la cantidad de procesos que están en memoria principal) se usa el planificador a largo plazo, que es el encargado de escoger procesos
en almacenamiento masivo y traerlos a memoria principal. Este planificador tiene
una frecuencia de ejecución baja, alrededor
de una vez cada 100 milisegundos (aunque depende mucho del sistema
operativo). No es común su uso en sistemas de tiempo compartido.
Por otra parte tenemos el planificador a corto plazo,
que se ejecuta mucho más frecuentemente. Su tarea es seleccionar procesos de la
cola de procesos listos y asignarles la CPU. Su ejecución debe ser concisa y
rápida debido a su frecuente uso.
Hay otro nivel de planificador que se puede encontrar más en los
sistemas de tiempo compartido, y es el planificador a mediano plazo.
Este selecciona procesos que no se están ejecutando, los coloca en memoria
virtual (swaping o intercambio) y en el
momento necesario los trae nuevamente a memoria principal. La diferencia
con el planificador a largo plazo es que éste selecciona procesos que están en
ejecución (pero esperando por el procesador en cola de listos, en espera o
bloqueados).
Operaciones con procesos
Los procesos se pueden crear, destruir, suspender, reanudar, cambiar
su prioridad y temporizar su ejecución (quantum). En general todas estas
acciones las realiza el sistema operativo
automáticamente, aunque en algunos casos
Pág. 5
particulares puede ser necesaria la
intervención del usuario.
Jerarquía de procesos: padres e hijos
Tenemos 2 tipos de procesos: procesos padres y procesos
hijos.
Los procesos padres son aquellos que invocan la ejecución
de otros procesos, que reciben el nombre de hijos. Los
procesos hijos pueden ocupar recursos de 2 maneras
distintas: del sistema o de los recursos que tiene
asignados su padre.
Tipos de procesos
Los procesos se
clasifican de varias maneras.
· Según el código ejecutable:
o reutilizables: pueden ser usados por varios programas de manera simultánea. Manejan datos compartidos.
En cada llamada empiezan a ejecutarse desde el principio.
o reentrantes: se mantiene una sola imagen cargada en el
sistema.
· De acuerdo al uso del procesador y los
recursos:
o apropiativos: no sueltan la CPU hasta que terminan su procesamiento. No son para nada deseables
estos tipos de procesos porque quitan capacidad de control al sistema
operativo.
o noapropiativos: permiten al sistema operativo
administrarles la CPU.
· De
acuerdo a la forma de ejecución:
o residentes: se ubican sólo en memoria principal.
Puede ser conveniente que los procesos del sistema más utilizados sean residentes, a fin de mejorar la performance general.
o intercambiables: pueden encontrarse tanto en memoria principal
como en virtual.
Procesos cooperativos e independientes
Los procesos independientes son aquellos que no comparten recursos y que no dependen de otros procesos
externos para proveerse de información. Es decir, que funcionan de
manera independiente.
Los procesos cooperativos son más difíciles
de implementar
y su organización en el sistema es más compleja, pero
permiten proveerse de datos entre ellos, comparten
recursos tales como E/S, memoria principal, etc.
Las razones principales de su uso son para compartir
información, para acelerar los cálculos, para usar la
modularidad y por comodidad para el usuario.
Una desventaja posible es que en error en uno de ellos
puede repercutir en sus procesos dependientes, provocando
cuelgues o inestabilidades.
Otro de sus problemas es conocido como problema de los
productores - consumidores: un proceso
consume información
provista por un proceso productor. ¿Pero qué pasa si el
proceso productor produce más despacio que lo que consume
el consumidor? ¿O si es al revés? Para solucionar este
problema se introduce el uso de buffers. Estos pueden ser
de 2 formas, limitados o ilimitados.
Puede ser necesario que en vez de 1 buffer
debamos usar 2.
Así, el proceso productor rellena el buffer
1, cuando está
Pág. 6
lleno lo pasa a consumir el proceso consumidor. Pero mientras ocurre ésto no es conveniente que el
productor sobrescriba el mismo buffer 1. En vez de ello, el productor
comienza a escribir en el buffer 2. Y de esta forma se van alternando ambos
buffers.
Comunicación entre procesos
Los procesos cooperativos o padres e hijos deben tener la
capacidad de comunicarse.
Se pueden usar buffers por un lado, y por el otro
mensajes.
En el caso de los mensajes disponemos de dos mecanismos:
· comunicacióndirecta: se envía un mensaje de un
proceso a otro cuyos parámetros son nombre de
proceso y mensaje. Su sintaxis es:
enviar(procesoP,mensaje) y
recibir(procesoQ,mensaje)
· Comunicaciónindirecta: el mensaje se envía a un
buzón
de mensajes. La sintaxis es:
enviar(buzón,mensaje) y
recibir(buzón,mensaje). Cada proceso tiene un buzón propio y este se puede
implementar a través de un buffer, que puede ser de
capacidad cero, capacidad
limitada, o capacidad ilimitada.
En todos los casos el sistema operativo o el
subsistema de comunicación entre procesos (IPC) deben asegurar la consistencia y la
correctitud de los mensajes. Para esto se pueden implementar sumas de
verificación (checksum) o similares.
Excepciones
El sistema operativo debe contar con un gestor de excepciones a fin de
tratar los eventos anómalos que se pueden producir durante la ejecución de los
procesos. Al producirse una de éstas se puede abortar la ejecución del proceso
o se la puede tratar y luego continuar con la ejecución.
Los tipos
de excepciones son fallos de hardware, fallos de software, entrada de datos
incorrectos o eventos anómalos (como resultados inesperados. ej: división por
cero). Según la gravedad de cada excepción, éstas pueden ser catastróficas (ej:
fallo en el suministro eléctrico), irrecuperables (desborde de pila) o
recuperables (ej: desborde de arreglo).
Concurrencia
La concurrencia de procesos es una situación deseada en un sistema operativo, pero no es gratis
porque además de agregar complejidad al sistema causa diversos problemas:
· inanición :
cuando se
posterga la
ejecución de un
proceso indefinidamente.
· bloqueomutuo(esperacircular): cuando se forma una
cadena en la que un proceso A tiene los recursos que
Pág. 7
necesita B, y el proceso B tiene los recursos
que necesita
el A.
· condicióndecarrera : 2 o más procesos compiten por
el uso
de la CPU y los recursos. El primero que
llegue será el beneficiado. Se debe manejar esta
situación para lograr “justicia” en la ejecución.
· condicióndeexclusiónmutua: Cuando un proceso usa
un
recurso del sistema y no se debe ni puede
interrumpir para mantener la consistencia de los
datos. A la parte del código que usa los
recursos se
le llama sección crítica.
· condicióndeapropiaciónderecursos: hay procesos
que se
pueden apropiar de algunos recursos
indefinidamente o por un largo tiempo. Ocurre a
menudo con procesos apropiativos. Esto también se
debe gestionar y solucionar.
· condicióndeesperaactiva : cuando un proceso ocupa
ciclos de CPU sólo esperando la liberación de algún
recurso. Provoca un uso ineficiente de los recursos
y se
debe evitar a toda costa. Relacionada con el
DMA (acceso directo a memoria) y con las
interrupciones.
H ilo s
Los hilos son procesos ligeros que se componen de
registros, un espacio de pila y un contador de programa.
Los hilos comparten su código ejecutable, su pila y los
recursos que utiliza. Con el uso de hilos deja de ser
necesaria la costosa conmutación de contexto
de uno a otro
proceso.
Los hilos son especiales para realizar procesamiento
paralelo, pero esto incurre en algunos problemas como la
consistencia de datos, para lo que se usan distintos
mecanismos para solucionarlos como secciones críticas y
cerraduras.
Los hilos pueden estar a nivel del núcleo del sistema
operativo o a nivel de usuario.
· Hilosanivelusuario: su ventaja es que tienen
mejor desempeño porque no se deben hacer
llamadas al
núcleo. Su desventaja es que el bloqueo de un hilo
produce el bloqueo del resto de los hilos de la
tarea.
· Hilosaniveldelnúcleo: Su ventaja es que el
bloqueo de uno de ellos no afecta al resto. Su
desventaja es que la conmutación de un hilo
a otro
se hace mediante interrupciones, que producen
sobrecarga.
Dos ejemplos de uso intensivo de hilos son el sistema operativo de tiempo real Solaris 2; y el lenguaje
Java, ambos de Sun Microsystems.
Sincronización
Al haber procesos concurrentes se deben
emplear mecanismos para asegurar la consistencia de los datos. Como ejemplo, supongamos que tenemos 3 procesos concurrentes
que quieren modificar un mismo archivo. Si los 3 acceden a este al mismo
tiempo el archivo quedará con valores incorrectos. Para resolver problemas como
este se ideó la sección crítica, que es el segmento de código que accede
a los recursos. Sólo puede haber una sección crítica en ejecución por vez, así nos aseguramos que los datos quedan consistentes.
Pág. 8
espera
que deseados
desuso.
Se compone de “espera con mutex”,
y “algoritmo de Dekker”.
Los mecanismos para manejar la sincronización se
clasifican en 2 grandes grupos, espera activa y
inactiva.
El
enfoque de espera activa se basa en procesos
consumen
tiempo mientras esperan, son los menos
han
quedado en
“alternancia”,
y
Los mecanismos de espera inactiva no mientras esperan. Se
clasifican en:
consumen
recursos
Semáforo: Un semáforo es un mutex con espera inactiva
que tiene 2 operaciones, señal(entero) y espera(entero). Se implementa como una
estructura que contiene un número entero y una lista de procesos. La
operación espera(entero) agrega un proceso en la lista del semáforo, mientras
que señal(entero) selecciona un proceso de
esta lista para ejecutar.
Ejemplos:
proceso1 ( ) { espera(2)
.
.....
señal(2) } proceso2 ( ) {
espera(1)
.
.....
señal(1) }
· Monitores: Están caracterizados por un conjunto de
procedimientos (que se declaran dentro de un
monitor). Sólo se puede ejecutar un procedimiento a
la vez de los están declarados en éste. Así se
asegura que no habrá 2 procedimientos
utilizando los
mismos recursos.
· Rendez-vous: Es similar a los monitores pero en vez
de ser la llamada a un procedimiento, es a un
conjunto de sentencias dentro de éste.
· Contadordeeventos: Se usan variables enteras para
contar las cantidades de determinados
eventos que se
producen. Ej: cuantos leen y cuantos escriben. Esta
información la puede usar luego el sistema
operativo.
· Cerraduras: Otra posibilidad es asignar una
cerradura a cada dato o recurso. Para acceder a
estos, se debe usar un protocolo que permita o
restrinja el acceso según el estado de la
cerradura.
· Protocolosconmarcasdetiempo: Otra posibilidad es
ejecutar las transacciones (atómicas) a partir de
una marca de tiempo que se le asocia a cada una.
· Otras: Mensajes y llamadas remotas.
Hay varios
problemas clásicos que normalmente se usan para comprobar el buen
funcionamiento de un algoritmo o esquema de sincronización. Ellos son:
· Elproblemadeloslectoresyescritores: Un proceso
puede acceder a un recurso con dos fines, uno es
sólo lectura y otro es lectura - escritura. Cuando
tenemos un conjunto de procesos que sólo leen un
recurso no hay problema, pero estos surgen cuando
hay al menos un proceso que escribe. De esta manera
no podemos asegurar que lo que otros procesos están
Pág. 9
leyendo eran los datos anteriores o los nuevos
luego de
haberse hecho la escritura. Como una posible implementación podríamos tener 2
colas: una para procesos lectores y otra
para escritores. De haber 1 o más procesos escritores compitiendo por
CPU, se deberá restringir o bien la lectura o escritura por parte de los demás
procesos, o bien la escritura de éste y privilegiar a los lectores.
• El problema de los filósofos
comensales: Ilustra de una manera clara cómo hay conflictos al haber 5
filósofos, 5 palillos chinos y 1 plato de arroz en el medio. Para que un
filósofo pueda comer necesita tener 2 palillos en la mano, pero esta situación
dejará a un filósofo sin palillos. Es un buen esquema
que plantea cómo evitar la inanición (que un filósofo muera de hambre).
Interbloqueo (bloqueo mutuo)
Hay una situación que es totalmente indeseada en la ejecución de
varios procesos: y es el interbloqueo o también
llamado bloqueo mutuo. En general, esta situación ocurre cuando hay varios
procesos que tienen recursos A y piden nuevos recursos B. Y otros que tienen B
y piden A. En esta situación se genera una traba de la que no pueden salir
por cuenta propia.
Es tarea del sistema operativo evitarlos o
corregirlos, aunque también los puede ignorar (como pasa en muchas versiones de
UNIX).
Para que ocurra un bloqueo mutuo los procesos
involucrados deben ejecutar su sección crítica de manera exclusiva (mutua exclusión), cada uno está ocupando algunos
recursos y solicita más y no son capaces de expropiarse la ejecución entre sí (procesos no apropiativos). Por
último, el sistema debe estar en un
estado de espera circular(el proceso1 tiene
recurso1 y pide r2. El p2 tiene r2 y pide r3.
El pN tiene rN y pide el r1. Es decir que todos tienen los recursos que
necesitan los otros y piden los que tienen estos. Para evitar los bloqueos
mutuos se puede:
V
hacer listar a cada proceso los recursos que
usará y en base a esto permitirle o no ejecutarse.
V
Obligar a los procesos que cuando solicitan
otro recurso liberen
el actual que poseen.
V
la sutil diferencia de que cuando se les
asigna otro recurso se libere el que
tienen. También se les puede asignar a los recursos un orden, y
cuando el recurso que se pide es posterior, se libera
el anterior
que tienen.
Hay algunos algoritmos para detectar o evitar
bloqueos mutuos,
como el algoritmo de grafo de asignación de recursos, que se usa para
detectar interbloqueos y consiste en detectar ciclos dentro de este grafo (hay
bloqueo mutuo si hay algún ciclo).
También tenemos el algoritmo del banquero, el cual se usa para
evitarlos. Consiste en preguntar a cada proceso los recursos que necesitará y
sólo ejecutarlo si luego de asignados el
sistema aún queda en estado seguro. Para esto se puede simular con el
algoritmo del grafo esta situación. Se le dio este nombre porque el sistema
actúa como un banquero, que no puede prestar más dinero del que tiene.
Si el sistema no evita los bloqueos mutuos se debe hacer algo si ocurren. Una alternativa es destruir los
procesos uno por uno y comprobar en cada paso si el sistema aún está
bloqueado. Otra opción menos drástica es expropiar
Pág. 10
los recursos de algunos procesos hasta que se rompa el bloqueo.
Algoritmos de planificación
Ya sabemos que el sistema operativo tiene una cola de procesos listos,
es decir que están esperando por la CPU. Pero se debe emplear un mecanismo para
seleccionar el proceso correcto de esta
cola a fin de asegurar: maximizar la productividad, el uso de la CPU y
el rendimiento, minimizar el tiempo de espera, de retorno y de respuesta. Se debe elegir uno o una combinación de éstos de
acuerdo a estos criterios, con el fin de encontrar un rendimiento óptimo
del sistema. Los principales algoritmos de planificación son:
· FCFS
(1ro en llegar, 1ro en ser atendido):es el más
justo de todos, pero no es el más eficiente ni el
que mejor rendimiento produce.
· SJF (el trabajo más corto primero):es
uno de los
mejores, pero es muy difícil de implementar
porque
implica la necesidad de conocer el tiempo que
demandará un proceso.
· el
trabajo de tiempo restante más corto 1r o: es una
variante del anterior, también produce buenos
resultados, aunque puede producir inanición.
· por
prioridad: no tiene el mejor rendimiento pero
está cercano. Se debe implementar
envejecimiento de
prioridades para evitar la inanición.
· round
robin: apoya al tiempo compartido. La
ejecución de los procesos se divide
en intervalos de
tiempo regulares llamados quantum. Este debe ser
pequeño para simular concurrencia pero no
demasiando
para no provocar sobrecarga y para permitirle a la
CPU hacer procesamiento productivo. El actual
estándar ronda los 10 ms. Ej: las primeras
versiones
de Solaris tenían implementado un quantum largo.
· colas
múltiples: es una generalización de todas ya
que es posible ubicar a los procesos
en diferentes
colas, y cada una con un algoritmo diferente.
· colas
múltiples con realimentació n:
la idea de este
es parecida al anterior pero es posible que los
procesos cambien de cola, según su estado o el uso
que hagan de los recursos. Es muy bueno
para evitar
la inanición y permite implementar a gusto los
algoritmos anteriores.
Administración de la memoria
Al decir memoria no sólo estamos
hablando de memoria principal (RAM), sino también de secundaria (disco),
caché, terciaria, etc.
El
sistema operativo debe ser el encargado de administrarla eficientemente para
que varios procesos la puedan compartir. Hace esto a través de su “Administrador
Pág.
11
de memoria” (MMU). Los requerimientos para un
correcto manejo
de memoria son:
1.
transparencia: la asignación que hace el SO de la memoria a cada proceso debe ser transparente para
el usuario.
2.
protección: se debe asegurar que no haya una sobre -escritura de memoria.
3. segmentos
múltiples: los segmentos de un proceso deben aparecer
lógicamente contiguos.
4.
código compartido: se debe mantener una sola imagen de cada proceso.
Los
programas hacen uso de ésta a través de variables u objetos, que tienen un
nombre que está vinculado internamente con una dirección en memoria principal. Ejemplo: la variable entera “edad” puede estar
vinculada a la dirección de memoria 01E3-559F (en hexadecimal, 32 bits).
Debemos
considerar varios puntos para saber cuál es la cantidad óptima de memoria que
requiere un sistema. Entre estos tenemos el tamaño de los programas, la
cantidad de programas, el espacio ocupado por el sistema operativo y el tamaño
del disco rígido.
Recordando la primera clasificación de los sistemas operativos
encontramos la monoprogramación. En este antiguo mecanismo la memoria estaba
dedicada exclusivamente a un solo proceso y hasta que no se terminaba no ejecutaba otro. En este esquema se
dividió la memoria en 2 partes: una para el usuario y otra para el
sistema operativo. Esto trajo consigo problemas como la protección. No se
realiza intercambio (entre memoria y disco).
La
multiprogramación es lo contrario a la monoprogramación. En este esquema la
memoria se comparte con varios procesos y hay intercambios (swapping). Esto quiere decir que es posible la memoria virtual,
que es una extensión de la principal pero en disco rígido. Surgen
entonces 2 tipos de direcciones:
-
físicas: sólo en memoria principal. Es más pequeña que la lógica.
-
lógicas: abarca tanto la memoria principal
como la secundaria (disco). Funciona como un solo espacio de
direcciones.
Uno de los mayores problemas que debe considerar un sistema operativo
es la “fragmentación de la memoria”, que se refiere a su división en pequeñas
partes de forma que quedan espacios vacíos demasiado pequeños para ser
utilizados con eficiencia. Destacamos la fragmentación interna y externa.
La
fragmentación interna corresponde al espacio vacío que queda en el
último bloque de cada proceso. No se puede usar por estar ya ocupado. Se
produce al dividir la memoria en bloques de igual tamaño.
La
fragmentación externa corresponde al espacio vacío que queda entre los
diferentes procesos y que no puede ser asignado a ninguno por ser demasiado
pequeño. Se produce mayormente con los bloques de tamaño variable en los que se
divide la memoria.
Estos problemas se pueden solucionar o evitar de varias maneras. Aquí
enunciaremos sólo algunas, pero en sí cada empresa desarrolladora de sistemas
operativos dispone de sus propios métodos, que están adaptados a la estructura
de su SO. Corresponde a desarrollos privados que rara vez se divulgan de manera
total.
Pág. 12
Podemos almacenar los datos y procesos de manera contigua o en
fragmentos.
El almacenamiento contiguo de los procesos genera fragmentación
externa pero evita la interna. Es decir que pueden quedar varios huecos
inutilizados entre cada proceso por ser
demasiado pequeños. Para hacer más espacio entonces es necesario realocar los
procedimientos teniendo en cuenta que no deben quedar espacios entre
estos. Pero este proceso, llamado compactación, es muy costoso en términos de
tiempo.
Una alternativa mejor es dividir un proceso en múltiples partes de
menor tamaño, así podremos ubicarlas en los espacios
libres que queden entre procesos. Esta opción tal vez es mejor pero
tenemos que saber que aparece algo de fragmentación interna (en el último
bloque de un proceso, por no completarse totalmente ya que es de tamaño fijo) y
también tenemos fragmentación externa (aunque disminuye mucho en comparación
con la asignación contigua). La selección del espacio libre donde se ubicarán
nuestros bloques puede ser:
· primerajuste: es el más eficiente y da los mejores
resultados de performance, pero puede desperdiciar
algo de memoria principal.
· mejorajuste: implica recorrer toda la lista en
busca del hueco más pequeño donde quepa nuestro
bloque. Poca performance si no se usan tablas de
espacio libres. Es el que menos de memoria
produce.
· peorajuste: no tiene buenos resultados. Es
contrario
al mejor ajuste.
Una vez ubicados los bloques en la memoria principal necesitamos poder
leer cada uno de estos bloques de un mismo proceso y poder reconstruirlo
exactamente igual a como estaba antes de la división en partes. Esto se puede
solucionar usando punteros o tablas de punteros. Cada uno de éstos estará al
final de cada bloque, y nos indicará cuál es el próximo bloque componente. Las
tablas de punteros son quizás más eficientes y permiten un acceso aleatorio al
archivo o proceso en memoria principal. ¿Por qué? Porque de lo contrario
tendríamos que recorrer uno por uno los bloques siguiendo sus punteros, hasta
llegar al bloque deseado. Este mecanismo es muy ineficiente y para archivos o
procesos grandes agrega un tiempo de espera totalmente inaceptable. Es por esto
que al tener todos los punteros a bloques en una sola tabla, se puede obtener
el bloque exacto en unos pocos accesos.
Paginación
La paginación es una técnica que permite
pasar procesos de
memoria principal a virtual.
Se corresponde directamente con la memoria virtual.
Cada proceso posee una tabla de páginas propia, aunque se
puede implementar una tabla de páginas global a nivel
sistema con el proceso dueño de cada una acoplado. Este
esquema recibe el nombre de paginación invertida, porque
no es el proceso el que contiene las páginas, sino que es
el sistema.
La memoria principal está dividida lógicamente en marcos.
Cada marco puede contener 1 página. Tanto los marcos como
las páginas son de longitud fija, lo que simplifica
enormemente su búsqueda y manipulación por parte del
sistema operativo.
¿Cómo hacemos para acceder a una dirección específica de
la memoria?
Para ésto la dirección se desdobla en dos partes: una
representa el número de página y la otra el
desplazamiento
desde su principio.
Pág. 13
Si queremos acceder a la dirección “d” calculamos:
num. marco = parte_entera(d / tamaño de
marco) desplazamiento = d - num. marco*tamaño de marco
Con estas dos fórmulas nos es suficiente para saber la ubicación
exacta dentro de la memoria, aunque debemos tener una tabla con la página que
le corresponde a cada marco, otra tabla con la ubicación de las distintas
páginas en el disco, otra con los marcos libres, y otra con las páginas libres.
La paginación tiene un mecanismo llamado “demonio de paginación” que
es un proceso demonio (hilo de muy baja prioridad) que se encarga de recorrer
las tablas de páginas y recolectar información como ser las páginas libres o
las menos usadas.
Fallo de página:
Ocurre cuando se solicita una página que no está en memoria principal.
Entonces la MMU (unidad de manejo de memoria del sistema operativo) debe hacer
un intercambio disco >>> memoria principal, para traer la página que
falta.
Paginación multinivel
Cuando el espacio de direcciones es muy grande se
dificulta la ubicación de las páginas en las tablas de
manera eficiente. Para esto podemos usar dos esquemas que
mejorarán la velocidad de acceso a las páginas. Una es
usar técnicas de dispersión (hashing).
Otra es usar una doble paginación. En ésta tenemos las
páginas y la tabla de páginas, pero agregamos una nueva
tabla que indexa la tabla de páginas.
Podemos tener 3, 4 o más niveles de paginación.
Segmentación
Utilizando el mismo enfoque de la paginación, dividimos los procesos
en partes. Sólo que esta vez su tamaño es variable. Esto tiene varias ventajas.
Disminuye la fragmentación externa, desaparece la interna, y agrega protección y seguridad a los datos. También
permiten traer de disco sólo los segmentos que se necesitan (así no es
necesario traer todo el proceso) y compartir bloques de código y datos, lo que
los hace un mecanismo ideal para implementar un sistema operativo flexible y
poderoso. Cada segmento tiene la posición
en memoria donde comienza, su tamaño y bits de protección, entre otros.
Esta técnica produce fragmentación externa, a diferencia de la paginación que
produce interna.
Debemos tener tablas al igual que con la paginación para manipularlos
de una manera eficiente y rápida. Segmentación paginada: Es una
combinación de los 2. Se aprovechan las
mejores características de cada mecanismo y esto permite reducir aún más la
fragmentación y mejorar el rendimiento. Su esquema e un conjunto de
segmentos indexados a su vez por una tabla
de páginas. Podemos tener el otro enfoque que es paginación
segmentada, que también puede producir buenos resultados.
Administración de la asignación de memoria
Para señalizar que páginas se encuentran
libres y cuales ocupadas tenemos 3 técnicas:
· Administraciónconmapadebits: es muy eficiente pero puede
consumir mucha memoria. Por ejemplo para una memoria de 512 MB y un marco de 4
KB tendríamos una mapa de bits de 16 MB. Cuanto más grande la memoria y más pequeños los marcos, la tabla será
más grande. Ej: 01010101010111111010010101111110000. Los
Pág. 14
1 indican
que esa posición de memoria está ocupada. Cada digito hace referencia a bloques
de memoria de 4 KB, por ej.
· Administraciónconlistasenlazadas: Tenemos una
lista en la que cada nodo tiene información de si
está vacía u ocupada y los límites o la
cantidad de
bloques ocupados.
· Sistemadelosasociados: Se parte de considerar a
la memoria como un gran bloque. A medida
que se van
haciendo asignaciones, se va dividiendo siempre por
potencias de 2.
Protección:La protección de las páginas y de los marcos se puede hacer con
bits que indican si son sólo de lectura, de lectura-escritura o de ejecución.
Para almacenar todos estos estados y atributos de las páginas
necesitamos algunas tablas con varios bits para cada una. Cada bit corresponde
a una bandera. Nombremos algunas banderas usadas: bit de
presente/ausente, bit de protección (para indicar lectura o lectura - escritura, o 3 bits para lectura /
escritura / ejecución), bit de lectura (se marca con 0 la página
que ha sido referenciada o leída, y cada cierto tiempo se la marca con 1 para
indicar que no fue referenciada. Una alternativa
más potente al uso de este bit es almacenar el tiempo en el que se hizo
la última referencia. Esto permite una precisión máxima, bit de escritura.
Técnicas de gestión
de memoria
Tenemos 6 técnicas para gestionar la memoria, 3 son de paginación y
las otras 3 de segmentación.
· enparticionesfijas: Esta técnica es sencilla de
implementar. Cada proceso se carga en una
partición
de tamaño fijo (casi siempre de mayor tamaño que el
proceso). Puede tener fragmentación interna. El
proceso trae toda la partición para ejecutarse.
· enparticionesdinámicas: Similar a la anterior pero
la partición se crea según el tamaño del proceso.
Tiene fragmentación externa. Produce sobrecarga de
la CPU.
· enpáginassimples: Los procesos se dividen en
muchos marcos de igual tamaño. Para
ejecutar un
proceso se necesitan traer todas sus páginas.
· ensegmentossimples: Los procesos se dividen en
muchos
marcos de distinto tamaño.
· enmemoriavirtualpaginada: Para ejecutar un
proceso no se necesitan traer todas sus
páginas. La
carga se hace de manera automática.
· enmemoriavirtualsegmentada: Igual que la anterior
pero con segmentos.