Sei sulla pagina 1di 83

Introduccin

Qu es un sistema operativo?
A pesar de que todos nosotros usamos sistemas operativos casi a diario, es difcil definir qu es un sistema operativo. En parte, esto se debe a que los sistemas operativos realizan dos funciones diferentes.

Proveer una mquina virtual, es decir, un ambiente en el cual el usuario pueda ejecutar programas de manera conveniente, protegindolo de los detalles y complejidades del hardware. Administrar eficientemente los recursos del computador.

El sistema operativo como mquina virtual Un computador se compone de uno o ms procesadores o CPUs, memoria principal o RAM, memoria secundaria (discos), tarjetas de expansin (tarjetas de red, modems y otros), monitor, teclado, mouse y otros dispositivos. O sea, es un sistema complejo. Escribir programas que hagan uso correcto de todas estos componentes no es una tarea trivial. Peor an si hablamos de uso ptimo. Si cada programador tuviera que preocuparse de, por ejemplo, como funciona el disco duro del computador, teniendo adems siempre presentes todas las posibles cosas que podran fallar, entonces a la fecha se habra escrito una cantidad bastante reducida de programas. Es mucho ms fcil decir `escriba lo apuntado por este puntero al final del archivo "datos"', que 1. Poner en determinados registros del controlador de disco la direccin que se quiere escribir, el nmero de bytes que se desea escribir, la posicin de memoria donde est la informacin a escribir, el sentido de la operacin (lectura o escritura), amn de otros parmetros; 2. Decir al controlador que efectu la operacin. 3. Esperar. Decidir qu hacer si el controlador se demora ms de lo esperado ( cunto es "lo esperado"?). 4. Interpretar el resultado de la operacin (una serie de bits). 5. Reintentar si algo anduvo mal. 6. etc. Adems, habra que reescribir el programa si se instala un disco diferente o se desea ejecutar el programa en otra mquina. Hace muchos aos que qued claro que era necesario encontrar algn medio para aislar a los programadores de las complejidades del hardware. Esa es

precisamente una de las tareas del sistema operativo, que puede verse como una capa de software que maneja todas las partes del sistema, y hace de intermediario entre el hardware y los programas del usuario. El sistema operativo presenta, de esta manera, una interfaz omquina virtual que es ms fcil de entender y de programar que la mquina "pura". Adems, para una misma familia de mquinas, aunque tengan componentes diferentes (por ejemplo, monitores de distinta resolucin o discos duros de diversos fabricantes), la mquina virtual puede ser idntica: el programador ve exactamente la misma interfaz. El sistema operativo como administrador de recursos La otra tarea de un sistema operativo consiste en administrar los recursos de un computador cuando hay dos o ms programas que ejecutan simultneamente y requieren usar el mismo recurso (como tiempo de CPU, memoria o impresora). Adems, en un sistema multiusuario, suele ser necesario o conveniente compartir, adems de dispositivos fsicos, informacin. Al mismo tiempo, debe tenerse en cuenta consideraciones de seguridad: por ejemplo, la informacin confidencial slo debe ser accesada por usuarios autorizados, un usuario cualquiera no debiera ser capaz de sobreescribir reas crticas del sistema, etc. (En este caso, un usuario puede ser una persona, un programa, u otro computador). En resumen, el sistema operativo debe llevar la cuenta acerca de quin est usando qu recursos; otorgar recursos a quienes los solicitan (siempre que el solicitante tenga derechos adecuados sobre el recurso); y arbitrar en caso de solicitudes conflictivas. Recursos administrados por un sistema operativo Los recursos administrados por un sistema operativo son:

Tiempo del procesador. Memoria Principal. Dispositivos Perifericos. Software.

Tiempo del procesador. El recurso ms importante en el sistema de computacin es el procesador central. Sin acceso al CPU. los programas no pueden ejecutarse. La estrategia ms simple para asignar este recurso sera asignarlo a un trabajo de usuariohasta que finalice. Esta estrategia es usada en muchos computadores. Sin embargo la mayora de los programas gastan ms de la mitad de su tiempo esperando que terminen operaciones de Entrada/Salida. Esto nos lleva a tratar

de compartir el tiempo del CPU entre varios usuarios, lo cual implica un mecanismo ms complejo que nos permita utilizar eficientemente el tiempo del procesador y explotar el paralelismo existente con las operaciones de Entrada/Salida. Memoria Principal. Un segundo recurso que es escaso en la mayora de los computadores es la memoria principal. Un programa se puede ejecutar solamente si tiene asignada la memoria fisica que necesita, ya que el procesador accesa las instrucciones y los datos que se encuentran en esa memoria fsica. Si el sistema operativo soporta la ejecucin simultnea de varios trabajos entonces la memoria est compartida entre esos varios trabajos. En estos casos el S.O. debe asiganr eficientemente la memoria a esos trabajos, evitando desperdicios. El objetivo principal de los diferentes esquemas de administracin de memoria (que se estudiarn en detalle aqui), es la reduccin del desperdicio que ocurre como consecuencia de los diferentes tamaos de los programas de usuario. La mayora de estos esquemas son complejos y generan un overhead (tiempo durante el cual el CPU procesa al S.O.) considerable, siendo muy difcil cuantitativamente la contribucin de estos esquemas a la eficiencia general del sistema. Dispositivos Perifricos. La mayora de los dispositivos perifricos se asignan a un solo usuario, no se comparten entre varios usuarios. Esta situacin puede ser muy ineficiente en el caso de algunos dispositivos tales como la impresora, si el trabajo al que fuese asignado este dispositivo tuviese un tiempo largo de ejecucin. Por otra parte, los dispositivos de acceso directo son compartidos entre los usuarios a travs del sistema de archivos y pueden ocurrir demoras derivadas del uso compartido que pudieran ser intolerables en un momento dado. La asignacin de los dispositivos a los usuarios tiene implicaciones muy fuertes en la eficiencia y comportamiento del sistema de computacin. Dado que la mayora de los equipos incluye una sola impresora, los sistemas operativos incluyen normalmente un sistema de SPOOLING (operaciones perifericas simultneas en linea) que evita las ineficiencias que se generaran si este dispositivo fuese asignado a un trabajo por vez. Sin embargo, en computadores pequeos, el overhead ocasionado por el spooler sera intolerable y pudiera ser tal vez ms efectivo abortar y recomenzar algn trabajo. Por otra parte el uso no controlado de los dispositivos por parte de los usuarios puede ocasionar "trancas". El sistema pudiera llegar a estar procesando varios

trabajos que se encuentren simultneamente tranacados (Deadlock) sin realizar ningn tipo de trabajo til. Software. Los recursos de software de un sistema de computacin, consisten en las funciones disponibles al usuario con el objeto de administrar datos y controlar la ejecucin de programas. Entre estos recursos se encuentran los servicios de administracin de archivos, los despachadores, libreras del sistema y rutinas de utilidad. El mtodo ms utilizado para permitir a varios usuarios compartir un recurso de software, es haciendo este recurso de software reentrante. La utilizacin de software reentrante, evita tener en la memoria varias copias de ese software, situacin que sera muy ineficiente. En computadores pequeos puede ser imposible la implementacin de programas reentrantes.

Evolucin de los sistemas operativos


Los sistemas operativos y la arquitectura de computadores han evolucionado de manera interrelacionada: para facilitar el uso de los computadores, se desarrollaron los sistemas operativos. Al construir y usar los sistemas operativos, se hace obvio que ciertos cambios en la arquitectura los simplificara. Por eso, es conveniente echar una mirada a la historia. La primera generacin (1945-1955): tubos de vaco Lo cierto es que el primer computador digital fue diseado por el matemtico ingls Charles Babbage hace cerca de siglo y medio. Era un computador totalmente mecnico, que Babbage nunca pudo construir, principalmente debido a que la tecnologa de la poca no era capaz de producir las piezas con la precisin requerida. Despus de eso, poco se hizo hasta la segunda guerra: alrededor de 1940 se construyeron las primeras mquinas calculadoras usando tubos de vaco. Estas mquinas de varias toneladas de peso eran diseadas, construidas, programadas y operadas por el mismo grupo de personas. No haba ni lenguajes de programacin, ni compiladores; mucho menos sistema operativo. Cada programa se escriba en lenguaje de mquina, usando tableros con enchufes e interruptores y tena que manejar todo el sistema (lo que era factible gracias a que el programador era el mismo que dise y construy la mquina). Con el tiempo se introdujeron las tarjetas perforadas, para reemplazar al tablero, pero el sistema era esencialmente el mismo.

La segunda generacin (1955-1965): transistores y procesamiento por lotes La introduccin de los transistores permiti aumentar sustancialmente la confiabilidad de los computadores, lo que a su vez hizo factible construir mquinas comerciales. Por primera vez hubo una separacin entre diseadores, constructores, y programadores. La aparicin de los primeros compiladores (de FORTRAN) facilit la programacin, a costa de hacer mucho ms compleja la operacin de los computadores. Por ejemplo, para probar un programa en FORTRAN recin escrito, el programador deba esperar su turno, y: 1. Cargar compilador de FORTRAN, tpicamente desde una cinta magntica. 2. Poner el alto de tarjetas perforadas correspondientes al programa FORTRAN y correr el compilador. 3. El compilador genera cdigo en assembler, as que hay que cargar ahora el ensamblador para traducirlo a lenguaje de mquina. Este paso requiere poner otra cinta con el ensamblador. Ejecutar el ensamblador, para generar el programa ejecutable. 4. Ejecutar el programa. Si hay errores en cualquiera de estos pasos, el programador deba corregir el programa y comenzar todo de nuevo. Obviamente, mientras el programdor pona cintas y tarjetas, y mientras se devanaba los sesos para descubrir por qu el programa no funciona, la CPU de millones de dlares de costo se mantena completamente ociosa. Ms que rpido, se idearon mecanismos para mantener a la CPU siempre ocupada. El primero fue separar el rol de programador del rol de operador. Un operador profesional demoraba menos en montar y desmontar cintas, y poda acumular lotes de trabajos con requerimientos similares: por ejemplo, si se acumula la compilacin de varios programas FORTRAN, entonces el compilador de FORTRAN se carga una sola vez para todos los trabajos. An as, en la transisin de un trabajo a otro la CPU se mantena desocupada. Aparecieron entonces los monitores residentes, que fueron los precursores de los sistemas operativos. Un monitor residente es un pequeo programa que est siempre en la memoria del computador, desde que ste se enciende. Cuando un programa termina, se devuelve el control al monitor residente, quien inmediatamente selecciona otro programa para ejecutar. Ahora los programadores, en vez de decirle al operador qu programa cargar, deban informrselo al monitor (mediante tarjetas de control especiales):
$JOB $FTN

programa FORTRAN $LOAD $RUN datos para el programa $END

Esto se conoce como procesamiento por lotes: el programador deja su alto de tarjetas, y despus vuelve a retirar la salida que se emite por la impresora (y que puede ser nada ms que la notificacin de que el programa tena un error de sintaxis). La tercera generacin (1965-1980): circuitos integrados y multiprogramacin El procesamiento por lotes evita que la CPU tenga que esperar tareas ejecutadas por lentos seres humanos. Pero ahora el cuello de botella se traslad a los dispositivos mecnicos (impresoras, lectoras de tarjetas y de cinta), intrnsecamente ms lentos que que las CPUs electrnicas. Para resolver esto, aparece, dentro de la tercera generacin de computadores, la multiprogramacin: varios trabajos se mantienen permanentemente en memoria; cuando uno de ellos tiene que esperar que una operacin (como grabar un registro en cinta) se complete, la CPU contina con la ejecucin de otro trabajo. Si se mantiene un nmero suficiente de trabajos en la memoria, entonces la CPU puede estar siempre ocupada. Pero el sistema sigue siendo esencialmente un sistema de procesamiento por lotes; los programadores no interactan en lnea con el computador, los tiempos de respuesta desde que se deja un trabajo para ejecucin hasta conocer el resultado son demasiado grandes. (En cabio, los computadores de primera generacin eran interactivos!) De ah nace el concepto de tiempo compartido que es una variante de la multiprogramacin en la cual una CPU atiende simultneamente los requerimientos de varios usuarios conectados en lnea a travs de terminales. Ya que los usuarios humanos demoran bastante entre la emisin de un comando y otro, una sola CPU es capaz de atender, literalemente, a cientos de ellos simultneamente (bueno, en realidad, uno despus de otro, pero los usuarios tienen la ilusin de la simultaneidad). Al mismo tiempo, cuando no hay ningn comando que ejecutar proveniente de un usuario interactivo, la CPU puede cambiar a algn trabajo por lote. La cuarta generacin (1980-): computadores personales Con el advenimiento de la integracin a gran escala, que permiti concentrar en un solo chip miles, y luego millones de transistores, naci la era de la computacin personal. Los conceptos utilizados para fabricar los sistemas operativos de la tercera generacin de computadores siguen siendo, en general, adecuados para la cuarta generacin. Algunas diferencias destacables:

Dado los decrecientes costos de las CPUs, ya no es nada de grave que un procesador est desocupado. La creciente capacidad de las CPUs permite el desarrollo de interfaces grficas; buena parte del cdigo de los sistemas operativos de hoy es para manejar la interfaz con el usuario. Los sistemas paralelos (un computador con varias CPUs), requieren sistemas operativos capaces de asignar trabajos a los distintos procesadores. Las redes de computadores y sistemas distribuidos abren nuevas posibilidades e imponen nuevas obligaciones a los sistema operativo.

Apoyo del hardware


Interrupciones: la base de los sistemas operativos modernos Un computador moderno se compone de una CPU (a veces ms de una) y una serie de controladores de dispositivos, conectados a travs de un bus comn a la memoria. Cada controlador est a cargo de un tipo especfico de dispositivo. Cuando se enciende el computador, se ejecuta automticamente un pequeo programa, cuya nica tarea es cargar el sistema operativo en la memoria, y entregarle el control (ejecutarlo). El sistema operativo hace las inicializaciones del caso, y luego simplemente espera a que algn evento ocurra. La ocurrencia de un evento es, por lo general, sealizada por una interrupcin de software o hardware. Los controladores de dispositivo pueden gatillar una interrupcin en cualquier momento, enviando una seal a la CPU a travs del bus del sistema. Las interrupciones de software son gatilladas por procesos, por la va de ejecutar una instruccin especial que se conoce como llamada al sistema. Ejemplos de eventos que gatillan interrupciones: terminacin de una operacin de I/O, llamadas al sistema, divisin por cero, alarmas del reloj. Para cada tipo de interrupcin, debe existir una rutina que la atienda: el servidor de la interrupcin. Cuando la CPU es interrumpida: 1. La CPU deja de hacer lo que estaba haciendo, que puede haber sido nada, (si simplemente estaba esperando), o la ejecucin de un proceso. 2. Determina el tipo de interrupcin. 3. Ejecuta el servidor de interrupcin correspondiente. 4. Contina lo que fue interrupido. Ms en detalle, una forma de hacer todo esto es la siguiente: Dado que existe una cantidad limitada (y reducida) de tipos de interrupciones posibles, se usa

una tabla con las direcciones de los servidores de cada interrupcin, tpicamente en las primersimas posiciones de la memoria. Esta tabla se conoce como vector de interrupciones. As por ejemplo, si las direcciones ocupan 4 bytes, la direccin del servidor de la interrupcin i se guarda en los 4 bytes a partir de la posicin 4i de la memoria. Cuando ocurre una interrupcin: 1a. La CPU debe memorizar lo que estaba haciendo para continuarlo despus: se guarda el PC (y posiblmente otros registros) en el stack del sistema. 1b. Se deshabilitan las interrupciones para que la CPU no sea interrumpida mientras atiende una interrupcin (situacin que podra generar caos). 2. Se determina la direccin del servidor de la interrupcin. 3. Se transfiere el control a esa direccin. 4. La rutina que atiende la interrupcin debe finalizar con una instruccin IRET, que restablece el estado que la CPU tena cuando fue interrumpida, usando los datos almacenados en el stack. Esquemas ms sofisticados enmascaran (deshabilitan selectivamente) las interrupciones en vez de deshabilitarlas totalmente (punto 1b), de manera que una interrupcin de alta prioridad SI pueda interrumpir a la CPU cuando est atendiendo una de menor prioridad. Todos los sistemas operativos modernos se basan en interrupciones (interrupt driven). Si no hay procesos que ejecutar, ni dispositivos ni usuarios que atender, el sistema operativo no hace nada: se "sienta" a esperar que algo pase. Cuando algo pasa, se sealiza una interrupcin, y el sistema operativo entra en actividad (o sea, los servidores de interrupcin son parte del sistema operativo).
Ejemplo: multiprogramacin (timesharing)

1. El sistema operativo inicializa el timer o reloj en una tajada de tiempo, y lo echa a andar. 2. El sistema operativo entrega el control a un proceso. 3. El proceso ejecuta. 4. Concluido el tiempo prefijado, el timer provoca una interrupcin. 5. El manejador de interrupciones del timer (que es parte del sistema operativo), guarda la informacin del proceso interrumpido necesaria para poder reanudarlo despus.

6. Se repite el ciclo, escogiendo ahora otro proceso. Se puede obtener multiprogramacin sin interrupciones? Windows 3.x versus Windows 95: cooperative versus preemptive multitasking.
Otro ejemplo: manejo de dispositivos de I/O

Para comenzar una operacin de I/O, el sistema operativo escribe los registros del caso en el controlador del dispositivo. A su vez, el controlador determina qu hacer mirando el contenido de esos registros. Por ejemplo, si se trata de una solicitud de lectura, inicia la transferencia de datos desde el dispositivo hacia la memoria. Cuando finaliza la transferencia, el controlador le avisa a la CPU a travs de una interrupcin. Esto permite que la CPU, en vez de esperar que la transferencia termine (lo que sera I/O sincrnico), en el intertanto puede realizar otra tarea (I/O asincrnico). Una secuencia tpica:
1. El proceso que es ejecutando en la CPU solicita una operacin de I/O,

2. 3. 4.

5.

6.

mediante una llamada al sistema. El sistema operativo suspende el proceso, ponindolo en la cola de procesos suspendidos, y comienza la operacin de I/O. El sistema operativo escoge otro proceso para que siga ejecutando en la CPU. Cuando la operacin de I/O se completa, el control vuelve al sistema operativo gracias a que el controlador del dispositivo provoc una interrupcin. El sistema operativo, determina, segn la interrupcin y sus tablas internas, que el proceso que haba sido suspendido ahora puede reanudarse, as que lo pone en la cola de procesos listos para ejecutar. El sistema operativo reanuda ese, o tal vez otro proceso de la cola de procesos listos.

Proteccin En los primeros computadores el operador tena el control completo del sistema. Con el tiempo, se fueron desarrollando los sistemas operativos, y parte del control se traspas a ellos. Adems, para mejorar la utilizacin del sistema, se comenz primero a manejar varios programas en memoria en forma simultnea, y luego a atender simultneamente a varios usuarios. Pero el remedio trajo su propia enfermedad, ya que un programa poda por error o por mala intencin de su creador, modificar datos de otros programas, o peor an, modificar el propio sistema operativo, lo que poda botar todo el sistema. En general, un programa puede alterar el normal funcionmiento del sistema de las siguientes formas:

Ejecutando una instruccin de I/O ilegal (por ejemplo, que borre todos los archivos del disco). Sobreescribiendo reas de la memoria que pertenecen al sistema operativo. No devolviendo el control de la CPU al sistema operativo.

Para evitar esto, es indispensable el apoyo del hardware, a travs de los siguientes mecanismos.
Operacin dual

Para asegurar una operacin adecuada, se debe proteger al sistema operativo y todos los programas del malfuncionamiento de cualquier otro programa. Para eso, el hardware debe proveer al menos dos modos de operacin.

Modo usuario. Modo sistema (o privilegiado, protegido o supervisor).

El bit de modo indica el modo de operacin actual. Cuando se enciende el computador y se carga el sistema operativo, se comienza en modo sistema. El sistema operativo siempre cambia a modo usuario antes de pasar el control a un proceso de usuario. Cuando ocurre una interrupcin, el hardware siempre cambia a modo sistema. De esta menera, el sistema operativo siempre ejecuta en modo sistema. Cual es la gracia? Que hay ciertas operaciones crticas que slo pueden ser ejecutadas en modo sistema.
Proteccin de I/O

Para prevenir que un usuario ejecute instrucciones de I/O que puedan provocar dao, la solucin es simple: las instrucciones de I/O slo pueden ejecutarse en modo sistema. As los usuarios no pueden ejecutar I/O directamente, sino que deben hacerlo a travs del sistema, quien puede filtrar lo que sea del caso. Para que este mecanismo de proteccin sea completo, hay que asegurarse que los programas de usuario no puedan obtener acceso a la CPU en modo sistema. Por ejemplo, un programa de usuario podra poner una direccin que apunte a una rutina propia en el vector de interrupciones. As, cuando se produzca la interrupcin, el hardware cambiara a modo sistema, y pasara el control a la rutina del usuario. O, tambin, el programa de usuario podra reescribir el servidor de la interrupcin. Se requiere entonces...
Proteccin de memoria

No slo hay que proteger el vector de interrupciones y las rutinas servidoras, sino que, en general, queremos proteger las reas de memoria utilizadas por el

sistema operativo y por otros programas. Esto lo vamos a ver con ms detalle ms adelante, pero una forma es usando dos registros: base y lmite, que establecen el rango de direcciones de memoria que el programa puede accesar legalmente. Para que esto funcione, hay que comparar cada direccin accesada por un programa en modo usuario con estos dos registros. Si la direccin est fuera del rango, se genera una interrupcin que es atendida por el sistema operativo, quien aborta el programa (usualmente con un lacnico mensaje "segmentation fault"). Esta comparacin puede parecer cara, pero teniendo presente que se hace en hardware, no lo es tanto. Obviamente, el programa usuario no debe poder modificar estos registros: las instrucciones que los modifican son instrucciones protegidas.
Proteccin de CPU

La nico que falta, es asegurarse que el sistema operativo mantenga el control del buque, o sea, hay que prevenir, por ejemplo, que un programa entre en un ciclo infinito y nunca devuelva el control al sistema operativo. Esto se logra con un timer, tal como vimos en el ejemplo de multiprogramacin.
Instrucciones privilegiadas

Instruccin para cambiar a modo protegido Instrucciones para modificar registros de administracin de memoria (por ej., base y limite) Instruccin para manejar el timer Instruccin para deshabilitar interrupciones Instrucciones para hacer I/O

Entonces, cmo hace I/O un programa de usuario, si slo el sistema operativo puede hacerlo? El programa le pide al sistema operativo que lo haga por l. Tal solicitud se conoce como llamada al sistema, que en la mayora de los sistemas operativos se hace por medio de una interrupcin de software o trap a una ubicacin especfica del vector de interrupciones. Ejemplo hipottico, (parecido a MSDOS), para borrar un archivo:
1. Poner en registro A el cdigo de la operacin: 41h = borrar archivo

2. Poner puntero al nombre del archivo en registro B 3. INT 21h (generar interrupcin de software) Como la llamada es a travs de una interrupcin, se hace lo de siempre: cambiar a modo protegido, y pasar control a la direccin en la posicin 4*21h del vector de interrupciones, o sea, a la rutina que maneja las llamadas al sistema (o tal vez, la rutina que maneja las llamadas que tienen que ver con archivos; puede que otras clases de llamadas sean atendidas por medio de

otras interrupciones). Dicha rutina examina el registro A para determinar qu operacin debe ejecutar, y despus determina el nombre del archivo a travs del registro B. En seguida, decide si la operacin es vlida: puede que el archivo no exista o pertenezca a otro usuario; segn eso, borra el archivo o "patalea" de alguna manera. Cuando uno hace esto en un lenguaje de alto nivel, como C, simplemente escribe:
char* Nombre = "Datos"; remove(Nombre);

El compilador de C es quien se encarga de traducir esto a una llamada al sistema, ocultando el detalle de la interfaz con el sistema operativo. En resumen: los sistemas operativos modernos se apoyan ampliamente en el hardware. Las necesidades recin vistas (interrupciones, instrucciones privilegiadas, proteccin de memoria) fueron impuestas a los diseadores de hardware por los requerimientos de multiprogramacin de los sistemas operativos. Por eso dijimos que la historia de los sistemas operativos est interrelacionada con la historia de la arquitectura de computadores.

Conceptos claves que afectan el diseo de un S.O.


Relocalizacin Relocalizar un conjunto de instrucciones y/o datos consiste en asignarle, para su ejecucin, un conjunto de de direcciones de memoria independientes del proceso de traduccin. Un programa puede ser traducido relativo a cierta direccin y cargado en memoria para su ejecucin en otra direccin. El proceso de relocalizacin comprende todas las actividades necesarias para la ejecucin de este programa en el nuevo conjunto de direcciones. La relocalizacin puede efectuarse en tiempos diversos: a) En tiempo de enlace por un cargador/enlazador. b) En tiempo de carga por un cargador relocalizador. c) En tiempo de ejecucin. Reentrancia Se dice que un programa es reentrante cuando una sola copia de ese programa puede ser simultneamente utilizada por varios usuarios. La reentrancia requiere que cada programa deba estar compuesto de dos partes: 1) Una parte o segmento, el cual contiene las instrucciones del programa y debe ser "pura" (no debe modificarse a si misma) ya que es compartida.

2) Una segunda parte que contiene los datos que si pueden ser modificados por el programa. Interrupciones Una Interrupcin es un mecansmo del hardware que obliga al CPU a suspender su actividad para atender un evento externo. Este mecansmo fue desarrollado como un medio para incrementar la eficiencia del procesador. El objetivo de su desarrollo est ligado a la simultaneidad de las actividades del CPU y las operaciones de entrada/salida, ya que se necesitaba un mecansmo a travs del cual pudiera indicarse al cpu la finalizacin de estas actividades. Otro motivo de su desarrollo fue la creacin de un mecansmo para manejar ciertas condiciones internas tales como: divisin por cero, overflow, cdigos de operacin invlidos, condiciones de reloj, etc. Canales y Procesadores de E/S El concepto de canal ha existido por muchos aos. Un canal es un procesador especial que ejecuta unos programas particulares llamados programas de canal. Usualmente son costosos, por lo que existen normalmente un nmero limitado en los sistemas de computacin. El objetivo de los programas de canal es realizar operaciones de entrada/salida. Los programas de canal normalmente comparten la memoria principal con los programas de usuario. Existen normalmente dos tipos de canales:

Multiplexores: Est orientado a la transmisiones caracter por caracter, por lo que se utiliza con dispositivos de baja velocidad. Selectores: permite la transmisin de bloques de informacin entre la memoria y los dispositivos, por lo que se usa asociado a dispositivos de alta velocidad.

Buffering Un buffer es un rea de memoria principal utilizada para almacenar datos durante las operaciones de entrada y salida. Por ejemplo durante una entrada los datos son colocados en el buffer por el canal al terminar la transferencia, esos datos pueden ser accesados por el procesador. Si se usa un solo buffer el proceso se lleva a cabo de la forma siguiente: el canal deposita datos en el buffer, el procesador los procesa, y asi sucesivamente. El procesador no puede comenzar a procesar los datos hasta que el canal termine de depositarlos en el buffer. El uso de dos buffer permite superponer actividades las actividades de procesamiento y entrada/salida. Mientras el canal deposita datos en el buffer,

el procesador procesa los datos depositados en el otra buffer. Cuando el procesador termina con los datos del primer buffer, comienza a procesar los datos del segundo y simultneamente el canal deposita datos en el primer buffer, esta tcnica es mejor conocida como doble buffering. Proteccin de la memoria principal En los sistemas multiusuario es necesario utilizar un mecansmo de proteccin de las reas de memoria para prevenir que un usuario accese el conjunto de direcciones de otro usuario o del sistema operativo. Estos mecansmos se basan en la limitacin del rango de direcciones que un programa puede referenciar. Por ejemplo, si un programa utiliza direcciones contiguas de memoria, pudieran utilizarse un par de registros que delimitarn el lmite inferior y superior del rango de direcciones usado por el programa. Si el programa tratara de accesar direcciones superiores o inferiores al rango de direcciones delimitado por el par de registros se producira una interrupcin de hardware. Pudieran tambin utilizarse claves de proteccin asociadas a reas de memoria; un programa solo pudiera accesar las reas de memoria que tuviesen claves de proteccin iguales a las del programa. Relojes Un sistema de computacin puede tener varios relojes. El reloj interval timer (reloj para medir intervalos de tiempo) se utiliza para prevenir que un usuario monopolice el CPU. Despus de un perodo de tiempo este reloj genera una interrupcin y el procesador puede asi ser asignado a otro trabajo. Pueden existir tambin otros relojes para llevar la cuenta de la fecha y hora y otros fines. Direccionamiento de Base y desplazamiento En la medida que crecieron las capacidades de memoria de los computadores, las arquitecturas tuvieron que ser modificadas para poder acomodar rangos muy grandes de direcciones. Un computador que puede accesar 16 MB requerira un campo de direccin de 24 bits, lo que implicara instrucciones de mquina muy grandes, sobre todo en caso de instrucciones de varios operandos. Para solucionar este problema la mayora de las arquitecturas incluyen algn tipo de direccionamiento de base y desplazamiento bajo el cual, un nmero (desplazamiento) es sumado al contenido de algn registro (registro base) para generar una direccin de memoria.

Este esquema tiene adems la ventaja de hacer a los programas independientes del lugar de memoria donde son cargados, lo que es muy valioso en sistemas de multiprogramacin donde los programas son cargados cada vez en un lugar diferente. Estado de problema, Estado Supervisor, Instrucciones Privilegiadas Los sistemas de computacin tienen normalmente varios estados de ejecucin que son utilizados para incrementar la seguridad del sistema. Normalmente existe un estado de problema y uno o varios estados de supervisor. Se dice que un procesador se encuentra en estado de problema cuando procesa las instrucciones que forman el sistema operativo. Cuando un procesador se encuentra en un estado particular solo puede ejecutar un subconjunto del conjunto de instrucciones. Un usuario que se encuentre en estado de problema no puede ejecutar ciertas instrucciones, ya que si al usuario se le permitiese la ejecucin de este tipo de instrucciones, pudiera realizar acciones que afecten la seguridad del sistema o modificar informacin confidencial perteneciente a otro usuario. Las instrucciones que inician la ejecucin de programas de cana, las instrucciones que modifican los relojes, las instrucciones que manipulan ciertos registros del CPU, etc., son ejemplos de instrucciones que no pueden ejecutarse en estado de problema, son instrucciones llamadas privilegiadas que solo pueden ejecutarse en estado supervisor, osea, cuando se ejecuta el sistema operativo. El sistema operativo es considerado como el usuario ms confiable, por lo cual realiza su ejecucin en estado de supervisor bajo el cual puede ejecutar todo el conjunto de instrucciones del equipo. En algunos sistemas se utilizan ms de dos estados. Es interesante hacer notar que el nmero de instrucciones privilegiadas (instrucciones que solo pueden ejecutarse en estado supervisor) se han incrementado con la evolucin de la arquitectura de hardware lo que indica que las nuevas generaciones de arquitecturas han incorporado al hardware, ms y ms funciones que antes eran realizadas por el sistema operativo. Algunos microcomputadores tienen en hardware la totalidad del sistema operativo. Spooling En un sistema que utilice spooling (operaciones perifricas simultneas en lnea) un dispositivo de alta velocidad (disco) se interpone entre un programa en ejecucin y un dispositivo de baja velocidad que est siendo utilizado por el programa. Por ejemplo, en lugar de imprimir lneas directamente a la impresora, las lneas se graban a disco, lo que permite al programa terminar

ms rpido y que el impresor pueda ser compartido eficientemente entre varios usuarios. Cuando exista disponibilidad fsica del impresor las lneas pueden leerse del disco e imprimirse. Microprogramacin (Firmware) Unidades de control microprogramables. El concepto de microprogramacin es generalmente atribudo al profesor Maurice Wilkes, el cual en 1.951 present los conceptos que forman la base de las tcnicas actuales de microprogramacin. En los aos 60 cuando apareci la IBM 360, la microprogramacin fue utilizada en gran escala. Durante los aos 60, los fabricantes de computadores utilizaron la microprogramacin para la implementacin del conjunto de instrucciones. A comienzos de los 70, apareci la microprogramacin dinmica, la cual permite que nuevos microprogramas sean cargados fcilmente en la memoria de la unidad de control, donde son ejecutados. La microprogramacin envuelve la programacin de las instrucciones de mquina. Los microprogramas residen en una unidad de control donde son ejecutados. Los microprogramas estn formados por microinstrucciones que son an ms elementales que las instrucciones de lenguaje de mquina. Cada instruccin en lenguaje de mquina se se implementa a travs de un microprograma. El uso de esta tcnica implica que la memoria en donde residen los microprogramas sea mucho ms rpida que la memoria principal. La microprogramacin se relaciona con los sitemas operativos, porque en los sistemas operativos existen secuencias de instrucciones que se ejecutan frecuentemente. La implementacin microprogramada de esta secuencia de instrucciones, mejora notablemente el comportamiento de un sistema de computacin, reduce los costos de desarrollo y mejora la seguridad del sistema (ya que el microprograma no puede ser violentado por los programas de usuario); el inconveniente, quizs, es la limitaciones a la hora de realizar modificaciones. Emulacin Es una tcnica bajo la cual una mquina se comporta como si fuese otra. El conjunto de instrucciones de la mquina emulada es microprogramada en la mquina husped. De esta manera los programas objeto de la mquina emulada corren en la mquina husped . Lenguajes de Programar S.O.

Durante mucho tiempo los sistemas operativos fueron implementados en lenguaje ensamblador. En los ltimos aos se han diseado e implementado varios lenguajes para implementar sistemas operativos. La mayora de los lenguajes de programar sistemas operativos son ms eficientes que el lenguajeensamblador. Sin embargo usualmente se necesita el uso de lenguaje ensamblador para implementar ciertas funciones. La utilizacin de lenguejes de programacin de sistemas ha reducido el tiempo necesario para programar un S.O., ya que se estima que las funciones que deben implementarse en lenguaje ensamblador (pulida), solo representan el 1% del esfuerzo de programacin necesario. Un ejemplo de un lenguaje de programacin de sistemas es el C, con el que se elabor casi en su totalidad el S.O. UNIX.

Programacin de Entrada/Salida
En esta parte se presentarn las tcnicas de hardware y software utilizadas para las operaciones de E/S enfatizando la concurrencia existente entre estas operaciones y el procesamiento del CPU. Se presentarn una serie de ejemplos de utilizacin de buffers para ilustrar estas tcnicas. Los dispositivos de almacenamiento pueden clasificarse de acuerdo a su velocidad de acceso en: almacenamiento del procesador (registros, ndices, acumuladores, registros de instrucciones, etc); memoria principal (memoria de ferrita, circuitos integrados, SIMM, etc.); Memoria secundaria (Discos, cintas, etc.); Dispositivos perifricos (Impresoras, Scanners, etc.). La velocidad de transferencia de informacin vara por un factor de alrededor 109 a travs de la jerarqua anterior, desde un caracter por segundo en algunos perifricos como las impresoras, hasta millones de instrucciones por segundo (MIPS) en algunos CPU's. Cada uno de los dispositivos nombrados puede ser visto como una unidad de E/S. Es importante sealar aqu que las operaciones de E/S entre los registros del CPU y entre el CPU y la memoria son controladas e iniciadas por el hardware, es decir, no es competencia del S.O. El control de E/S es otra de las misiones que debe realizar un S.O. para facilitar el uso de los distintos dispositivos que forman parte de un sistema informtico. El uso de los perifricos directamente por los procesos no es fcil ni cmodo, por lo cual los procesos no necesitan conocer las peculiaridades ni caractersticas de dichos dispositivos, nicamente deben intercambiar datos

con ellos debido a que los detalles de uso son ocultos por el S.O. para que las operaciones E/S sean independientes del tipo y modelo del dispositivo. En general, el software de gestin de operaciones de E/S que posee el S.O. representa aproximadamente el 50% del total, por lo que esta parte es de suma importancia.

Interfaz Procesador - Perifrico:


La velocidad y complejidad de los perifricos determinan como van a ser conectados al procesador. Existen tres tipos de conexiones a saber: 1.- REGISTROS: Por medio de registros que poseen los dispositivos se pueden conectar al procesador. Estos registros pueden ser accedidos en una zona determinada de la memoria o, indirectamente, por medio de instrucciones hardware que devuelven el estado del mismo. Estos registros Hardware pueden ser ledos o escritos por el S.O. para facilitar las operaciones que se efectan sobre ellos. Estos registros suelen ser: Estado: indica el estado en que se encuentra el dispositivo (Interrupciones habilitadas o no, error de operacin, configuracin, etc.). Estos registros slo pueden ser ledos por el S.O., es decir, no pueden ser escritos. Operacin: por medio de este registro el S.O., a travs de un Driver, puede escribir indicando al dispositivo qu tipo de operacin es la que se solicita (entrada, salida, informacin del estado, etc.). Datos: Es el registro donde se colocan los datos relativos a la operacin de E/S. Estos registros tienen cuatro misiones: 1. Transferir el estado del dispositivo (Status): Por ejemplo si el dispositivo es la impresora seala si est encendida, con papel y en lnea; o, si est ocupado o desocupado el dispositivo. 2. Transferir instrucciones al dispositivo: cuando el procesador le seala a una unidad de disco la pista donde se va a colocar el cabezal para leer. 3. Transferir datos desde el dispositivo: en la lectura de un disco, los datos son pasados despus de ser ledos a los registros de la unidad de disco donde posteriormente sern accesados por el procesador.

4. Transferir datos al dispositivo: caso de envo de informacin a la impresora o a una unidad de disco o cinta. Para controlar la terminacin de una operacin de E/S se emplean dos mtodos:

Polling o Sondeo: que consiste en leer constantemente el registro de status del dispositivo; este mtodo tiene el inconveniente de ocupar el procesador un tiempo no deseado, ya que el procesador deber realizar un escrutinio de los dispositivos y mientras el dispositivo est ocupado se pierde tiempo de procesador en revisar el registro de status, hasta que el dispositivo se desocupe. Interrupciones: aqu el procesador contina con otros trabajos y slo cuando el dispositivo concluye la operacin de E/S llama la atencin del procesador, interrumpindole para que trate dicha situacin y realice las acciones que considere necesarias, es decir, sirva la interrupcin.

2.- CONTROLADORES: Existen dispositivos (como los discos) que no se conectan directamente al procesador, sino que lo hacen a travs de un Controlador que contiene el estado del dispositivo (status), controla el mismo y chequea los datos transferidos. Los controladores son conectados al procesador como si fueran dispositivos perifricos, comunicndose a travs de registros; stos controladores, tambin llamados unidades de control pueden manejar varios dispositivos del mismo tipo, como por ejemplo una unidad controladora de disco que realiza el control de los drives (3 y 5), y el disco duro. 3.- CANALES: Las unidades de control normalmente son conectadas al procesador por intermedio de un Canal (o Procesador de E/S que puede ser Multiplexor o Selector), esto es realizado con la finalidad de que los dispositivos perifricos sean tratados como virtuales, abstractos o transparentes. Estos canales son manejados a travs de comandos y cuando termina la operacin devuelven el status correspondiente e interrumpen al procesador.

Operaciones de E/S.
Las operaciones de E/S de los perifricos envuelve: Operaciones de Lectura/Escritura: Movimiento de Datos de un dispositivo de almacenamiento a otro.

Operaciones de Control: Instrucciones enviadas a los controladores de dispositivos para actividades tales como posicionar el mecanismo de control de acceso a un disco, devolver o saltar registros en una cinta, saltar pginas en una impresora, etc. Las operaciones de control normalmente preparan a los dispositivos para leer o grabar. Operaciones de Chequeo de estado: el estado (ocupado desocupado, apagado, etc.) de los dispositivos de E/S puede interrogarse a travs de instrucciones que permitan leer los registros de status del dispositivo.

Drivers o Software de Control de E/S:


Podemos definir un Driver como el software formado por un conjunto de rutinas y tablas que, formando parte del ncleo de un S.O., ejecutan y controlan todas las operaciones de E/S sobre cualquier dispositivo perifrico conectado a la computadora. Dichos Drivers son particulares para cada dispositivo, por lo cual el S.O. manejar: Una serie de Rutinas que controlan toda la gestin de los dispositivos y la informacin que fluye en un sentido y otro, y Tablas diferentes por cada uno de los dispositivos que estn conectados al sistema de computacin, donde se alojar la informacin que caracteriza a cada perifrico conectado. Los Drivers se encuentran alojados permanentemente en memoria principal (ya que forman parte del S.O.), y requieren de una elevada rapidez de ejecucin (bajo overhead), ya que no forman parte del proceso de usuario. Funciones de un Driver: 1. Definir las caractersticas del perifrico al resto del S.O. 2. Realizar Bootstrap, es decir, inicializar los registros asociados al perifrico en el momento de arranque. 3. Habilitar y deshabilitar al dispositivo para un proceso. 4. Procesar todas las operaciones de E/S solicitadas por un proceso. 5. Cancelar toda operacin de E/S que sea necesario por cualquier motivo. 6. Procesar todas la interrupciones de hardware generadas por el propio perifrico. 7. Tratar los errores y estado del dispositivo haciendo la correspondiente comunicacin al usuario. Rutinas de un Driver:

1. Inicializacin: Al inicializarse el Sistema, esta rutina se encarga de

2. 3.

4.

5.

inicializar el dispositivo incluyendo la informacin correspondiente a los registros de status y operacin del mismo. Atencin de peticiones de E/S: Atiende todas las solicitudes de E/S realizadas por los procesos de usuario. Gestin de Interrupciones(Interrupt Handler): Rutinas que manejan todas las interrupciones del dispositivo. Toma el control cuando el dispositivo perifrico origina una interrupcin al procesador. Cancelacin de operaciones de E/S: Esta rutina obliga a la cancelacin de una actividad que se est llevando a cabo en el perifrico, debido a alguna circunstancia de fuerza mayor, que obligue al Driver a tomar tal determinacin. Otras: como el Time-Out o rutina que controla el tiempo de proceso de la operacin y la rutina de Power Fail que le permite al dispositivo recuperarse despus de una cada del sistema.

Interrupciones Vectorizadas: Los S.O. estn capacitados para aceptar interrupciones que provienen de los perifricos; as para reconocer cual dispositivo es el causante de la interrupcin y poder darle el tratamiento adecuado, el S.O. destina parte de su memoria (la ms baja) para almacenar direcciones a manejadores de interrupciones asociados a cada dispositivo. Cada palabra almacenada que contiene la direccin de un manejador de interrupcin se conoce con el nombre de Vector de interrupcin que indica la palabra que contiene la direccin de una rutina que debe tratar una interrupcin. Los S.O. admiten un mximo de vectores de Interrupciones que es fijado en el momento de la generacin del mismo; un ejemplo de interrupciones vectorizadas es la interrupcin 21H del sistema operativo MS-DOS.

E/S Directa.
La mayora de los computadores antguos y algunos modernos tienen instrucciones "Directas" de Entrada/Salida. Por "Directa" entendemos el hecho de que la operacin de E/S es manejada exclusivamente por el procesador central. Esto incluyen las operaciones que inician la operacin, controlan las areas de E/S envueltas, mantiene la cuenta del nmero de caracteres transmitidos y chequean los errores. Cuando se utiliza este esquema el CPU no est disponible hasta que la instruccin de E/S haya sido completamente terminada; en otras palabras las instrucciones de E/S forman parte del conjunto de instrucciones de la mquina. El tiempo Tp requerido por un programa para su ejecucin es Tp=Tc+Tio, donde Tio es el tiempo requerido para la operacin de E/S y Tc es el tiempo interno que no es de E/S.

Normalmente se utilizan buffers como interfase entre los dispositivos de E/S. y la memoria principal. Una operacin de entrada toma la informacin del buffer y activa el dispositivo que llena nuevamente el mismo. El dispositivo de E/S est siempre en operacin adelante (en entrada) o atrs (en salida) del pograma. Si por ejemplo se tiene un programa que lee un archivo secuencial de disco, el buffer asociado al disco se llena con un registro antes de que el programa lo solicite; cuando el programa solicita el registro se hace una transferencia del bffer a un rea del programa y se inicia una operacin de entrada para llenar nuevamente el bffer. Los bffers son invisibles al programador y permiten la ejecucin paralela del dispositivo de E/S y el CPU. La utilizacin de I/O busy flags (Banderas de ocupado/desocupado) permite alcanzar un alto grado de control sobre los dispositivos. Estas banderas son registros de 1 bit que son , por ejemplo, puestos en 1 (true) por el hardware cuando el dispositivo est ocupado y en cero (false) cuando el dispositivo est libre. En un computador simple que utilice dos buffers llamados in y out, una instruccin de E/S producira las siguientes acciones del hardware. Entrada while flag loop end loop; inarea=in; flag=true; iniciar entrada; Salida while flag loop end loop; out=outarea; flag=true; Iniciar salida;

In y Out son buffers; inarea y outarea son reas de memoria que se usan para mantener los registros de E/S; flag es una bandera que indica si el dispositivo se encuentra ocupado/desocupado. En los programas presentados arriba, el CPU se encuentra continuamente en un lazo (loop), mientras el dispositivo se encuentre transmitiendo. Al terminar la transmisin el hardware apaga la bandera, el programa se sale del lazo e inicia otra operacin de E/S. Note que el CPU pudiera ejecutar rutinas que no envuelvan E/S mientras que el dispositivo asociado con la bandera se encuentre transmitiendo. If flag Then Calcule else Realice E/S; end if;

Las instrucciones anteriores implican que el CPU no se encuentra en un lazo contnuo, sino que realiza una operacin de clculo simultnemente con la entrada y salida de datos. La utilizacin de E/S directa constituye una manera ineficiente de resolver el problema de E/S entre la memoria y los dispositivos perifricos, ya que el CPU estar la mayor parte del tiempo esperando por la culminacin de las operaciones de E/S, dada la diferencia de velocidades que existen entre el procesamiento del CPU y la transmisin de informacin a/desde dispositivos perifricos. Mientras se espera por la culminacin de una operacin de E/S sera posible ejecutar miles de instrucciones.

E/S Indirecta.
Todos los sistemas de computacin tienen alguna forma de E/S indirecta con el objeto de alcanzar un paralelismo entre la operacin del CPU y las operaciones de E/S. bajo este esquema el procesador inicia las operaciones de E/S a travs de un pedido al canal, el cual pudiera ser expresado de la forma siguiente: startio(Nmero de Canal, Direccin) Donde el nmero de canal identifica un canal en particular, al cual est conectado el dispositivo involucrado en la E/S, y Direccin es la direccin de memoria donde empieza el programa de canal a ejecuta. Este programa de canal tiene las instrucciones necesarias para que el canal realice la operacin iniciada con la instruccin startio. Note que startio es una instruccin ejecutada por el CPU central y el canal ejecuta las instrucciones que llevan a cabo la E/S. El estado del canal puede ser interrogado por el CPU en cualquier momento. Para controlar esta operacin se utiliza una bandera o un registro asociado a cada canal. Se usar el operador booleano busy(i) para interrogar el estado del canal i. Las instrucciones: if not busy(i) then startio(i, Area); end if; Prueban el estado del canal i. Si no est ocupado la instruccin startio(i, Area) inicia una operacin de E/S. Otro mtodo de comunicacin entre el canal y el CPU es a travs de interrupciones. El canal interrumpe la operacin del CPU al terminar una operacin de E/S o cuando existen errores en la transmisin. Una interrupcin trae como resultado una transferencia de control a alguna direccin fija

asociada a la causa de la interrupcin y al estado de la mquina (contador de pociciones, registros, etc.) es guardado automticamente para que sea posible reiniciar el programa que se estaba ejecutando cuando ocurri la interrupcin (cambio de contexto). Es posible desactivar la ocurrencia de algunas interrupciones. Por ejemplo normalmente mientras se procesa una interrupcin puede ser deseable la desactivacin de nuevas interrupciones.

No piense que esto es un "Bug" Estamos en Construccin (Disculpe las molestias)

Buffers. Estructuras de corrutinas. Interrupciones. Mecansmos de sincronizacin.

Procesos
Hasta ahora hemos hablado de programas y procesos un poco vagamente, y como si fueran sinnimos. Lo cierto es que son conceptos distintos, porque un proceso es un programa en ejecucin, incluyendo el valor actual del program counter (PC), registros y variables. Un programa es pasivo (es slo cdigo o texto) y un proceso es activo y dinmico (vara en el tiempo). Conceptualmente cada proceso tiene su propia CPU virtual. En la prctica, hay una sola CPU real, que cambia peridicamente la ejecucin de un proceso a otro, pero para entender el sistema es ms fcil modelarlo como una coleccin de procesos que ejecutan concurrentemente (pseudoparalelismo).

Analoga: preparar una receta de una torta. El programa es la receta, el proceso es la actividad que consiste en leer la receta, mezclar los ingredientes y hornear la torta. Varios procesos pueden estar ejecutando el mismo programa, por ejemplo, si dos o ms usuarios estn usando simultneamente el mismo editor editor de texto. El programa es el mismo, pero cada usuario tiene un proceso distinto (y con distintos datos).

Estado de los procesos


Para efectos del sistema operativo, cada proceso puede estar en uno de los siguientes estados: Ejecutando. El proceso est siendo ejecutado en la CPU. Por lo tanto a lo ms un proceso puede estar en este estado en un computador uniprocesador. Listo. El proceso est en condiciones de ejecutarse, pero debe esperar su turno de CPU. Bloqueado. El proceso no est en condiciones de ejecutarse. Est esperando que algn evento ocurra, como la finalizacin de una operacin de I/O.

Pensando en trminos de scheduler y procesos, es ms fcil entender lo que pasa en el sistema. Todo el manejo de las interrupciones y de los detalles de echar a andar y suspender procesos estn escondidos en el scheduler (que es bastante pequeo). El resto del sistema operativo puede estructurarse como procesos,

que nada saben de interrupciones. Algunos procesos estn ejecutando programas en respuesta a comandos emitidos por los usuarios (o sea, son procesos de usuarios). Otros procesos forman parte del sistema; se encargan, por ejemplo de atender peticiones de otros procesos para manipular archivos, o de manejar algn dispositivo. Si ocurre, por ejemplo, una interrupcin de disco debido a que se complet una operacin previamente solicitada, el hardware se encarga de pasarle el control al scheduler, quien decide suspender al proceso que estaba ejecutando (lo pasa a LISTO), y ejecutar el proceso encargado del disco (que era el que haba solicitado la operacin).

Implementacin de procesos
Para implementar este modelo de procesos, el sistema operativo mantiene para cada proceso un bloque de control o process control block (PCB), donde se guarda para cada proceso la informacin necesaria para reanudarlo si es supendido, y otros datos.

Estado (ejecutando, listo, bloqueado) Program counter Registros de CPU Informacin para scheduling (por ejemplo, prioridad) Informacin para administracin de memoria (p.ej., registros base y lmite) Informacin de I/O: dispositivos y recursos asignados al proceso, archivos abiertos, etc. Estadsticas y otros: tiempo real y tiempo de CPU usado, identificador del proceso, id. del dueo, etc.

El sistema mantiene una cola con los procesos que estn en estado LISTO. Los procesos suspendidos se podran poner todos en otra cola, pero suele ser mas eficiente manejar colas distintas segn cual sea la condicin por la cual estn bloqueados. As, se maneja una cola de procesos para cada dispositivo.

Creacin de procesos
Hasta ahora hemos hablado harto de procesos, pero nos falta un detalle: cmo se crean y se destruyen procesos. Un proceso `padre' puede crear nuevos procesos `hijos' mediante llamadas al sistema. A su vez, estos hijos tambin pueden crear otros procesos, formndose as un rbol de procesos.

Por ejemplo, en Unix, cuando se carga el sistema operativo, se inicializa un proceso init. Este proceso lee un archivo que dice cuntos terminales hay, y crea un proceso login para cada terminal, que se encarga de solicitar nombre y password. Cuando un usuario entra, login determina que shell le corresponde al usuario, y crea otro proceso para ejecutar esa shell. A su vez, la shell crea ms procesos segn los comandos que ejecute el usuario. Un proceso se destruye cuando ste hace una llamada al sistema, pidindole que lo elimine. Tambin hay otras formas en que un proceso puede ser destruido. Un proceso puede destruir a otro (mediante una llamada al sistema). Obviamente, deben existir ciertas restricciones (por ejemplo, para que un usuario no pueda matar procesos de otro usuario, o del sistema). Por lo general, un proceso puede ser destruido slo por su padre o por el sistema. Otra situacin en que un proceso es destruido ocurre cuando el proceso provoca algn error fatal (p.ej., divisin por cero). Esto causa una interrupcin, y el sistema operativo lo destruye.

Hebras (Threads)
Motivacin Consideremos el problema productor-consumidor: un proceso produce items que son consumidos por un proceso consumidor. Para esto se usa un buffer que puede contener varios items; el productor va depositando los items a medida que los produce, y el consumidor los va sacando del buffer a medida que los va consumiendo. Por cierto, hay que preocuparse de que el productor no siga poniendo items si el buffer est lleno, y que el consumidor no intente sacar un item si el buffer est vaco, o sea, los procesos deben sincronizarse. Por ejemplo, para traducir de un idioma a otro, podramos tener un proceso que descompone cada frase en un idioma para determinar su estructura gramatical, y otro proceso que, a partir de la estructura gramatical compone una frase en el otro idioma. Las ventajas de resolver esta clase de problemas usando dos procesos, es que tenemos

Modularidad, ya que cada proceso realiza una funcin bien especfica. Disminucin en el tiempo de ejecucin en caso que contemos con ms de un procesador, ya que los procesos pueden trabajar en paralelo.

Pero tambin hay algunas desventajas:

Los procesos deben sincronizarse entre s, y deben compartir el buffer. Cmo puede hacerse esto si los procesos tiene espacios de direccionamiento disjuntos? (Recordemos que el sistema operativo no

permite que un proceso escriba en la memoria que le corresponde a otro proceso). Veremos formas de hacerlo, pero, por ahora, lo importante es que no es "natural": hay que hacerlo explcitamente. Para que la CPU suspenda un proceso y retome otro, debe hacer lo que se conoce como cabio de contexto (context-switch), y para eso, se requiere guardar el estado del proceso que est ejecutando, y cargar el estado que se haba guardado del nuevo proceso. El estado de un proceso comprende el PC y los registros de la CPU. Adems, si se usan las tcnicas de administracin de memoria que veremos ms adelante, hay ms informacin involucrada. Este cambio es puro overhead, puesto que entretanto la CPU no hace trabajo til (ningn proceso avanza). Considerando que la CPU hace varios cambios de contexto en un segundo, su costo es relativamente alto. Adems, al cambiar de un proceso a otro, como los espacios de direccionamiento son disjuntos, hay otros costos indirectos, que tienen relacin con el cache de la CPU.

Alternativa: threads o hebras o procesos livianos. Una hebra es un hilo de control dentro de un proceso. Un proceso pesado o tradicional tiene slo una hebra de control. Si usamos threads, entonces podemos tener varias hebras dentro de un proceso. Cada hebra representa una actividad dentro del proceso, es decir, tiene su propio PC, conjunto de registros y stack, pero comparte con las dems hebras el espacio de direccionamiento y los recursos asignados, como archivos abiertos y otros. En muchos aspectos los procesos livianos son similares a los procesos pesados: comparten el tiempo de CPU, y a lo ms un thread est activo (ejecutando) a la vez. Los otros pueden estar LISTOS o BLOQUEADOS. Pero los procesos pesados son independientes, y el sistema operativo debe proteger a unos de otros, lo que acarrea algunos costos. Los procesos livianos dentro de un mismo proceso pesado no son independientes: cualquiera puede accesar toda la memoria correspondiente al proceso pesado. En ese sentido, no hay proteccin entre threads: nada impide que un thread pueda escribir, por ejemplo, sobre el stack de otro. Bueno, quien debiera impedirlo es quien programa los threads, que es una misma persona (por eso no se necesita proteccin). Ventajas:

Context-switch entre threads de un mismo proceso es mucho ms barato que context-switch entre procesos; gracias a que comparten el espacio de direccionamiento, un cambio de contexto entre threads no incluye los registros y tablas asociados a la administracin de memoria. La creacin de threads tambin es mucho ms barata, ya que la informacin que se requiere para mantener un thread es mucho menos

que un PCB. La mayor parte de la informacin del PCB se comparte entre todos los threads del proceso. El espacio de direccionamiento compartido facilita la comunicacin entre los threads. Por ejemplo, no hay que hacer nada especial para que productor y consumidor compartan el buffer.

Implementacin de hebras Hay libreras de threads que permiten implementar hebras dentro de procesos normales o pesados sin apoyo del sistema operativo. El scheduling y manejo de las hebras se hace dentro del proceso. El sistema operativo no tiene idea de las hebras; slo ve y maneja un proceso como cualquier otro. La ventaja de este esquema es que los cambios de contexto entre hebras de un mismo proceso son extremadamente rpidos, porque ni siquiera hay una llamada al sistema de por medio. La desventaja es que si uno de los threads hace una llamada bloqueante (por ejemplo, solicita I/O), el sistema operativo bloquea todo el proceso, an cuando haya otros threads listos para ejecutar. La alternativa es que el propio sistema operativo provea servicios de threads; as como se pueden crear procesos, se pueden tambin crear nuevos threads dentro de un proceso, y stos son administrados por el sistema operativo. Usos Cul es un uso natural para las hebras? Ya vimos el caso productorconsumidor. Otro uso es en los servidores. Cada hebra en el servidor puede manejar una solicitud. El diseo es ms sencillo y este esquema mejora la productividad, porque mientras unos hilos esperan, otros pueden hacer trabajo til. Ejemplo: servidor de archivos, que recibe solicitudes para leer y escribir archivos en un disco. Para mejorar el rendimiento, el servidor mantiene un cach con los datos ms recientemente usados, en la eventualidad que reciba algn requerimiento para leer esos datos, no es necesario accesar el disco. Cuando se recibe una solicitud, se le asigna a un thread para que la atienda. Si ese thread se bloquea porque tuvo que accesar el disco, otros threads pueden seguir atendiendo otras solicitudes. La clave es que el buffer debe ser compartido por todos los threads, lo que no podra hacerse si se usa un procesos pesados para cada solicitud.

Sincronizacin

Muchos problemas se pueden resolver ms fcilmente o ms eficientemente si usamos procesos (o hebras) cooperativos, que ejecutan concurrentemente, tcnica que se conoce como pogramacin concurrente. La pogramacin concurrente es una herramienta poderosa, pero introduce algunos problemas que no existen en la programacin secuencial (no concurrente). Concurrencia = operaciones paralelas o pseudoparalelas (intercaladas). Supongamos que usamos dos hebras concurrentes para determinar cuntos nmeros primos hay en un intervalo dado.
int numPrimos = 0;

void primos (int ini, int fin) { for (i=ini; i<=fin; i++) if (primo(i)) numPrimos=numPrimos+1; }

Siendo Primos una variable global, podemos ejecutar primos(1,5000) en paralelo con primos(5001,10000) para saber cuntos nmeros primos hay entre 1 y 10000. El problema? numPrimos es una variable compartida que se accesa concurrentemente, y puede quedar mal actualizada si se dan determinadas intercalaciones de las operaciones de las dos hebras. Para ejecutar una operacin como numPrimos=numPrimos+1 se suelen requerir varias instrucciones de mquina, como por ejemplo:
LOAD numPrimos ADD 1 STORE numPrimos (cargar valor en el acumulador) (sumarle 1 al acumulador) (escribir acumulador de vuelta en memoria)

Supongamos que, ms o menos simultneamente, las dos hebras encuentran su primer nmero primo. Podra darse el siguiente timing (inicialmente, numPrimos==0).
Hebra 1 LOAD numPrimos ADD 1 LOAD numPrimos ADD 1 STORE numPrimos Hebra 2

STORE numPrimos

El resultado es que numPrimos queda en 1, pero lo correcto sera 2. El problema se produce porque las dos hebras o procesos tratan de actualizar una variable compartida al mismo tiempo; o mejor dicho, una hebra comienza a actualizarla cuando la otra no ha terminado. Esto se conoce como race condition: cuando el resultado depende del orden particular en que se intercalan las operaciones de procesos concurrentes. La cosa se resuelve si garantizamos que slo una hebra a la vez puede estar actualizando variables compartidas.

El problema de la seccin crtica


Modelo: n procesos, { P0, P1, ... , Pn-1}, cada uno de los cuales tiene un trozo de cdigo llamado seccin crtica, en el que accesa variables, o en general, recursos compartidos. El problema de la seccin crtica consiste en encontrar un mecanismo o protocolo que permita que los procesos cooperen de manera tal que se cumplan las siguientes condiciones:

Exclusin mutua. La ejecucin de las respectivas secciones crticas es mutuamente exclusiva, es decir, nunca hay ms de un proceso ejecutando su seccin crtica. Ausencia de postergacin innecesaria. Si un proceso quiere entrar en su seccin crtica mientras los otros estn ejecutando sus secciones nocrticas, entonces el primer proceso podr entrar. Entrada eventual. Si un proceso quiere entrar a la seccin crtica, entonces eventualmente (a la larga) entrar.

Podemos pensar que cada proceso ejecuta:


while(TRUE) { protocolo de entrada seccin crtica protocolo de salida seccin no crtica }

Vamos a suponer que:


Todos los procesos tienen oportunidad de ejecutar. Todo proceso que comienza a ejecutar su seccin crtica, ejecutar en algn momento el protocolo de salida. Las intrucciones bsicas de lenguaje de mquina como LOAD, STORE y TEST se ejecutan de forma atmica.

No debemos hacer ninguna suposicin respecto de la velocidad relativa de ejecucin de un proceso respecto de otro. Por ahora, vamos a restringir el anlisis al caso de dos procesos. Primer intento Deshabilitar interrupciones. Se descarta, por peligroso: un proceso de usuario con capacidad de deshabilitar interrupciones puede botar al sistema. Adems, no funcionara en multiprocesadores. Segundo intento Compartir una variable turno que indique quin puede entrar a la seccin crtica.
while (TRUE) { while (turno != 0); seccin crtica turno = 1; seccin no crtica }

Otro proceso: simtrico.

Provee exclusin mutua, pero hay postergacin innecesaria (estricta alternancia). Tercer intento Para remediar el problema de la alternancia estricta, podramos manejar ms informacin: interesado[i] est en verdadero si proceso i quiere entrar a la seccin crtica.
int interesado[2];

Proceso i: while (TRUE) { interesado[i] = TRUE; while (interesado[1-i]); seccin crtica interesado[i]=FALSE; seccin no crtica

Tampoco funciona: si ambos procesos ponen interesado[i] en TRUE al mismo tiempo, ambos quedan esperando para siempre. Podramos cambiar el orden: chequear primero y setear despes la variableinteresado, pero entonces podramos terminar con los dos procesos en la seccin crtica. Cuarto intento: algoritmo de Peterson Combinando las dos ideas anteriores podemos obtener un algoritmo que s funciona.
while (TRUE) {

int otro=1-i; interesado[i] = TRUE; turno = otro; while (interesado[otro] && turno==otro);

seccin crtica

interesado[i]=FALSE;

seccin no crtica }

Inicialmente interesado[0]=intersado[1]=FALSE y turno puede ser 1 o 0. Exclusin mutua. Supongamos que ambos procesos quieren entrar. Claramente, no pueden entrar al mismo tiempo, porque la condicin de espera en el while (interesado[otro] && turno==otro) no puede ser negativa para ambos procesos a la vez. Entonces supongamos que Pi entra primero. En ese caso, turno=i, y para que el otro entre, turno debe cambiar a 1-i, o bien interesado[i] a FALSE. El nico que hace esos cambios es el propio proceso i, y lo hace cuando est fuera de su seccin crtica. Ausencia de postergacin innecesaria. Si proceso i quiere entrar y el otro est ejecutando su seccin no crtica, entonces interesado[otro]==FALSE y Pi no tiene impedimento para entrar. Entrada eventual. Si un proceso quiere entrar, a lo ms debe esperar que el otro salga de la seccin crtica. Hay que tener cuidado cuando se demuestra esta

propiedad. En este caso, una vez que se cumple la condicin que permite a un proceso entrar, la condicin permanece al menos hasta que le toca la CPU al proceso que quiere entrar. Si la condicin fuera intermitente, hay que considerar que el scheduler puede ser nuestro enemigo y tomar decisiones de planificacin caprichosas, de manera de darle la CPU al proceso que quiere entrar justo cuando la condicin se apaga. Solucin para n procesos: en seccin 6.2.2 (Multiple-Process Solution, pgina 170) del Silberschatz (cuarta edicin). Con ayuda del hardware Muchos sistemas tienen instrucciones especiales que ayudan bastante a la hora de resolver el problema de la seccin crtica. En general, son instrucciones que de alguna manera combinan dos o tres operaciones en una sola operacin atmica. Por ejemplo, TEST-AND-SET (TS) lee el contenido de una direccin de memoria en un registro, y pone un 1 en la misma direccin, todo en una sola accin atmica o indivisible, en el sentido que ningn otro proceso puede accesar esa direccin de memoria hasta que la instruccin se complete. De cierto modo es equivalente a:
TS (registro,variable): deshabilitar interrupciones LOAD registro,variable STORE variable, 1 rehabilitar interrupciones

Con esto, una solucin al problema de la seccin crtica, en pseudoasssembler, sera:


Entrada: TS (R, lock) cmp R, 0 jne Entrada ret |Copiar lock a R, y poner lock en 1 |Haba un 0 en lock? |Si no era 0, repetir |Si era 0, retornar: podemos entrar

Salida:

store lock, 0 ret

|Volver lock a 0

Inicialmente, la variable lock est en 0. Este protocolo provee exclusin mutua sin postergacin innecesaria, y sirve para n procesos, pero no garantiza entrada eventual por qu? Solucin con entrada eventual: en seccin 6.3 (Synchronization Hardware, pgina 174) del Silberschatz (cuarta edicin).

Semforos
Inconvenientes de las soluciones anteriores:
1. Es difcil generalizarlas para problemas de sincronizacin ms

complejos que la seccin crtica. 2. Derrochan CPU, ya que usan espera ocupada (busy waiting): cuando un proceso quiere entrar a la seccin crtica, est permanentemente chequeando si puede hacerlo. Si el sistema operativo tuviera un mayor conocimiento de la situacin, podra bloquear a un proceso que quiere entrar a la seccin crtica, sin concederle oportunidad de ejecutar, mientras no pueda entrar. Una posibilidad es usar semforos. Un semforo S es un tipo abstracto de dato que puede manipularse mediante dos operaciones: P (o wait) y V (o signal), y cuyo efecto es equivalente a:
P(S): while (S.val<=0); S.val=S.val-1;

V(S): S.val=S.val+1;

donde S.val es un entero que corresponde al valor del semforo y que nunca debe ser negativo, y los incrementos y decrementos a S.val deben ejecutarse de manera indivisble o atmica. Usos El problema de la seccin crtica se puede resolver fcilmente con un semforo S, con valor inicial 1.
Semaphore S; // inicialmente en 1

while (TRUE) { P(S); seccin crtica V(S); seccin no crtica }

Tambin, si un queremos que un proceso P2 ejecute un trozo de cdigo C2 pero slo despus que P1 haya completado otro trozo C1, usamos semforo con valor inicial 0.
P1: C1; V(S);

P2: P(S); C2;

Implementacin Podramos implementar semforos usando directamente la definicin anterior, usando algn protocolo de exclusin mutua para proteger los accesos a S.val. Pero la idea era justamente no usar espera ocupada. Alternativa: ya que los semforos tienen una semntica precisa, el sistema operativo puede proveer semforos, y bloquear a un proceso que hace P(S) hasta que S.val sea positivo. Para implementarlos en el sistema operativo, adems del valor asociado al semforo, manejamos una lista con los procesos que estn bloqueados esperando que el valor se haga positivo.
struct Semaforo int val; PCB *Bloqueados; // Puntero al primer proceso de la lista // inicialmente NULL

P (Semaforo S) { if (S.val > 0) S.val=S.val-1; else { Poner proceso en la lista S.Bloqueados Ceder CPU } }

V (Semaforo S) { if (S.Bloqueados==NULL)

S.val=S.val+1; else Sacar un proceso de S.Bloqueados y ponerlo en READY }

Lo habitual es que la lista sea una cola FIFO, lo que garantiza que los procesos bloqueados no esperarn eternamente, pero la solucin sigue siendo correcta si se usa cualquier otra estrategia. Lo que falta por resolver es que la ejecucin de las operaciones P y V sea atmica. Dos posibilidades:
1. Deshabilitar interrupciones. Ahora no es peligroso, pues se trata de

rutinas del sistema operativo. No sirve para multiprocesadores. 2. Usar algn protocolo de exclusin mutua, como los que hemos visto. Otra vez tendramos espera ocupada! El punto es que ahora sabemos que las secciones crticas son muy cortas, y en consecuencia es muy poco probable que un proceso gaste mucha CPU esperando entrar a la seccin crtica. En cambio, la siguiente implementacin (ms directa de nuestra definicin inicial), tiene un problema. Cual? Cmo se podra remediar, sin cambiar la estructura de la solucin?
P (Semaforo S) { if (S.val <= 0) { Poner proceso en la cola S.Bloqueados Ceder CPU } S.val=S.val-1; }

V (Semaforo S) { S.val=S.val+1; if (S.Bloqueados!=NULL) Sacar un proceso de S.Bloqueados y ponerlo en READY }

Anexo: implementacin con espera ocupada y la debida atomicidad

Podemos usar protocolos de entrada y salida a una seccin crtica de la siguiente manera:
P (Semaforo S) { int OK=FALSE; while (!OK) { entrarSC(); if (S.val>0) { S.val--; OK=TRUE; } else Esperar un poco (optativo, pero conveniente); salirSC(); } }

V (Semaforo S) { entrarSC(); S.val++; salirSC(); }

Problemas clsicos de sincronizacin


Veremos algunos problemas de sincronizacin que son representaativos de grandes clases de problemas. Productores-consumidores con buffer limitado Buffer es una lista circular de n elementos, donde in apunta al prximo elemento desocupado, y out al elemento ms antiguo en el buffer.
Productor: while (TRUE) { nextP=producirElemento(); buffer[in]=nextP;

in = in+1 % n; }

Consumidor: while (TRUE) { nextC=buffer[out]; out = out+1 % n; consumirElemento(nextC); }

Pero: (1) buffer tiene capacidad limitada, y por ende productor no debe poner elementos cuando el buffer est lleno, y (2) consumidor no debe consumir cuando buffer est vaco. Usamos semforos lleno y vacio, cuyos valores corresponden, respectivamente, al nmero de posiciones ocupadas y desocupadas del buffer. Por lo tanto, lleno se inicializa en 0 y vaco en n.
Productor: while (TRUE) { nextP=producirElemento(); P(vacio); buffer[in]=nextP; in = in+1 % n; V(lleno); }

Consumidor: while (TRUE) { P(lleno); nextC=buffer[out]; out = out+1 % n; V(vacio); consumirElemento(nextC); }

Esta solucin funciona mientras haya slo 1 productor y un consumidor. Si hay ms, hay que evitar que dos consumidores consuman el mismo elemento, y que dos productores usen la misma posicin del buffer. Solucin: secciones

crticas, pero diferentes, de modo que un productor pueda operar en paralelo con un consumidor.
Productor: while (TRUE) { nextP=producirElemento(); P(vacio); P(mutexP); buffer[in]=nextP; in = in+1 % n; V(mutexP); V(lleno); }

Consumidor: while (TRUE) { P(lleno); P(mutexC); nextC=buffer[out]; out = out+1 % n; P(mutexC); V(vacio); consumirElemento(nextC); }

Lectores y escritores Un objeto, tal como un archivo o un registro de una base de datos, es compartido por varios procesos concurrentes. Hay procesos escritores, que modifican el objeto, y procesos lectores, que slo lo consultan. Puede haber mltiples procesos leyendo el objeto simultneamente, pero cuando hay un proceso escribiendo, no puede haber ningn lector ni ningn otro escritor.
Escritor: P(wrt); escribir();

V(wrt);

es un semforo inicializado en 1. La idea es que los escritores, como bloque, tmabin hagan P(wrt) y V(wrt) de manera de impedir accesos concurrentes por parte de lectores y escritores. Solucin: primer lector que llega hace P(wrt), y el ltimo que sale hace V(wrt).
wrt Lector: P(mutex); lectores++; if (lectores==1) P(wrt); V(mutex); // Somos los primeros en llegar

leer();

P(mutex); lectores--; if (lectores==0) V(wrt); V(mutex); // Somos los ltimos en salir

Esta solucin no es justa, ya que da prioridad a los lectores: si hay un flujo constante de lectores, los escritores nunca podrn escribir. Una alternativa es impedir que entren ms lectores si es que hay algn escritor esperando, lo cual slo invierte el problema: ahora los lectores podran esperar indefinidamente. Los filsofos comensales Cinco filsofos pasan la vida alternando entre comer y pensar, alrededor de una mesa redonda. Como son medio torpes, requieren dos tenedores para comer, pero como son pobres, slo tienen 5 tenedores. Han acordado que cada uno usar slo los tenedores a su izq. y a su derecha. Entonces, de los 5 filsofos, slo 2 pueden comer al mismo tiempo, y no pueden comer dos que son vecinos.

Una posibilidad: representar cada tenedor con un semforo inicializado en 1 (Semaforo tenedor[5];), y cada filsofo i hace:
while (TRUE) { P(Tenedor[i]); P(Tenedor[i+1 % 5]); comer(); P(Tenedor[i]); P(Tenedor[i+1 % 5]); pensar(); }

Problema: bloqueo mutuo. Soluciones posibles:


Usar solucin asimtrica: uno de los filsofos toma primero el tenedor i+1%5 y despes el i. Permitir que un filsofo tome sus tenedores slo si ambos estn disponibles (y hacerlo dentro de una seccin crtica). Permitir que slo cuatro filsofos se sienten en la mesa.

Estas soluciones evitan bloqueo mutuo, pero tambin es conveniente asegurar que ningn filsofo muera de hambre. Si un proceso es postergado indefinidamente se dice que sufre de inanicin o starvation (an cuando no haya comida de por medio).

Planificacin (scheduling) de procesos


Cuando hay ms de un proceso que est en condiciones de ejecutar en la CPU, se debe escoger alguno. El encargado de tomar esa decisin es el planificador o scheduler, y el algoritmo que usa se llama algoritmo de planificacin. Posibles objetivos (algunos de ellos contradictorios) del algoritmo de planificacin son:

Justicia. Asegurarse que todos los procesos tengan su turno de CPU. Eficiencia. Mantener la CPU ocupada todo el tiempo. Tiempo de respuesta. Minimizar el tiempo de respuesta de los usuarios interactivos. Rendimiento o productividad (throughput). Maximizar el nmero de trabajos terminados por hora. Tiempo de espera. Minimizar el tiempo medio de espera (en la cola READY) de los procesos.

Una complicacin adicional que hay que tener presente es que cada proceso es nico e impredecible. Algunos pierden la mayor parte del tiempo esperando por I/O (son I/O-bound o intensivos en I/O), otros ms que nadaq requieren tiempo de CPU (son CPU-bound o intensivos en CPU). En cualquier caso, todos los procesos alternan entre una fase de ejecucin de CPU y otra de espera por I/O. Aunque la duracin de las fases de CPU es impredecible y vara mucho entre un proceso y otro, tiende a tener una frecuencia como la de la figura: hay un gran nmero de fases de CPU cortos, y muy pocos largos. Esta informacin puede ser importante para seleccionar un algoritmo de planificacin adecuado.

Cundo hay que planificar? Recordando el diagrama...

...una decisin de planificacin puede o debe tomarse cuando ocurre cualquiera de las siguientes transiciones entre estados de un proceso: 1. 2. 3. 4. EJECUTANDO a BLOQUEADO. EJECUTANDO a TERMINADO. EJECUTANDO a LISTO. BLOQUEADO a LISTO.

En los casos 1 y 2, necesariamente hay que escoger un nuevo proceso, pero en los casos 3 y 4 podra no tomarse ninguna decisin de scheduling, y dejar que contine ejecutando el mismo proceso que estaba ejecutando. En ese caso, se habla de planificacin no-expropiadora (nonpreemptive) (Windows 3.x). Si en cambio se toma una decisin de scheduling en los casos 3 y 4, entonces se habla de planificacin expropiadora. Esta ltima es ms segura y ms justa, pero tiene un problema: consideremos dos procesos que comparten informacin, y que a uno de ellos se le quita la CPU justo cuando estaba en medio de una actualizacin de los datos compartidos. Cuando sea el turno del segundo proceso, ste podra intentar leer los datos cuando estn en un estado inconsistente. Este problema se remedia con sincronizacin. A continuacin veremos distintos algoritmos de planificacin.

El primero que llega se atiende primero


FCFS (First-come, first-served) por sus siglas en ingls. Es un algoritmo que no usa expropiacin, y que consiste en atender a los procesos por estricto orden de llegada a la cola READY. Cada proceso ejecuta hasta que termina, o

hasta que hace una llamada bloqueante (de I/O), o sea, ejecuta su fase de CPU completa. La gracia es que se trata de un algoritmo muy simple: la cola READY se maneja como una simple cola FIFO. El problema es que el algoritmo es bastante malo, pero estudiando porque es malo, podremos encontrar algoritmos mejores.
Tiempo de espera

Consideremos que los procesos P1, P2 y P3 estn LISTOS para ejecutar su siguiente fase de CPU, cuya duracin ser de 24, 3 y 3 milisegundos, respectivamente. Si ejecutan en el orden P1, P2, P3, entonces los tiempos de espera son: 0 para P1, 24 para P2 y 27 para P3, o sea, en promedio, 17 ms. Pero si ejecutan en orden P2, P3, P1, entonces el promedio es slo 3 ms. En consecuencia, FCFS no asegura para nada que los tiempos de espera sean los mnimos posibles; peor an, con un poco de mala suerte pueden llegar a ser los mximos posibles.
Utilizacin de CPU

Ahora supongamos que tenemos un proceso CPU-bound y varios I/O-bound. Entonces podra pasar lo siguiente: El proceso CPU-bound toma la CPU por un perodo largo, suficiente como para que todas las operaciones de I/O pendientes se completen. En esa situacin, todos los procesos estn LISTOS, y los dispositivos desocupados. En algn momento, el proceso CPU-bound va a solicitar I/O y va a liberar la CPU. Entonces van a ejecutar los otros procesos, pero como son I/O bound, van a liberar la CPU muy rpidamente y se va a invertir la situacin: todos los procesos van a estar BLOQUEADOS, y la CPU desocupada. Este fenmeno se conoce como efecto convoy, y se traduce en una baja utilizacin tanto de la CPU como de los dispositivos de I/O. Obviamente, el rendimiento mejora si se mantienen ocupados la CPU y los dispositivos (o sea, conviene que no haya colas vacas).

El trabajo ms corto primero


SJN (shortest-job-next) por sus siglas en ingls. Supongamos que tenemos tres procesos cuyas prximas fases de CPU son de a, b y c milisegundos de duracin. Si ejecutan en ese orden, el tiempo medio de espera es: 0 + a + (a + b) = 2a+b O sea, el primer proceso que se ejecute es el que tiene mayor incidencia en el tiempo medio, y el ltimo, tiene incidencia nula. En conclusin, el tiempo medio se minimiza si se ejecuta siempre el proceso con la menor prxima fase de CPU que est LISTO. Adems, es una buena manera de prevenir el efecto

convoy. Lo malo es que para que esto funcione, hay que adivinar el futuro, pues se requiere conocer la duracin de laprxima fase de CPU de cada proceso. Lo que se hace es predecir la prxima fase de CPU en base al comportamiento pasado del proceso, usando un promedio exponencial. Supongamos que nuestra prediccin para la n-sima fase es Tn, y que en definitiva result ser tn. Entonces, actualizamos nuestro estimador para predecir Tn+1 Tn+1 = (1-a) tn + a Tn El parmetro a, entre 0 y 1, controla el peso relativo de la ltima fase en relacin a la historia pasada. Tn+1 = (1-a)tn + a(1-a)tn-1 + ... + aj(1-a)tn-j+ ... + an+1T0 O sea, mientras ms antigua la fase menos incidencia tiene en el estimador. Un valor atractivo para a es 1/2, ya que en ese caso slo hay que sumar los valores y dividir por dos, operaciones especialmente fciles en aritmtica binaria.

Planificacin por prioridad


SJN es un caso especial de planificacin por prioridad, en la cual a cada proceso se le asigna una prioridad, y la CPU se asigna al proceso con mayor prioridad en la cola READY. SJF es planificacin por prioridad donde la prioridad es funcin del estimador de la duracin de la prxima fase de CPU. Este tema da para mucho, pues hay muchas formas de definir la prioridad. La prioridad puede definirse de manera esttica o dinmica; interna o externa. Ejemplos:

Segn categora del usuario (externa). Segn tipo de proceso: sistema, interactivo, o por lotes; o bien, CPUbound o I/O bound (interna). Segn cuanto hayan ocupado la CPU hasta el momento (dinmica). Para evitar que un proceso de baja prioridad sea postergado en demasa, aumentar prioridad mientras ms tiempo lleve esperando: aging o envejecimiento (dinmica). Para evitar que un proceso de alta prioridad ejecute por demasiado tiempo, se puede poner un lmite de tiempo, o ir bajando la prioridad.

Round-robin (RR)
Volviendo a FCFS, una forma obvia de mejorarlo es agregando expropiacin o preemption de manera que cada proceso no retenga la CPU por ms de un quantum o tajada de tiempo predefinida. FCFS con tajada de tiempo se conoce como round-robin, y se implementa igual que FCFS, solo que antes de cederle la CPU a un proceso se echa a andar el timer para que provoque una

interrupcin dentro de un quantum de tiempo. El proceso ejecuta hasta que haga una llamada bloqueante o hasta que use toda su tajada se tiempo. En cualquiera de los dos casos, la CPU se entrega al siguiente en la cola READY. El punto interesante es encontrar el quantum adecuado. Si es muy grande, la cosa degenera en FCFS, pero tampoco puede ser demasiado pequeo, porque entonces el costo en cambios de contexto es preponderante. Por ejemplo, si un cambio de contexto toma 5 ms, y fijamos el quantum en 20 ms, entonces 20% del tiempo de la CPU se perder en overhead. Un valor tpico es 100 ms. Una regla que suele usarse es que el 80% de las fases de CPU deben ser de menor duracin que un quantum. Con respecto a FCFS, se mejora el tiempo de respuesta y la utilizacin de la CPU, ya que se mantienen ms balanceadas las colas READY y BLOCKED. Pero RR tampoco asegura que los tiempos de espera sean los mnimos posibles. Usando el mismo ejemplo anterior, y considerando un quantum de 4ms, pero sin considerar costos de cambio de contexto, si el orden es P1, P2, P3 entonces el tiempo medio de espera es 5.66ms (por qu?).

Mltiples colas
Para complicar ms la cosa, podemos agrupar los procesos en distintas clases, y usar distintos algoritmos de planificacin intra-clase, ms algn algoritmo inter-clases. Por ejemplo, los procesos interactivos y los procesos por lotes tienen distintos requerimientos en cuanto a tiempos de respuesta. Entonces, podemos planificar los proceso interactivos usando RR, y los procesos por lotes segn FCFS, teniendo los primeros prioridad absoluta sobre los segundos. Una forma de implementar este algoritmo es dividiendo la cola READY en varias colas, segn la categora del proceso. Por ejemplo, podemos tener una cola para

Procesos de sistema. Procesos interactivos. Procesos de los alumnos. Procesos por lotes.

Cada cola usa su propio algoritmo de planificacin, pero se necesita un algoritmo de planificacin entre las colas. Una posibilidad es prioridad absoluta con expropiacin. Otra posibilidad: asignar tajadas de CPU a las colas. Por ejemplo, a la cola del sistema se le puede dar el 60% de la CPU para que haga RR, a la de procesos por lotes el 5% para que asigne a sus procesos segn FCFS, y a las otras el resto.

Por otra parte, podramos hacer que los procesos migren de una cola a otra. Por ejemplo: varias colas planificadas con RR, de prioridad decreciente y quantum creciente. La ltima se planifica con FCFS. Un proceso en la cola i que no termina su fase de CPU dentro del quantum asignado, se pasa al final de la siguiente cola de menor prioridad, pero con mayor quantum. Un proceso en la cola i que s termina su fase de CPU dentro del quantum asignado, se pasa al final de la siguiente cola de mayor prioridad, pero con menor quantum. Ejemplo: Cola 0: quantum=10 ms, 40% de CPU. Cola 1: quantum=20 ms, 30% de CPU. Cola 2: quantum=35 ms, 15% de CPU. Cola 3: FCFS, 5% de CPU. As los procesos de fases ms cortas tienen prioridad. Este algoritmo es uno de los ms generales, pero tambin uno de los ms complejos de implementar. Tambin es difcil de afinar, pues hay mltiples parmetros que definir.

Planificacin en dos niveles


Hasta ahora de alguna manera hemos supuesto que todos los procesos ejecutables estn en memoria. Pero si hay poca memoria disponible y muchos procesos, entonces algunos procesos deben mantenerse en disco, lo que cambia radicalmente la problemtica de la planificacin, porque el tiempo requerido para hacer un cambio de contexto que involucre traer un proceso del disco es muchsimo mayor que el tiempo de un cambio de contexto entre procesos en memoria. Las cosas se simplifican si se divide el problema en dos, y se usa un scheduler distinto para cada caso. Un scheduler de corto plazo se encarga slo de decidir a qu proceso se le asigna la CPU, de entre todos los que estn en memoria. Peridicamente, otro scheduler de largo plazo decide qu procesos que han estado demasiado tiempo en memoria deben ser pasados a disco para dar oportunidad a procesos que han estado mucho rato en el disco. Para tomar esa decisin se pueden usar factores como el tiempo que un proceso lleva en memoria o disco, cantidad de CPU usada hasta el momento, tamao del proceso, prioridad, etc.

Planificacin en multiprocesadores
Cuando hay varias CPUs (y una memoria comn), la planificacin tambin se hace ms compleja. Podramos asignar una cola READY a cada procesador, pero se corre el riesgo de que la carga quede desbalanceada: algunos procesadores pueden llegar a tener una cola muy larga de procesos para ejecutar, mientras otros estn desocupados (con la cola vaca). Para prevenir

esta situacin se usa una cola comn de procesos listos. Este enfoque tiene dos alternativas:
1. Cada procesador es responsable de su planificacin, y saca procesos de

la cola READY para ejecutar. El problema? Hay ineficiencias por la necesaria sincronizacin entre los procesadores para accesar la cola. 2. Dejar que slo uno de los procesadores planifique y decida qu procesos deben correr los dems: multiprocesamiento asimtrico.

Evaluacin de los algoritmos


Est claro que hay numerosas alternativas de planificacin. cmo seleccionar una? Primero, hay que definir qu mtricas son las que nos importan ms: por ejemplo, maximizar la utilizacin de la CPU pero con la restriccin que el tiempo de respuesta no supere 1 segundo. Despus hay que escoger un mtodo para evaluar los algoritmos y ver cul se ajusta mejor al criterio escogido. Modelacin determinista Tomamos un caso en particular, y determinamos analticamente la medida de inters. Por ejemplo, (Proceso, fase de CPU): (P1, 10), (P2,30), (P3, 5). Podemos medir el tiempo medio de espera para FCFS, SJF, y RR con quantum de 8 ms. Desventajas: es demasiado especfico y requiere un conocimiento muy exacto de la situacin. Ventajas: es rpido. Analizando muchos casos se puede encontrar una tendencia. Modelos de colas A pesar de que cada proceso es nico e impredecible, s podemos determinar experimentalmente una distribucin de las duraciones de las fases de CPU y de I/O. Tpicamente esta distribucin es exponencial. De la misma manera podemos determinar la distribucin probabilstica de los tiempos de llegada de nuevos procesos. El sistema entonces se modela como una coleccin de servidores (CPU y dispositivos), que atienden procesos. Conociendo la distribucin de los tiempos de llegada y de atencin, se pueden determinar mtricas como utilizacin (porcentaje de uso de los servidores), tamaos medios de las colas y tiempos medios de espera. El problema es que para que el modelo sea matemticamente tratable, hay que hacer simplificaciones y suposiciones que no siempre son realistas. Siendo as, los resultados son aproximados. Simulaciones

Para obtener una evaluacin ms acuciosa, podemos hacer una simulacin: en vez de resolver el modelo matemticamente, lo programamos y vemos como se comporta (Nachos es un ejemplo). El simulador tiene una variable que representa el reloj, y a medida que sta se incrementa se modifica el estado del simulador para reflejar las actividades de los diversos elementos simulados, a la vez que se van computando las estadsticas del caso. Los eventos que van a conducir la simulacin pueden generarse segn su distribucin probabilstica, o tambin pueden provenir del monitoreo de un sistema real. Los resultados van a ser muy exactos, pero el problema de las simulaciones es que son caras. Implementacin En trminos de exactitud, lo mejor es programar en el sistema operativo el algoritmo que queremos evaluar, echarlo a andar y ver cmo se comporta. Pero:

Tambin es caro. Los sistemas reales, con usuarios de verdad, no son muy adecuados para hacer experimentos. La propia implantacin del algoritmo puede modificar el comportamiento de los usuarios, desvirtuando las mediciones.

Bloqueos mutuos (deadlocks)


Cuando tenemos muchos procesos que compiten por recursos finitos, puede darse una situacin en la que un proceso est bloqueado esperando por un recurso que nunca se liberar, porque lo posee otro proceso tambin bloqueado. Ley de principios de siglo, en Kansas: "cuando dos trenes se aproximan a un cruce, ambos deben detenerse completamente, y ninguno podr continuar hasta que el otro se haya ido." Otro ejemplo: solucin al problema de los filsofos comensales del captulo anterior. Otro ejemplo similar: los semforos Q y S controlan acceso a recursos compartidos, y:
Proceso 0: P(Q); P(S); usar recursos Proceso 1: P(S); P(Q); usar recursos

V(S); V(Q);

V(Q); V(S);

Caracterizacin
Un conjunto de procesos C est bajo bloqueo mutuo si cada proceso en C est esperando por un evento que slo otro proceso de C puede causar. Tal evento es tpicamente la liberacin de un recurso fsico (como impresora) o lgico (como registros o semforos). Para que haya deadlock, deben darse simultneamente las siguientes condiciones: 1. Exclusin mutua. Los recursos no son compartidos. Si un proceso est usando un recurso, otros no pueden hacerlo. 2. Retencin y espera. Hay procesos que tienen recursos asignados y al mismo tiempo estn esperando poder adquirir otros recursos. 3. No expropiacin. Los recursos no pueden ser expropiados a los procesos. (Ejemplo: impresora). 4. Espera circular. Existe un conjunto {P0, P1, ..., Pn} de procesos tales que el proceso Pi est esperando por un recurso retenido por Pi+1 para 0 <= i < n, y Pn est esperando recurso retenido por P0. En rigor, espera circular implica retencin y espera, pero es til separar las condiciones, pues basta con que una no se d para que no haya bloqueo mutuo. Una forma de modelar estas condiciones es usando un grafo de recursos: crculos representan procesos, los cuadrados recursos. Una arista desde un recurso a un proceso indica que el recurso ha sido asignado al proceso. Una arista desde un proceso a un recurso indica que el proceso ha solicitado el recurso, y est bloqueado esperndolo. Entonces, si hacemos el grafo con todos lo procesos y todos los recursos del sistema y encontramos un ciclo, los procesos en el ciclo estn bajo bloqueo mutuo.

Mtodos para manejar bloqueos mutuos


No hacer absolutamente nada Los deadlocks son evidentemente indeseables. Los recursos retenidos por los procesos bajo bloqueo mutuo no estn disponibles para otros procesos, y los procesos en deadlock no pueden avanzar. Pero si un deadlock se produce, en promedio, cada diez aos y en cambio el sistema se cae todos los das por

fallas en el hardware o en el sistema operativo, entonces el problema de los bloqueos mutuos es irrelevante. Muchos sistema operativo modernos (UNIX entre ellos) no se preocupan de evitar deadlocks (porque es caro y los procesos deben someterse a ciertas restricciones), pero algunas tendencias hacen que el tema vaya adquiriendo importancia: a medida que progresa la tecnologa, tiende a haber ms recursos y ms procesos en un sistema. Deteccin y recuperacin Una posibilidad es monitorear cada cierto tiempo el estado del grafo de recursos. (Cada cunto?) Si se detecta un ciclo, se matan todos los procesos del ciclo (se usa!), o se van matando procesos del ciclo hasta que no queden ciclos (cul matar primero?). Es un mtodo drstico, pero mejor que nada. Prevencin Una tercera estrategia es imponer restricciones a los procesos de manera de hacer estructuralmente imposible la ocurrencia de un bloqueo mutuo. La idea es asegurar que no se d al menos una de las cuatro condiciones necesarias para que haya deadlock.
Exclusin mutua.

Hay recursos que son intrnsecamente no compartibles, de modo que no se puede descartar la exclusin mutua.
No expropiacin.

Esta condicin se puede eliminar imponiendo expropiacin. Si un proceso P tiene recursos y solicita otro que est ocupado, se le pueden expropiar a P los que ya tiene, o bien expropiarle al otro proceso el recurso que P necesita. Es aplicable a cierta clase de recursos (cuyo estado se puede almacenar y luego recuperar), pero no a otros como registros de base de datos o impresoras.
Retencin y espera.

Podemos impedir esta condicin exigiendo que los procesos soliciten de una vez, al comienzo, todos los recursos que van a necesitar. Si uno o ms recursos no estn disponibles, el proceso se bloquea hasta que pueda obtenerlos todos. Inconvenientes: muchos procesos no pueden saber de antemano qu y cuntos recursos necesitarn. Subutilizacin de recursos, ya que quedan retenidos de principio a fin de la ejecucin.

Alternativa: Hacer que los procesos liberen todos los recursos que tienen antes de solicitar un nuevo conjunto de recursos. Tambin tiene inconvenientes: por ejemplo, programa que usa archivo temporal durante toda su ejecucin. Si lo libera entremedio, otro proceso se lo puede borrar.
Espera circular.

Podemos evitar la espera circular si imponemos un orden total a los recursos (o sea, asignamos a cada recurso R un nmero nico F(R)), y obligamos a los procesos a que soliciten recursos en orden: un proceso no puede solicitar Q y despus R si F(Q)>F(R). Por ejemplo:

F(CD-ROM)=1 F(impresora)=2 F(plotter)=3 F(Cinta)=4

De esta manera se garantiza que no se generarn ciclos en el grafo de recursos. Una mejora inmediata es exigir solamente que ningn proceso solicite un recurso cuyo nmero es inferior a los recursos que ya tiene. Pero tampoco es la panacea. En general, el nmero potencial de recursos es tan alto que es difcil dar con tal funcin F para ordenarlos. Evitacin En vez de restringir la forma u orden en que los procesos deben solicitar recursos, antes de conceder un recurso, chequeamos que sea seguro. Hay diversos algoritmos, que varan en el tipo de informacin que requieren a priori de cada proceso. En el que vamos a ver, necesitamos que cada proceso declare la cantidad mxima de recursos de cada clase que va a necesitar: Por ejemplo: 2 unidades de cinta, una impresora lser y 200 bloques de disco, como mximo. (El sistema puede tener varias unidades de cinta y varias impresoras lser idnticas).
Estado seguro

Un estado de asignacin de recursos es el nmero de recursos disponibles y asignados, y el mximo declarado por cada proceso. Ejemplo: Sistema con 12 unidades de cinta y 3 procesos.

Mximo Actual Diferencia Disponible P Q R 10 4 9 5 2 2 5 2 7 3

Un estado seguro es un estado en el cual el sistema puede asignar recursos a los procesos (hasta su mximo) en alguna secuencia, y evitar deadlock. Ms formalmente, un estado es seguro slo si existe una secuencia segura, es decir, una secuencia de procesos <P1, P2,...,Pn > donde, para cada Pi, los recursos que Pi an puede solicitar pueden satisfacerse con los recursos disponibles y los retenidos por Pj con j<i. Si los recursos que Pi necesita no estn disponibles, Pi puede esperar hasta que los Pj terminen. Si no existe tal secuencia, se dice que el sistema est en un estado inseguro. El estado del ejemplo es seguro, ya que la secuencia <Q,P,R > satisface la condicin de seguridad. Si en ese estado se le concede una unidad ms a R, entonces pasamos a un estado inseguro. Un estado inseguro no necesariamente implica que se va a producir deadlock, pero se corre el riesgo. En cambio, mientras el sistema est en un estado seguro, no puede haber deadlock. La clave entonces es no pasar a un estado inseguro; en el ejemplo, no se le puede conceder otra unidad a R; si la solicita, hay que suspenderlo, aunque el recurso est disponible. Esto significa que habr una subutilizacin de los recursos que no existira si no se hiciera nada para manejar los bloqueos mutuos.
Algoritmo del banquero

Sistematizando y generalizando para mltiples recursos, obtenemos el algoritmo del banquero (se supone que los procesos son clientes que piden crdito, y los recursos corresponden al dinero del que dispone el banco). La idea es bsicamente la misma, slo que debemos manejar vectores en vez de escalares. Por ejemplo, para 5 procesos y 3 recursos, Mximo, Actual y Diferencia, que antes eran columnas, ahora son matrices de 5x3; y Disponible, que antes era un escalar, ahora es un vector de 3 elementos.

Mximo Actual Diferencia Disponible A B C A B C P0 7 5 3 0 1 0 P1 3 2 2 2 0 0 P2 9 0 2 3 0 2 P3 2 2 2 2 1 1 P4 4 3 3 0 0 2 A B C 7 1 6 0 4 4 3 2 2 0 0 1 1 3 1 A 3 B 3 C 2

Para chequear si un estado, como el anterior, es seguro: Buscar un proceso (cualquiera) cuyos recursos mximos puedan satisfacerse con los disponibles (ms los que ya tiene); o sea, un proceso tal que Diferencia <= Disponible, componente a componente. Si no existe, el estado es inseguro. 2. Si existe, suponer que el proceso termina y libera todos sus recursos, agregndolos a los disponibles. 3. Repetir 1 y 2 hasta haber pasado por todos los procesos, en cuyo caso el estado es seguro, o hasta determinar que el estado es inseguro.
1.

En el ejemplo, podemos escoger primero P1 o P3 (da igual); escojamos P1. Al terminar, los recursos disponibles quedan en <4,5,4 >. Ahora podemos escoger P3 o P4, y as, hasta determinar que el estado es seguro. Supongamos ahora que, en ese estado, P1 pide 1 instancia adicional de A y 2 de C. Los recursos estn disponibles, pero antes de concedrselos a P1, debemos chequear si el nuevo estado sera seguro o no. Dicho estado sera:

Mximo Actual Diferencia Disponible A B C A B C P0 7 5 3 0 1 0 P1 3 2 2 3 0 2 A B C 7 0 4 3 2 0 A 2 B 3 C 0

P2 9 0 2 3 0 2 P3 2 2 2 2 1 1 P4 4 3 3 0 0 2

6 0 4

0 0 1 1 3 1

y tambin es seguro, ya que la secuencia <P1, P3, P4, P0, P2 > es segura. En consecuencia, podemos otorgar los recursos solicitados por P1. Si en ese nuevo estado, P4 pide ahora 3 unidades de A y 3 de B, entonces P4 debe suspenderse porque no hay suficientes recursos para satisfacer el pedido. Si P3 pide 2 unidades adicionales de B, simplemente abortamos el proceso, pues no cumplira con el mximo declarado. Y si P0 pide 2 unidades de B, tambin debe suspenderse, pero en este caso porque si se le otorgan, el estado pasara a ser inseguro. Cada vez que algn proceso libera recursos, debera chequearse cules de las solicitudes pendientes pueden atenderse. Este algoritmo fue publicado en 1965 y ha sido objeto de innumerables estudios. En teora funciona muy bien, pero en la prctica, rara vez se usa, puesto que es muy difcil para los procesos saber a priori sus necesidades mximas de cada recurso. En resumen, los algoritmos de prevencin son extremadamente restrictivos y los de evitacin requieren informacin que por lo general no est disponible. Por eso, los mtodos de deteccin y recuperacin no son tan poco usuales ni descabellados. Tambin se usan mtodos adecuados a situaciones especficas, pero no existe ningn mtodo mentholatum (que sirva para todo).

Administracin de memoria
La memoria es un recurso escaso, y para aprovecharla bien hay que administrarla bien. A pesar de que la memoria es ms barata cada da, los requerimientos de almacenamiento crecen en proporcin similar. Por otra parte, la memoria ms rpida es obviamente ms cara, por lo que la mayora de los computadores tiene una jerarqua de memoria. Por ejemplo, en un Pentium tpico:
1. Cach de nivel 1: 8 KB empaquetados dentro del chip; por lo mismo, la

velocidad de acceso es de unos pocos nanosegundos.

2. Cach de nivel 2: 256 a 512 KB, 12-20 ns, U$80/MB 3. Memoria RAM: 8 a 32 MB, 70ns, U$10/MB 4. Disco duro. Para almacenamiento estable, y tambin para extender la RAM de manera virtual. 1GB, 10ms, U$0.3/MB. 5. Cinta. 1 a 40 GB. U$0.02/MB.

Administracin bsica
Monoprogramacin La forma ms simple de administrar memoria es ejecutando slo un programa a la vez, compartiendo la memoria con el sistema operativo. Por ejemplo, MSDOS, en direcciones crecientes de memoria: Sistema operativo; programa de usuario; manejadores de dispositivos (en ROM). Cuando usuario digita un comando, el sistema operativo carga el programa correspondiente en la memoria, y lo ejecuta. Cuando el programa termina, el sistema operativo solicita un nuevo comando y carga el nuevo programa en la memoria, sobreescribiendo el anterior. Multiprogramacin con particiones fijas Ya hemos hablado bastante de las ventajas de la multiprogramacin, para aumentar la utilizacin de la CPU. La forma ms simple de obtener multiprogramacin es dividiendo la memoria en n particiones fijas, de tamaos no necesariamente iguales, como lo haca el IBM 360 (dcada del 60; hoy es raro encontrarlo). Puede haber una cola de trabajos por particin, o bien una sola cola general. En el primer caso, cuando llega un trabajo, se pone en la cola de la particin ms pequea en la que todava quepa el trabajo. Si llegan muchos trabajos pequeos podra pasar que, mientras las colas para las particiones chicas estn llenas, las particiones grandes quedan sin uso. En el caso de una sola cola, cada vez que un programa termina y se libera una particin, se escoge un trabajo de la cola general. Cmo escoger? FIFO: podra quedar un trabajo pequeo en una particin grande, desaprovechando memoria. El ms grande que quepa: trabajos pequeos son postergados, lo cual no es buena poltica de programacin, si suponemos que los trabajos ms chicos son tambin los ms cortos (recordar SJN).
Reubicacin y proteccin

Bajo multiprogramacin, si un mismo programa se ejecuta varias veces, no siempre va a quedar en la misma particin. Por ejemplo, si el programa, ejecutando en la particin 1 (que comienza en la direccin 100K) ejecuta un salto a la posicin 100K+100, entonces, si el mismo programa ejecuta en la particin 3 (que comienza en 400K), debe ejecutar un salto a la posicin 400K+100, porque si salta a la 100K+100 va a caer en la memoria que corresponde a otro proceso. Este es el problema de la reubicacin, y hay varias formas de resolverlo. Consideremos un programa en assembler, donde las direcciones se especifican de manera simblica, como es el caso de la variable count y la entrada al ciclo loop en el siguiente fragmento de programa:
LOAD R1, count loop: ADD CMP JNE R1, -1 R1, 0 loop

La ligadura o binding de las direcciones count y loop a direcciones fsicas puede realizarse en: Tiempo de compilacin. Cuando al compilar se conoce la direccin absoluta, el compilador escribe la imagen exacta del cdigo que se cargar en la memoria, por ejemplo:
100: 102: 104: 106: LOAD $210, R1 ADD CMP JNE R1, -1 R1, 0 102

En este caso el cdigo debe cargarse a partir de la direccin 100. Los programas .COM de MS-DOS son de este estilo. Tiempo de carga. Si al compilar no se conocen todava las direcciones absolutas, hay que generar cdigo reubicable. El cargador o loader, es responsable de determinar las direcciones absolutas al momento de poner el programa en memoria. Para eso, el compilador genera cdigo como para ejecutar a partir de la direccin 0, y agrega un encabezado con informacin acerca de cules de las posiciones corresponden a direcciones que deben ajustarse segn donde se cargue el programa (.EXE de MSDOS?). Tiempo de ejecucin. Si el sistema operativo usa swapping (pasar procesos a disco para hacer espacio en la memoria), puede que un proceso sea cambiado de posicin durante su ejecucin. En este caso se usa hardware especial.

Pero adems de la reubicacin tenemos el problema de la proteccin: queremos que un programa ejecutando en una particin no pueda leer ni escribir la memoria que corresponde a otra particin. Podemos entonces matar dos pjaros de un tiro con una variante de los registro base y lmite que vimos en el captulo 1. Cuando se carga un programa en una particin, se hace apuntar base al comienzo de la particin, y lmite se fija como la longitud de la particin. Cada vez que la CPU quiere accesar la direccin d, el hardware se encarga de que en realidad se accese la direccin fsica base+d (y, por supuesto, adems se chequea que d<lmite). Decimos que d es la direccin lgica o virtual, y base+d la direccin fsica. El programa de usuario slo ve direcciones lgicas; es la unidad de administracin de memoria (MMU) quien se encarga de traducirlas transparentemente a direcciones fsicas. La gracia es que el compilador puede generar cdigo absoluto, pensando que el programa se va a cargar siempre en la posicin 0, y en realidad el binding se hace en tiempo de ejecucin.

Intercambio (Swapping)
En un sistema de procesamiento por lotes, organizar la memoria en particiones fijas es simple y efectivo: cada trabajo se carga en la memoria cuando le toque su turno, y se queda en memoria hasta que termine. Si hay suficientes particiones para mantener a la CPU siempre ocupada, no habra razones para usar nada diferente. Pero en un sistema interactivo, de tiempo compartido, la situacin es diferente, ya que es posible que la memoria no alcance para mantener a todos los procesos. En este caso se usa el disco como apoyo para extender la capacidad de la memoria: algunos procesos se pasan temporalmente a disco (recordar scheduler de largo plazo ). El sistema operativo mantiene una tabla que indica qu partes de la memoria estn desocupadas, y cules en uso. Podemos pensar en que las partes desocupadas son hoyos en la memoria; inicialmente, toda la memoria es un solo gran hoyo Cuando se crea un proceso o se trae uno del disco, se busca un hoyo capaz de contenerlo, y se pone el proceso all. Las particiones ya no son fijas, si no que van cambiando dinmicamente, tanto en cantidad como en ubicacin y tamao. Adems, cuando un proceso es pasado a disco, no hay ninguna garanta de que vuelva a quedar en la misma posicin de memoria al traerlo de vuelta, de manera que es imprescindible el apoyo del hardware para hacer binding en tiempo de ejecucin. Hasta ahora hemos supuesto que los procesos son estticos en tamao, pero es ms realista pensar que pueden crecer, por ejemplo va asignacin dinmica

de memoria. Si es as, conviene reservar un poco ms de memoria que la que estrictamente necesita al momento de ponerlo en memoria. Al hacer swapping, no es necesario guardar todo el espacio que tiene reservado, sino slo el que est usando. Qu pasa si proceso quiere crecer ms all del espacio que se le haba reservado? Si hay un hoyo contiguo se puede usar. Si no, se puede pasar el proceso a un hoyo ms grande. Si no hay ninguno, se pasa a disco hasta que haya. Tambin se puede, simplemente, matar al proceso. Otro punto que hay que tener en cuenta al usar swappping, es el I/O que pudiera estar pendiente. Cuando se hace, por ejemplo, input, se especifica una direccin de memoria donde se va a poner lo que se lea desde el dispositivo. Supongamos que proceso A trata de leer del disco hacia la direccin d, pero el dispositivo est ocupado: su solicitud, por lo tanto, es encolada. Entretanto, el proceso A es intercambiado a disco, y la operacin se completa cuando A no est en memoria. En esas circunstancias, lo ledo se escribe en la direccin d, que ahora corresponde a otro proceso. Para evitar tal desastre: no pasar a disco procesos con I/O pendiente, o bien hacer siempre I/O desde y hacia buffers del sistema operativo. Windows 3.x usa swapping, pero un proceso pasado a disco slo vuelve a la memoria si el usuario activa su ventana. Windows NT usa un esquema ms sofisticado. Unix comienza a usar swapping cuando se supera un cierto lmite de utilizacin de memoria. Administracin de la memoria con mapas de bits El sistema operativo debe saber dnde estn los hoyos. Podemos dividir la memoria en pequeas unidades, y registrar en un mapa de bits (con tantos bits como unidades haya) las unidades ocupadas con un 1 y las desocupadas con un 0. Las unidades pueden ser de unas pocas palabras cada una, hasta de un par de KB. A mayor tamao de las unidades, menor espacio ocupa el mapa de bits, pero puede haber mayor fragmentacin interna. Desventaja: para encontrar hoyo de n unidades hay que recorrer el mapa hasta encontrar n ceros seguidos (puede ser caro). Administracin de la memoria con lista ligada Otra forma es con una lista ligada de segmentos: estado (ocupado o en uso), direccin (de inicio), tamao. Cuando un proceso termina o se pasa a disco, si quedan dos hoyos juntos, se funden en un solo segmento. Si la lista se mantiene ordenada por direccin, podemos usar uno de los siguientes algoritmos para escoger un hoyo donde poner un nuevo proceso (cuyo tamao, obviamente, debe conocerse).

First-fit. Asignar el primer hoyo que sea suficientemente grande como para contener al proceso. Best-fit. Asignar el menor hoyo en el que el proceso quepa. Worst-fit. Asignar el mayor hoyo.

Cada vez que se asigna un hoyo a un proceso, a menos que quepa exactamente, se convierte en un segmento asignado y un hoyo ms pequeo. Best-fit deja el hoyo ms pequeo de todos. La idea de worst-fit es la de dejar hoyos grandes. Simulaciones han mostrado que first-fit y best-fit son mejores en trminos de utilizacin de la memoria. First-fit es ms rpido (no hay que revisar toda la lista). Se puede pensar en otras variantes (por ejemplo, mantener la lista ordenada por tamao, o varias listas, cada una con un rango de tamaos, etc). Fragmentacin externa e interna Los mtodos anteriores de administracin de memoria sufren el problema de la fragmentacin externa: puede que haya suficiente espacio libre como para agregar un proceso a la memoria, pero no es contiguo. La fragmentacin puede ser un problema severo. En algunos sistemas usar first-fit puede ser mejor en trminos de fragmentacin; en otros puede ser mejor best-fit, pero el problema existe igual. Por ejemplo para first-fit, las estadsticas hablan de un tercio de la memoria inutilizable por estar fragmentada. Una forma de resolver este problema es usando compactacin de la memoria: mover los procesos de manera que queden contiguos. Generalmente no se hace por su alto costo. En una mquina con 32MB que copia 32 bytes por microsegundo, podra tomar hasta un segundo de CPU. Si se usa, no es trivial decidir la mejor forma de hacerlo. Si movemos ciegamente los procesos hacia un extremo de la memoria, podemos estar moviendo de ms, puesto que puede ser ms barato dejar el hoyo en ese extremo (y no los procesos), o bien dejar el hoyo al medio. Otra posibilidad es desfragmentar slo hasta donde es razonable: si ya recuperamos 500K, pero nos quedan 100, no tiene sentido seguir mientras no hay ningn proceso que quepa en 100k. Por otra parte, supongamos que tenemos un segmento desocupado de 1000 bytes, y queremos poner un proceso de 998 bytes de tamao, lo que dejara un hoyo de 2 bytes. Difcilmente otro proceso podr aprovechar esos dos bytes: es ms caro mantener un segmento en la lista que "regalarle" esos dos bytes al proceso. La fragmentacin interna se produce cuando un proceso tiene asignada ms memoria de la que necesita.

Paginacin
Hace tiempo que alguien se dio cuenta de que esto de que los procesos tengan que usar un espacio contiguo de la memoria era un impedimento serio para

poder optimizar el aprovechamiento de la memoria. Idea: que las direcciones lgicas sean contiguas, pero que no necesariamente correspondan a direcciones fsicas contiguas. O sea, dividir la memoria fsica en bloques de tamao fijo, llamados marcos o frames, y dividir la memoria lgica (la que los procesos ven) en bloques del mismo tamao llamados pginas.

Se usa una tabla de pginas para saber en que marco se encuentra cada pgina. Obviamente, necesitamos el apoyo del hardware. Cada vez que la CPU intenta accesar una direccin, la direccin se divide en nmero de pgina p y desplazamiento u offset d. El nmero de pgina se transforma en el frame correspondiente, antes de accesar fsicamente la memoria.

El tamao de las pginas es una potencia de 2, tpicamente entre 0.5 y 8K. Si las direcciones son de m bits y el tamao de pgina es 2n, entonces los primeros m-n bits de cada direccin forman p, y los restantes nforman d. Este esquema es parecido a tener varios pares de registros base y lmite, uno para cada marco (o sea, por cierto, tenemos binding en tiempo de ejecucin). Cada proceso tiene su propia tabla, es decir, la tabla de pginas forma parte del contexto: cuando la CPU se concede a otro proceso, hay que cambiar la tabla de pginas a la del nuevo proceso. La paginacin en general encarece los cambios de contexto. La seguridad sale gratis, ya que cada proceso slo puede accesar las pginas que estn en su tabla de pginas. Fragmentacin? Slo interna, y de media pgina por proceso, en promedio. Esto sugerira que conviene usar pginas chicas, pero el problema es que aumenta el sobrecosto de administrar las pginas (entre otras cosas, aumenta el tamao de la tabla de pginas). En general, el tamao de pgina ha ido aumentando con el tamao de la memoria fsica de una mquina tpica. Tablas de pginas Si las direcciones son de m bits y el tamao de pgina es 2n, la tabla de pginas puede llegar a contener 2m-n entradas. En el PDP-11 m=16 y m=13; una relacin poco usual, pero basta con 8 entradas para la tabla de pginas, lo que permite tener 8 registros de CPU dedicados especialmente a tal propsito. En una CPU moderna, m=32 (y ahora, incluso, 64), y n=12 o 13, lo que

significa que se requeriran cientos de miles de entradas: ya no es posible tener la tabla en registros. Lo que podemos hacer es manejar la tabla de pginas de cada proceso completamente en memoria, y usar slo un registro que apunte a la ubicacin de la tabla. Para cambiar de un proceso a otro, slo cambiamos ese registro. Ventaja: agregamos slo un registro al cambio de contexto. Desventaja: costo de cada acceso a memoria se duplica, porque primero hay que accesar la tabla (indexada por el nmero de pgina). O sea, si sin paginacin nos costaba 70ns cada acceso, ahora nos cuesta 140! Solucin tpica (intermedia): usar un pequeo y rpido cach especial de memoria asociativa, llamado translation look-aside buffer (TLB). La memoria asociativa guarda pares (clave, valor), y cuando se le presenta la clave, busca simultneamente en todos sus registros, y retorna, en pocos nanosegundos, el valor correspondiente. Obviamente, la memoria asociativa es cara; por eso, los TLBs rara vez contienen ms de 64 registros. El TLB forma parte de la MMU, y contiene los pares (pgina, marco) de las pginas ms recientemente accesadas. Cuando la CPU genera una direccin lgica a la pgina p, la MMU busca una entrada (p,f) en el TLB. Si est, se usa marco f, sin acudir a la memoria. Slo si no hay una entrada para p la MMU debe accesar la tabla de pginas en memoria (e incorporar una entrada para p en el TLB, posiblemente eliminando otra). La gracia es que, por pequeo que sea el TLB, la probabilidad de que la pgina est en el TLB (tasa de aciertos) es alta, debido a que los programas suelen hacer muchas referencias a unas pocas pginas (por ejemplo, copiar un arreglo). Si la tasa de aciertos es del 90% y un acceso al TLB cuesta 10ns, entonces, en promedio, cada acceso a memoria costar 87ns (por qu?). o sea, slo un 24% ms que un acceso sin paginacin. Una Intel 80486 tiene 32 entradas en el TLB; Intel asegura una tasa de aciertos del 98%. En cada cambio de contexto, hay que limpiar el TLB, lo que puede ser barato, pero hay que considerar un costo indirecto: si los cambios de contexto son muy frecuentes, la tasa de aciertos se puede reducir (por qu?). Otras ventaja de paginacin: tambin se facilita almacenamiento de procesos en el disco; permite que procesos compartan pginas. Por ejemplo, varios procesos ejecutando el mismo cdigo (que tiene que ser reentrante): las primeras pginas lgicas apuntan a las mismas pginas fsicas, que contienen el cdigo. El resto, apunta a datos locales, propios de cada ejecucin.

Segmentacin

Cuando se usa paginacin, el sistema divide la memoria para poder administrarla, no para facilitarle la vida al programador. Lo que ocurre es que la vista lgica que el programador tiene de la memoria no tiene nada que ver con la vista fsica que el sistema tiene de ella. El sistema ve un slo gran arreglo dividido en pginas, pero cuando uno programa, uno piensa en trminos de un conjunto de subrutinas y estructuras de datos, a las cuales nos referimos por su nombre: la funcin coseno, el stack, la tabla de smbolos, sin importarnos su ubicacin en memoria, y si acaso una est antes o despus que la otra. La segmentacin es una forma de administrar la memoria que permite que el usuario vea la memoria de esa manera, es decir, como una coleccin de segmentos, cada uno de los cuales tiene un nombre y un tamao (que, adems, puede variar dinmicamente). Las direcciones lgicas se especifican como un par (segmento, desplazamiento).

Implementacin Similar a paginacin: en vez de tabla de pginas, tenemos tabla de segmentos; para cada segmento, necesitamos saber su tamao y dnde comienza (base). Una direccin lgica (s,d), se traduce a base(s)+d. Si d es mayor que el tamao del segmento, entonces ERROR. Ventajas:

Al usuario se le simplifica el manejo de estructuras de datos de tamao dinmico. Se facilita el que los procesos compartan memoria.

Los segmentos pueden estar protegidos segn la semntica de su contenido. Por ejemplo, un segmento que contiene cdigo, puede especificarse como slo para ejecucin (y nadie puede copiarlo ni sobreescribirlo); un arreglo puede especificarse como read/write but not execute. Esto facilita enormemente la deteccin de errores en el cdigo. Libreras compartidas de enlace dinmico (DLLs).

Pero la memoria sigue siendo, fsicamente, un slo arreglo de bytes, que debe contener los segmentos de todos los procesos. A medida que se van creando y eliminando procesos, se va a ir produciendo, inevitablemente fragmentacin externa. Si consideramos cada proceso como un slo gran segmento, tenemos el mismo caso que el de las particiones variables (ver Intercambio). Como cada proceso tiene varios segmentos, puede que el problema de la particin externa se reduzca, pues ya no necesitamos espacio contiguo para todo el proceso, sino que slo para cada segmento. Para eliminar completamente el problema de la fragmentacin interna, se puede usar una combinacin de segmentacin y paginacin, en la que los segmentos se paginan. Segmentacin paginada en los 386 En una 80386 puede haber hasta 8K segmentos privados y 8K segmentos globales, compartidos con todos los otros procesos. Existe una tabla de descripcin local (LDT) y una tabla de descripcin global (GDT) con la informacin de cada grupo de segmentos. Cada entrada en esas tablas tiene 8 bytes con informacin detallada del segmento, incluyendo su tamao y direccin. Una direccin lgica es un par (selector, desplazamiento), donde el desplazamiento es de 32 bits y el selector de 16, dividido en: 13 para el segmento, 1 para global/local, y 2 para manejar la proteccin. La CPU tiene un cach interno para 6 segmentos.

En realidad, la tabla de pginas es de dos niveles...

Memoria Virtual
Qu podemos hacer si un programa es demasiado grande para caber en la memoria disponible? Una posibilidad es usar superposiciones (overlays), como en MS-DOS: dividimos el programa en trozos independientes, y los vamos cargando de a uno, a medida que se necesiten. Por ejemplo, compilador de dos pasadas: Cargamos primero el cdigo de la primera pasada, la ejecutamos, y despus la descartamos para cargar el cdigo de la segunda pasada. Las rutinas comunes y estructuras de datos compartidas entre las dos pasadas las mantenemos en memoria permanentemente. El problema es que agregamos complejidad a la solucin. No siempre es fcil dividir un programa grande en unidades independientes, que no interactan entre s.

Mucho mejor sera poder extender la memoria de manera virtual, es decir, hacer que el proceso tenga la ilusin de que la memoria es mucho ms grande que la memoria fsica (o que el trozo de memoria fsica que le corresponde, si tenemos multiprogramacin). El sistema operativo se encarga de mantener en memoria fsica los trozos (pginas) que el proceso est usando, y el resto en disco. Ya que el disco es barato, podemos tener espacios de direccionamiento enormes.

Paginacin por demanda


Cmo se implementa memoria virtual? Con un poco de ayuda del hardware. Agregamos un bit a la tabla de pginas, que indica si la pgina en cuestin es vlida o invlida. Vlida significa que est en memoria (en el marco que indica la tabla), e invlida significa que no est. El acceso a las pginas vlidas funciona igual que antes, pero si la CPU intenta accesar una pgina invlida, se produce una falta de pgina que genera un trap al sistema operativo, quien debe encargarse de ir a buscar esa pgina al disco, ponerla en la memoria, y reanudar el proceso. O sea, en detalle, el sistema operativo debe:

Bloquear al proceso. Ubicar un marco libre. Si no hay, tiene que liberar uno (ya veremos cmo). Ordenar al controlador de disco que lea la pgina (de alguna manera, el sistema operativo debe saber dnde la guard). Mientras, otros procesos pueden ejecutar. Cuando se completa la lectura, modificar la tabla de pginas para reflejar que ahora la pgina si es vlida. Pasar el proceso a la cola READY. Cuando le toque ejecutar, no notar ninguna diferencia entre esta falta de pgina y una simple expropiacin de la CPU (en ambos casos, el efecto neto es que est un rato sin ejecutar).

Qu hemos ganado?

Ya no necesitamos overlays para ejecutar programas grandes. Slo cargamos en memoria las partes del programa que se usan, reduciendo costos de lectura desde disco. Por ejemplo, muchos programas tienen cdigo para manejar situaciones excepcionales y que, por lo mismo, rara vez se ejecuta. Ahora que no es necesario tener el programa completo en memoria para poder ejecutarlo, podemos aumentar el nivel de multiprogramacin.

Tablas de pginas

Ahora que la memoria lgica puede ser mucho ms grande que la fsica, se acenta el problema del tamao de la tabla de pginas. Con direcciones de 32 bits, la memoria virtual puede alcanzar los 4GB (lo cual ya no es irreal). Con pginas de 4 KB, necesitaramos hasta 1M entradas. Si cada entrada usa 32 bits, entonces la tabla podra pesar 4 MB. Adems, cada proceso tiene su tabla, y esta tabla debe estar siempre en memoria fsica (al menos mientras ejecuta por qu?). O sea, tenemos un problema serio. Solucin: usar tablas de varios niveles. El 386 usa dos niveles: una direccin lgica de 32 bits la dividimos en (p1, p2, d), de 10, 10 y 12 bits respectivamente. Usamos p1 como ndice a una tabla de tablas (ometatabla) o tabla de primer nivel, que contiene 210=1024 entradas de 32 bits (o sea, ocupa justo una pgina). La entrada correspondiente a p1 en esta tabla indica el frame donde se encuentra otra tabla (de segundo nivel), donde hay que buscar indexando por p2, el frame donde est la pgina que finalmente se necesita. La clave es que slo estamos obligados a mantener en memoria la tabla de primer nivel. Las otras (que tambin ocupan exactamente una pgina), se tratan como pginas ordinarias, es decir, pueden estar en disco. As, al utilizar la propia memoria virtual para estas pginas, se mantienen en memoria fsica slo las ms usadas. Claro que estamos agregando un acceso ms a la memoria para convertir cada direccin lgica a una fsica, pero con un TLB con tasa de aciertos alta el impacto es mnimo. Ahora, si las direcciones son de 64 bits, tendramos que usar ms niveles. Otra posibilidad sera usar tablas de pgina invertidas, en las que, en vez de habar una entrada por pgina virtual, hay una entrada por marco en la memoria fsica. As, si tenemos 32 MB de memoria real y pginas de 4 KB, una tabla invertida necesita slo 8K entradas (independientemente de si las direcciones son de 32 o 64 bits). Cada entrada dice a qu pgina virtual de qu proceso corresponde el marco. Cuando proceso P accesa direccin lgica l, hay que buscar un par (P,l) en esta tabla. La posicin de este par es el marco que hay que accesar. Problema obvio: la bsqueda en una tabla de 8192 entradas puede costar muchos accesos a memoria. Soluciones: otra vez el TLB evita hacer la bsqueda la mayor parte de las veces, y se puede implementar la tabla con hashing.

Reemplazo de pginas
Hasta ahora hemos soslayado un tema fundamental. Cuando un proceso accesa una pgina invlida, hay que ir a buscar su contenido a disco y ponerlo en algn marco. El punto es en qu marco, si no hay ninguno libre? Una posibilidad en tal caso es pasar a disco un proceso, con lo cual los marcos que ocupaba quedan libres. Vamos a analizar este caso ms adelante.

Lo usual es usar algn algoritmo de reemplazo de pginas para seleccionar un marco vctima (por ejemplo, al azar). Para poder usar ese marco, primero hay que sacar la pgina que originalmente contena, o sea, pasarla a disco. Sin embargo, si la pgina original no haba sido modificada, la copia en disco es idntica, as que se puede descartar esta operacin de escritura. El sistema operativo puede saber si una pgina ha sido modificada examinando un bit asociado a la pgina (el dirty bit) que el hardware se encarga de poner en 1 cada vez que se escribe en ella. O sea, cada falta de pgina produce una o dos transferencias de pginas entre la memoria y el disco. Moraleja: tratar de reducir las faltas al mnimo. Por lo tanto, para comparar algoritmos de reemplazo hay que contar cuntas faltas se producen dadas algunas secuencias de acceso a la memoria (cules?). Vamos a comenzar por analizar formas de elegir un marco de un conjunto. Despus vamos a analizar si ese conjunto debe contener todos los marcos, o slo los que le corresponden al proceso. Algoritmo ptimo El algoritmo que evidentemente minimiza el nmero de faltas consiste en escoger la pgina para la cual el lapso de tiempo hasta la prxima referencia es el mayor. Si tenemos tres marcos y las pginas son accesadas en la secuencia 7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1, tendramos 9 faltas. Lo "nico" malo es que es imposible de implementar, pues para escoger una pgina hay que conocer cules sern los accesos futuros. En todo caso, sirve como referencia. FIFO Consiste en reemplazar la pgina ms vieja (la que lleva ms tiempo en memoria fsica). Es simple, pero no es bueno, ya que la pgina ms antigua no necesariamente es la menos usada. En el ejemplo tendramos 15 faltas. Adems sufre de la Anomala de Belady: las faltas pueden aumentar si aumentamos el nmero de marcos disponibles (probar 1,2,3,4,1,2,5,1,2,3,4,5 con 3 y 4 marcos). La menos recientemente usada (LRU) La poltica ptima usa conocemiento del futuro. Se puede aproximar este conocemiento usando el pasado reciente para predecir el futuro. Se selecciona la pgina menos recientemente usada con la esperanza de que, si no ha sido accesada en el pasado reciente, no lo ser en el futuro cercano. Con el ejemplo

LRU producira 12 faltas. Es una buena poltica, pues los procesos presentan localidad temporal de referencia. El problema es que la implementacin requiere un apoyo del hardware que es caro de implementar. Por ejemplo, con un contador y un campo adicional (de unos 64 bits) para cada pgina. Cada vez que se accesa una pgina, se incrementa el contador y se guarda en el campo de la pgina accesada. As la pgina menos recientemente usada es aquella con el menor valor en su campo. Hay otras posibilidades, pero todas caras, por lo que LRU en general no se usa; ms bien se usan aproximaciones ms baratas.

Reemplazo de pginas
Hasta ahora hemos soslayado un tema fundamental. Cuando un proceso accesa una pgina invlida, hay que ir a buscar su contenido a disco y ponerlo en algn marco. El punto es en qu marco, si no hay ninguno libre? Una posibilidad en tal caso es pasar a disco un proceso, con lo cual los marcos que ocupaba quedan libres. Vamos a analizar este caso ms adelante. Lo usual es usar algn algoritmo de reemplazo de pginas para seleccionar un marco vctima (por ejemplo, al azar). Para poder usar ese marco, primero hay que sacar la pgina que originalmente contena, o sea, pasarla a disco. Sin embargo, si la pgina original no haba sido modificada, la copia en disco es idntica, as que se puede descartar esta operacin de escritura. El sistema operativo puede saber si una pgina ha sido modificada examinando un bit asociado a la pgina (el dirty bit o bit de modificacin) que el hardware se encarga de poner en 1 cada vez que se escribe en ella. O sea, cada falta de pgina produce una o dos transferencias de pginas entre la memoria y el disco. Moraleja: tratar de reducir las faltas al mnimo. Por lo tanto, para comparar algoritmos de reemplazo hay que contar cuntas faltas se producen dadas algunas secuencias de acceso a la memoria (cules?). Vamos a comenzar por analizar formas de elegir un marco de un conjunto. Despus vamos a analizar si ese conjunto debe contener todos los marcos, o slo los que le corresponden al proceso. Algoritmo ptimo El algoritmo que evidentemente minimiza el nmero de faltas consiste en escoger la pgina para la cual el lapso de tiempo hasta la prxima referencia es el mayor. Si tenemos tres marcos y las pginas son accesadas en la secuencia 7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1, tendramos 9 faltas.

Lo "nico" malo es que es imposible de implementar, pues para escoger una pgina hay que conocer cules sern los accesos futuros. En todo caso, sirve como referencia. FIFO Consiste en reemplazar la pgina ms vieja (la que lleva ms tiempo en memoria fsica). Es simple, pero no es bueno, ya que la pgina ms antigua no necesariamente es la menos usada. En el ejemplo tendramos 15 faltas. Adems sufre de la Anomala de Belady: las faltas pueden aumentar si aumentamos el nmero de marcos disponibles (probar 1,2,3,4,1,2,5,1,2,3,4,5 con 3 y 4 marcos). La menos recientemente usada (LRU) La poltica ptima usa conocimiento del futuro. Se puede aproximar este conocimiento usando el pasado reciente para predecir el futuro. Se selecciona la pgina menos recientemente usada con la esperanza de que, si no ha sido accesada en el pasado reciente, no lo ser en el futuro cercano. Con el ejemplo, LRU producira 12 faltas. Es una buena poltica, pues los procesos presentan localidad temporal de referencia. El problema es que la implementacin requiere un apoyo del hardware que es caro de implementar. Por ejemplo, con un contador y un campo adicional (de unos 64 bits) para cada pgina. Cada vez que se accesa una pgina, se incrementa el contador y se guarda en el campo de la pgina accesada. As, la pgina menos recientemente usada es aquella con el menor valor en su campo. Hay otras posibilidades, pero todas caras, por lo que LRU en general no se usa; ms bien se usan aproximaciones ms baratas. Aproximaciones a LRU Sin soporte de hardware es poco lo que se puede hacer (habra que usar FIFO u otro algoritmo). Pero la mayora de las mquinas proveen un bit de referencia por cada pgina cuya implementeacin en hardware es barata, y puede ayudar bastante si el software hace su parte. El sistema operativo pone en 0 el bit de referencia de cada pgina al inicializar un proceso, y el hardware lo pone en 1 cada vez que se accesa la pgina. As, despus de un rato, si examinamos los bits de referencia podemos saber qu pginas han sido usadas (aunque desconocemos el orden en que han sido usadas).
Ms bits de referencia

Idea: mirar los bits de referencia a intervalos regulares, registralos, y resetearlos. Si los registramos en el bit de mayor orden de un byte, previo desplazamiento a la derecha, e interpretamos el byte como un entero sin signo,

entonces hay que reemplazar la pgina cuyo byte sea el menor es la menos recientemente usada. Por supuesto, puede haber varias pginas con el menor byte; hay que escoger alguna (FIFO?) o tambin todas.
Segunda oportunidad

Es un caso especial del anterior, en el que se usa un byte de un bit. O sea, se usa FIFO, pero si la potencial vctima tiene el bit de referencia en 1, se pone en 0 y se le da una segunda oportunidad (se escoge otra). Posible implementacin: con lista circular (por eso tambin se conoce como algoritmo del reloj). Una optimizacin se basa en considerar que sale ms caro reemplazar una pgina que ha sido modificada, pues hay que actualizar la copia en disco antes de reemplazarla. Segn (bit de referencia, bit de modificacin) hay 4 clases: 00, 01, 10, 11. Se escoge FIFO dentro de la clase (no vaca) ms baja. (La clase 01 significa no referenciada, pero modificada: pueden existir pginas en esta categora?). Este algoritmo se usa en los MACs. Fondos de marcos Independientemente del algoritmo de reemplazo usado, se puede mantener un pool o fondo de marcos libres. Ante una falta de pgina, se escoge una vctima como siempre, pero la pgina faltante se pone en un marco del fondo si es que la vctima tiene el bit de modificacin encendido. La vctima se puede escribir a disco y pasar al fondo despus de reanudar el proceso, con lo que se reduce el tiempo de espera. Adems, si se produce una falta sobre una pgina que todava est en el pool, entonces no es necesario ir a buscarla al disco. Las primeras partidas de la CPU VAX no mantenan correctamente el bit de referencia, de manera que el sistema operativo VMS usaba FIFO; pero gracias a un fondo de pginas se mejoraba el rendimiento. Tambin se pueden aprovechar los momentos en que el disco est libre para escribir las pginas sucias (qu se gana? por cules pginas conviene comenzar?).

Hiperpaginacin o thrashing
El conjunto de pginas que un proceso est usando se denomina el conjunto de trabajo. Supongamos que un proceso est usando 4 pginas en forma intensiva, (por ejemplo, 1,2,3,4,1,2,3,4,1,2,3,4...). Si las 4 pginas que conforman su conjunto

de trabajo estn en memoria, entonces el proceso ejecutar fluidamente. Pero si slo disponde de 3 marcos, cualquiera sea el algoritmo de reemplazo, slo alcanzar a ejecutar unas pocas instrucciones cada vez, antes de producir una falta de pgina, o sea, hacehiperpaginacin, y como consecuencia el proceso andar un milln de veces ms lento que con cuatro marcos!

Asignacin de marcos
Cuntos marcos le asignamos a cada proceso? Debemos considerar que

No podemos asignar ms marcos que los que hay. Pasado un lmite, si asignamos ms marcos a un proceso no vamos a reducir significativametne el nmero de faltas de pginas (ejemplo del compilador de dos pasadas). Si m es el mximo nmero de marcos que requiere una instruccin de la mquina, no podemos asignar menos que m. Ejemplo: ADD A,B podra requerir 6 marcos. Si asignamos pocos, nos caben ms procesos en memoria, pero corremos el riesgo de que los procesos pasen a rgimen de hiperpaginacin.

Si hay N procesos y M marcos, podemos asignar M/P marcos a cada uno, pero los procesos chicos podran quedar con ms marcos que los que necesitan. Mejor sera hacer una asignacin proporcional al tamao de los procesos. En cualquiera de los dos casos, hay que considerar la entrada y salida de procesos al sistema. Adems, para mantener la proporcionalidad, el reemplazo de pginas debe ser local, es decir, si un proceso produce una falta de pgina, se escoge una vctima dentro de sus propios marcos. Otra posibilidad es dejar que la asignacin se vaya ajustando sola, por la va de usar reemplazo global, es decir, escoger una vctima entre todos los marcos, sin importar a que proceso est actualmente asignado. En general, se

obtienen mejores resultados, pues la asignacin se adapta dinmicamente al tamao de los conjuntos de trabajo. Una manera ms directa de controlar la hiperpaginacin es monitoreando la tasa de faltas por segundo de cada proceso. Si supera un lmite MAX se le asignan ms marcos, y si baja de MIN se le quitan marcos. Si se llega a una situacin en la que no es posible mantener a todos los procesos bajo MAX, entonces se pasan procesos a disco.

Sistemas de archivos
Utilizando la memoria principal los procesos pueden almacenar y tambin compartir informacin. Sin embargo, la cantidad de informacin que se puede almacenar es limitada, an con memoria virtual. Adems, deja de existir cuando el proceso termina, y --peor an-- se pierde si se corta la luz. En sntesis, se requiere otra clase de almacenamiento, que cumpla los siguientes requisitos:

Que permita guardar grandes volmenes de informacin. Que la informacin sobreviva a los procesos que la usan. Que mltiples procesos puedan accesar la informacin de manera concurrente.

La solucin usual es guardar la informacin en disco, organizndola lgicamente en unidades llamadas archivos. Los archivos son administrados por una parte del sistema operativo que se conoce como sistema de archivos.

Archivos
Desde el punto de vista del usuario, un archivo suele tener los siguientes atributos: Nombre. Ms que nada, para ayudar a los humanos. Las reglas para nombrar archivos varan de un sistema a otro (cuntos caracters, qu caracters, maysculas y minsculas diferentes, extensin, etc.).

Tipo. Muchos sistemas clasifican los archivos en distintos tipos (por ejemplo, texto, ejecutable, etc.). Contenido. Tamao. Actual y mximo. Fecha y hora. De creacin, de la ltima modificacin, del ltimo acceso. Usuarios. Identificador del creador y del dueo actual. Atributos de proteccin. Quin tiene derecho a hacer qu con el archivo. Otros atributos. Oculto, sistema, respaldado, etc. Operaciones sobre archivos El sistema operativo debe permitir operaciones sobre los archivos, mediante llamadas al sistema.

Crear y eliminar. Abrir y cerrar. Leer y escribir (tpicamente, a partir de la posicin actual). Reposicionarse. Obtener y cambiar atributos. Renombrar.

La informacin acerca de un archivo, exceptuando su contenido, se guarda en una entrada del directorio. Dicha entrada contiene un puntero a la ubicacin en disco del archivo. Una interfaz muy general para la llamada al sistema que escribe en un archivo, podra ser una que especifique

1. Nombre del archivo. 2. Posicin desde donde se va a escribir. 3. Informacin a escribir (p.ej., puntero y tamao) Sin embargo, ese esquema resulta ineficiente para el caso ms que usual en que se hacen varias escrituras al mismo archivo, puesto que cada escritura implica una bsqueda en el directorio para conocer la ubicacin del archivo. Por eso, lo tpico es usar una tabla de archivos abiertos por proceso, con la informacin relevante de cada archivo abierto (como ubicacin en disco y posicin actual). Los procesos, antes de leer o escribir en un archivo, deben hacer una llamada para abrirlo. Esta llamada agrega una entrada en la tabla, y retorna un identificador (por ejemplo, el ndice dentro de la tabla). De ah en adelante, el proceso ya no se refiere al archivo por nombre, sino por el identificador, lo que evita nuevas bsquedas en el directorio. Adems, por lo general se escribe a partir de la posicin actual. En sistemas multiusuario, existe una tabla de archivos abiertos por proceso, y otra global. La tabla local contiene informacin propia del proceso (por ejemplo, la posicin actual), e incluye un puntero a la entrada correspondiente en la tabla global. En sta ltima se guarda informacin que no depende de los procesos, como la ubicacin del archivo en disco. Mtodos de acceso Un archivo consiste en una secuencia de registros lgicos de algn tamao. En Unix es 1 byte, que es lo mismo que decir que los archivos no tienen ninguna estructura. Otros sistemas operativos pueden imponer cierta estructura. Los registros de un archivo se pueden accesar mediante:
Acceso secuencial.

Es el mtodo ms simple y el ms comn. Los registros se leen uno a uno, en orden. Las escrituras siempre se hacen agregando un registro al final. Es suficiente en algunos casos (compiladores, editores). Suele ser el nico mtodo posible para archivos almacenados en cintas magnticas.
Acceso directo, relativo o aleatorio.

Se puede accesar (leer o escribir) cualquier registro, en cualquier orden, como en un arreglo. Es esencial para aplicaciones como bases de datos.

Directorios
La informacin acerca de los archivos se almacena en directorios, que, en muchos casos son tambin archivos. Un directorio es una tabla que contiene una entrada por archivo. Una posibilidad es tener un slo directorio, que contenga todos los archivos. Es simple, pero no muy til para organizar muchos archivos de mltiples usuarios. Otra posibilidad es contar con un directorio para cada usuario, pero lo ms flexible y lo ms usado es una estructura en forma de rbol, como en Unix y DOS. Existe un directorio raz, que contiene archivos. Algunos de esos archivos son directorios, y as sucesivamente. Esto permite organizar los archivos de manera natural. Cada archivo tiene un nombre nico, que se compone de los nombres de todos los directorios en el camino desde la raza hasta el archivo.

Sistemas distribuidos
Un sistema distribuido es una coleccin de computadores conectados por una red de comunicaciones, que el usuario percibe como un solo sistema (no necesita saber qu cosas estn en qu mquinas). El usuario accesa los recursos remotos de la misma manera en que accesa recursos locales. En comparacin con un sistema centralizado:

Mejor aprovechamiento de los recursos. Mayor poder de cmputo a ms bajo costo. (Procesamiento paralelo). Algunas aplicaciones son inherentemente distribuidas: red de cajeros automticos. En teora, mayor confiablidad, si se maneja suficiente redundancia. (Si se cae una mquina, no se cae todo el sistema). Crecimiento incremental. El software es mucho ms complejo (de hecho, todava no est muy claro como hacerlo). Muchos usuarios desde muchas partes: problemas de seguridad.

Redes de computadores
Cada computador en una red es un nodo. Los nodos pueden estar conectados fsicamente de diversas maneras: red totalmente conectada, parcialmente conectada, jerrquica, en estrella, anillo o bus.

Ya que no hay memoria compartida, la comunicacin entre los nodos se basa exclusivamente en mensajes. Cmo porgramamos ahora un sistema productor-consumidor, si el productor est en un nodo y el consumidor en otro? Mediante mensajes. Un sistema operativo con soporte para redes provee primitivas de comunicacin interprocesos. send(P, mensaje) enva el mensaje al proceso P, y contina. receive(Q, mensaje) bloquea el proceso hasta recibir un mensaje de Q. receive(id, mesaje) bloquea el proceso hasta recibir un mensaje de cualquier proceso. El identificador del emisor se devuelve en id. Cmo se identifican los procesos? Cmo se hace llegar un mensaje a su destino, si la red no est totalmente conectada? (Estrategias de ruteo). Las redes de comunicacin no son confiables, lo que significa que no hay ninguna garanta de que un mensaje llegue a destino. Esta imperfeccin suele ser ocultada por el sistema operativo, quien provee a los procesos primitivas de comunicacin que son una abstraccin de una red confiable: por debajo el sistema se las arregla mediante ACKs, timeouts y retransmisiones para resolver problemas causador por errores transitorios como prdidad de mensajes. En rigor, en un sistema centralizado los procesos tambin se pueden comunicar mediante mensajes (recordemos que los procesos, por defecto, no comparten memoria).

Sistemas operativos de red


Un sistema operativo de red provee un ambiente en el que los usuarios pueden accesar recursos remotos, pero deben estar conscientes de la multiplicidad de mquinas. Login remoto En Unix, uno puede hacer telnet lucifer.cs.uwm.edu si quiere entrar a esa mquina en forma remota. Cuando se ejecuta este programa se crea un proceso cliente telnet que intenta comunicarse con la mquina remota. Para que esto funcione, en tal mquina debe haber un servidor telnet, que, cuando recibe una solicitud de conexin, crea un proceso que acta en representacin del usuario (previa autentificacin). Todo lo que el usuario digita es enviado por el cliente al proceso remoto, quien ejecuta los comandos y enva la salida para que el cliente la despliegue. Transferencia de archivos

Otra funcin que los sistemas operativos de red proveen es la de transferencia de archivos. En la Internet hacemos
ftp altar.ing.puc.cl <autentificacin...> get archivo

o tambin
rcp maquina1:archivo1 maquina2:archivo2

Bajo este esquema no hay transparencia para el usuario, pues ste debe saber exactamente dnde est el archivo que necesita. El acceso a un archivo remoto difiere bastante del acceso a un archivo local. Adems, los archivos en realidad no se comparten; ms bien, hay muchas copias de un mismo archivo en todos los lugares en los que se necesita; no slo se gasta espacio, sino que puede haber problemas de consistencia. FTP se implementa de manera similar a telnet, slo que el servidor FTP responde slo a un conjunto predefinido de comandos (get, put, ls, cd, etc.). Un punto importante acerca de telnet y FTP es que el usuario debe cambiar de paradigma. Para usar FTP el usuario debe conocer un conjunto de comandos que difiere bastante de los comandos del sistema operativo. En el caso de telnet la diferencia no es tan drstica, pero existe en la medida que el sistema operativo de la mquina remota difiera del de la mquina local. NFS Un avance sera proveer un sistema de archivos global, accesible por todas las estaciones de trabajo en la red. Los servidores de archivos soportan el sistema de archivos, y atienden solicitudes de las estaciones para leer, escribir y, en general, manipular archivos. NFS (Network File System) puede clasificarse como un sistema operativo de red. NFS permite que una coleccin de clientes y servidores compartan un sistema de archivos comn. Una mquina puede ser cliente y servidor al mismo tiempo. Cada servidor exporta uno o ms de sus directorios para que sean accesados por clientes remotos. Los clientes accesan estos directorios montndolos en algn punto de su jerarqua de directorios. ( mount server:/cdrom /net/cdrom). Este esquema permite tener estaciones sin disco. Una vez que el directorio est montado, para un programa que ejecuta en la mquina cliente, no hay diferencia en la forma de accesar archivos locales y remotos. Ahora s, los archivos son verdaderamente compartidos. Hay transparencia, pero menos que la ideal: el nombre de un archivo compartido depende del lugar desde donde se accese: /net/cdrom de una mquina puede ser el /remote/cddrive de otra.

Para el montaje, el cliente enva al servidor una solicitud, especificando el nombre de uno de los directorio que el servidor exporta. Si todo es legal, el servidor devuelve un asidor file handle al cliente, que contiene, entre otras cosas, el dispositivo en el que se encuentra, y el nmero del nodo-i del directorio. El cliente debe usar este asidor en todas las operaciones subsecuentes sobre ese directorio. NFS soporta las mismas operaciones sobre archivos que UNIX, con la excepcin de open y close. Para usar un archivo, el cliente primero enva una solicitud de bsqueda (LOOKUP) indicando el nombre del archivo. El servidor, en vez de almacenar localmente la informacin que tradicionalmente se maneja en una tabla de archivos abiertos, la enva como respuesta al cliente en un asidor. De ah en adelante, para leer y escribir archivos, el cliente debe especificar el asidor cada vez. Ventaja: toda la informacin la maneja el cliente, de manera que el servidor no tiene que recordar nada (servidor sin estado o stateless). El servidor puede caerse y recuperarse, sin que el cliente lo note. NFS soporta sistemas heterogneos. Por ejemplo, un cliente DOS puede accesar archivos de un servidor Unix.

Sistemas operativos distribuidos


Segn nuestra definicin, un sistema operativo distribuido debe hacer que los usuario (procesos) perciban el sistema como un monoprocesador virtual. No es necesario que los usuarios estn al tanto de la existencia de mltiples mquinas y mltiples procesadores en el sistema. En la actualidad no hay ningn sistema que cumpla cabalmente con esta definicin, pero se estn haciendo avances. Aspectos de diseo
Transparencia.

Los usuarios deben poder accesar los objetos remotos de la misma forma que los locales. Es responsabilidad del sistema operativo distribuido localizar el recurso y obtener la interaccin adecuada. La transparencia tambin tiene que ver con la forma de nombrar los objetos: el nombre de un objeto no debe depender del lugar en que se almacena. Un recurso debe poder migrar de un lugar a otro, sin que esto signifique que haya que cambiar su nombre. Los usuarios, adems, deben tener la misma vista del sistema, independientemente del lugar en que el usuario haga login. (Esto se cumple en AFS, pero no en NFS).

Confiabilidad.

Supongamos que tenemos un sistema con 5 mquinas, cada una con una probabilidad del 95% de estar funcionando normalmente en cualquier instante. Si el hecho de que una mquina se caiga bota todo el sistema, entonces la probabilidad de que el sistema est funcionando en un instante dado es del 77%. Si en cambio el sistema est hecho de manera tal que cualquier mquina puede asumir el trabajo de una mquina que se cae, entonces el sistema estar funcionando un 99.9994% del tiempo. La primera opcin es definitivamente mala (mucho peor que en un sistema centralizado); la segunda, es poco realista (muy difcil de implementar). Adems, la tolerancia a fallas es un tema particularmente complejo, debido a que, en general, no es posible diferenciar entre un enlace de comunicaciones cado, una mquina cada, una mquina sobrecargada, y prdida de mensajes. En la prctica: ubicar un punto intermedio razonable. O sea, replicar hasta un punto razonable los elementos claves (datos, servicios, hardware). Obviamente, la confiablidad tiene que ver con la consistencia de los datos. Si un archivo importante se replica, hay que asegurarse que las rplicas se mantengan consistentes; mientras ms haya, ms caro es mantenerlas, y ms probable es que haya inconsistencias. La seguridad es tambin un aspecto fundamental de la confiablidad.
Escalabilidad.

La escalabilidad de un sistema es la capacidad para responder a cargas de trabajo crecientes. En particular un sistema distribuido escalable debe disearse de manera que opere correcta y eficientemente con diez o con millones de mquinas. Un principio bsico en el diseo de sistemas escalables es que la carga de trabajo de cualquier componente del sistema debe estar acotada por una constante independiente del tamao del sistema. Si no es as, entonces el crecimiento del sistema estar limitado. En consecuencia, todo lo que huela a centralizacin a la larga constituir un freno a la escalabilidad. Por ejemplo, servidores de autentificacin, de nombres o de archivos: si estos son centralizados (uno para todo el sistema), entonces hay un lmite en la cantidad de servicios que pueden atender. (Adems de que la centralizacin atenta contra la tolerancia a fallas). Los algoritmos centralizados tambin deben evitarse. Por ejemplo, dada un topologa de red compleja, en teora la mejor manera de rutear mensajes es recopilando la informacin acerca del estado de los enlaces (qu conexiones hay, y qu grado de congestin tiene cada una), correr un algoritmo de teora de grafos que encuentra el camino ms corto (barato) entre cada par de nodos, y despus divulgar esa informacin. Pero,

otra vez, un mecanismo as no es escalable. En la medida que sea posible, hay que usar algoritmos descentralizados, que tienen las siguientes caractersticas: 1. Ninguna mquina tiene el conocimiento completo del estado del sistema. 2. Cada nodo toma decisiones basndose nicamente en la informacin que tiene disponible. 3. La falla de una mquina no hace fracasar el algoritmo. 4. Los algoritmos no dependen de la existencia de relojes sincronizados. (Por ejemplo, si un algoritmo obliga a que todos los nodos registren alguna informacin acerca de su estado a las 12:00:00.0...) Todas estas imposiciones son bastante fuertes. No siempre es posible encontrar algoritmos que cumplan todos estos requisitos. Incluso, algoritmos que los cumplen no siempre escalan bien.
Flexibilidad.

Sistemas distribuidos son nuevos. Es importante, por ende, que se puedan adaptar a nuevas tecnologas y a nuevos avances en el tema.
Rendimiento.

Ciertamente, es un aspecto que no se puede dejar de lado. Cmo se mide?

Potrebbero piacerti anche