miércoles, 29 de julio de 2009

ADMINISTRACION DE LA MEMORIA

La organización y administración de la “memoria principal ”, “memoria primaria” o “memoria real” de un sistema ha sido y es uno de los factores más importantes en el diseño de los S. O.
Los términos “memoria” y “almacenamiento” se consideran equivalentes.
Los programas y datos deben estar en el almacenamiento principal para:
* Poderlos ejecuta
r
* Referenciarlos directamente.
Se considera “almacenamiento secundario” o “almacenamiento auxiliar” al generalmente soportado en discos.
Los hechos demuestran que generalmente los programas crecen en requerimientos de memoria tan rápido como las memorias:

* “Ley de Parkinson parafraseada”: Los programas se desarrollan para ocupar toda la memoria disponible para ellos."

La parte del S. O. que administra la memoria se llama “administradormemoria”:

* Lleva un registro de las partes de memoria que se están utilizando y de aquellas que no.
* Asigna espacio en memoria a los procesos cuando estos la necesitan.
* Libera espacio de memoria asignada a procesos que han terminado

Organización y Administración del Almacenamiento.
Históricamente el almacenamiento principal se ha considerado como un recurso costoso, por lo cual su utilización debía optimizarse .
Por organización del almacenamiento se entiende la manera de considerar este almacenamiento:
¿ se coloca un solo programa de usuario o varios ?.
Si se encuentran varios programas de usuario:
¿ se concede a cada uno la misma cantidad de espacio o se divide el almacenamiento en porciones o “particiones” de diferente tamaño ?.
¿ se utilizará un esquema rígido de número y tamaño de particiones o un esquema dinámico y adaptable ?.
¿ se requerirá que los trabajos de los usuarios sean diseñados para funcionar en una partición específica o se permitirá que se ejecuten en cualquiera donde quepan ?.
¿ se requerirá o no que cada trabajo sea colocado en un bloque contiguo de memoria ?.

Administración del Almacenamiento.
Independientemente del esquema de organización hay que decidir las estrategias que se utilizarán para optimizar el rendimiento.
Las “estrategias de administración” deben considerar:
¿ cuándo se consigue un nuevo programa para colocar en la memoria ?:
¿ cuando el sistema lo pide específicamente o se intenta anticiparse a las peticiones ?.
¿ dónde se colocará el programa que se ejecutará a continuación ?:
¿ se prioriza el tiempo de carga o la optimización en el uso del almacenamiento ?.
¿ con qué criterio se desplazarán programas ?.

Jerarquía de Almacenamiento.
Los programas y datos tienen que estar en la memoria principal para poder ejecutarse o ser referenciados Los programas y datos que no son necesarios de inmediato pueden mantenerse en el almacenamiento secundario.
El almacenamiento principal es más costoso y menor que el secundario pero de acceso más rápido.
Los sistemas con varios niveles de almacenamiento requieren destinar recursos para administrar el movimiento de programas y datos entre niveles .

Un nivel adicional es el “caché” o memoria de alta velocidad, que posee las siguientes características:
* Es más rápida y costosa que la memoria principal.
* Impone al sistema un nivel más de traspaso:
*Los programas son traspasados de la memoria principal al caché antes de su ejecución.
* Los programas en la memoria caché ejecutan mucho más rápido que en la memoria principal.
* Al utilizar memoria caché se espera que:
*La sobrecarga que supone el traspaso de programas de un nivel de memoria a otro sea mucho menor que la mejora en el rendimiento obtenida por la posibilidad de una ejecución mucho más rápida en la caché.
Estrategias de Administración del Almacenamiento.
Están dirigidas a la obtención del mejor uso posible del recurso del almacenamiento principal
Se dividen en las siguientes categorías:
* Estrategias de búsqueda:
* Estrategias de búsqueda por demanda.
* Estrategias de búsqueda anticipada.
* Estrategias de colocación.
* Estrategias de reposición.
Las “estrategias de búsqueda” están relacionadas con el hecho de cuándo obtener el siguiente fragmento de programa o de datos para su inserción en la memoria principal.
En la “búsqueda por demanda” el siguiente fragmento de programa o de datos se carga al almacenamiento principal cuando algún programa en ejecución lo referencia.
Se considera que la “búsqueda anticipada” puede producir un mejor rendimiento del sistema.
Las “estrategias de colocación” están relacionadas con la determinación del lugar de la memoria donde se colocará (cargará) un programa nuevo.
Las “estrategias de reposición” están relacionadas con la determinación de qué fragmento de programa o de datos desplazar para dar lugar a los programas nuevos.
Asignación Contigua de Almacenamiento Versus No Contigua.
En la “asignación contigua” cada programa ocupa un bloque contiguo y sencillo de localizaciones de almacenamiento.
En la “asignación no contigua” un programa se divide en varios bloques o “segmentos” que pueden almacenarse en direcciones que no tienen que ser necesariamente adyacentes, por lo que es más compleja pero más eficiente que la asignación continua.
Asignación Contigua de Almacenamiento de Un Solo Usuario.
Se consideran S. O. que ya poseen desarrollado el “sistema de control de entrada / salida”: IOCS: input / output control system

El tamaño de los programas está limitado por la cantidad de memoria principal, pero se puede superar este límite con técnicas de “recubrimientos”, con las siguientes características:

* Si una sección particular del programa ya no es necesaria, se carga otra sección desde el almacenamiento secundario ocupando las áreas de memoria liberadas por la sección que ya no se necesita.
* La administración manual por programa del recubrimiento es complicada y dificulta el desarrollo y el mantenimiento.

Multiprogramación de Partición Variable.

Los procesos ocupan tanto espacio como necesitan, pero obviamente no deben superar el espacio disponible de memoria.

No hay límites fijos de memoria, es decir que la partición de un trabajo es su propio tamaño.
Se consideran “esquemas de asignación contigua”, dado que un programa debe ocupar posiciones adyacentes de almacenamiento.
Los procesos que terminan dejan disponibles espacios de memoria principal llamados “agujeros”:
* Pueden ser usados por otros trabajos que cuando finalizan dejan otros “agujeros” menores.
* En sucesivos pasos los “agujeros” son cada vez más numerosos pero más pequeños, por lo que se genera un desperdicio de memoria principal. Combinación de agujeros (áreas libres).
Consiste en fusionar agujeros adyacentes para formar uno sencillo más grande.
Se puede hacer cuando un trabajo termina y el almacenamiento que libera tiene límites con otros agujeros.

Compresión o Compactación de Almacenamiento.

Puede ocurrir que los agujeros (áreas libres) separados distribuidos por todo el almacenamiento principal constituyan una cantidad importante de memoria:

* Podría ser suficiente (el total global disponible) para alojar a procesos encolados en espera de memoria.
* Podría no ser suficiente ningún área libre individual.

La técnica de compresión de memoria implica pasar todas las áreas ocupadas del almacenamiento a uno de los extremos de la memoria principal:

* Deja un solo agujero grande de memoria libre contigua.
* Esta técnica se denomina “recogida de residuos”
Estrategias de Colocación del Almacenamiento.
Se utilizan para determinar el lugar de la memoria donde serán colocados los programas y datos que van llegando y se las clasifica de la siguiente manera:
* “Estrategia de mejor ajuste”:
*Un trabajo nuevo es colocado en el agujero en el cual quepa de forma más ajustada:
* Debe dejarse el menor espacio sin usar.
* “Estrategia de primer ajuste”:
* Un trabajo nuevo es colocado en el primer agujero disponible con tamaño suficiente para alojarlo.
* “Estrategia de peor ajuste”:
* Consiste en colocar un programa en el agujero en el que quepa de la peor manera, es decir en el más grande posible:
* El agujero restante es también grande para poder alojar a un nuevo programa relativamente grande.
Organización del Almacenamiento Virtual.
“Almacenamiento virtual ” significa la capacidad de direccionar un espacio de almacenamiento mucho mayor que el disponible en el almacenamiento primario de determinado sistema de computación.
Esta tecnología apareció en 1960 en la Universidad de Manchester (Inglaterra), en el sistema “Atlas”.
Los métodos más comunes de implementación son mediante:
* Técnicas de “paginación”.
* Técnicas de “segmentación”.
* Una combinación de ambas técnicas.
Las direcciones generadas por los programas en su ejecución no son, necesariamente, aquellas contenidas en el almacenamiento primario (memoria real), ya que las direcciones virtuales suelen seleccionarse dentro de un número mucho mayor de direcciones que las disponibles dentro del almacenamiento primario.
La evolución en las organizaciones de almacenamiento puede resumirse como sigue:
Real:
* Sistemas dedicados a un solo usuario.
* Sistemas de multiprogramación en memoria real:
* Multiprogramación en partición fija:
* Absoluta.
* Relocalizable (reubicable).
* Multiprogramación en partición variable.
Virtual:
* Multiprogramación en almacenamiento virtual:
* Paginación pura.
* Segmentación pura.
* Combinación paginación / segmentación.

Los mecanismos de “traducción dinámica de direcciones” (dat) convierten las direcciones virtuales en reales al ejecutarse el proceso.
Las direcciones contiguas dentro del espacio de direcciones virtuales de un proceso no tienen por qué ser contiguas dentro del almacenamiento real, a esto se denomina “contigüidad artificial.

Compartimiento de Recursos en un Sistema de Paginación.
En sistemas multiprogramados, especialmente en los de tiempo compartido, es común que más de un usuario estén ejecutando los mismos programas.
Para optimizar el uso de la memoria real se comparten las páginas que pueden ser compartidas:
* El compartimiento debe ser cuidadosamente controlado para evitar que un proceso modifique datos que otro proceso esta leyendo.
*Los programas se encuentran divididos en áreas separadas de “procedimiento” y “datos”.
*Los procedimientos no modificables se llaman “procedimientos puros reentrantes”.
*Los datos y procedimientos modificables no pueden ser compartidos.
*Los datos no modificables (ej.: tablas fijas) son compartibles.
* Se debe identificar cada página como compartible o no.
* Habrá marcos (celdas) de páginas compartidos por varios procesos.
El compartimiento:
* Reduce la cantidad de almacenamiento primario necesario para la ejecución eficaz de un grupo de procesos.
* Puede hacer posible que un sistema determinado mantenga una cantidad mayor de usuarios (procesos).
Segmentación.

En los sistemas de “segmentación” un programa y sus datos pueden ocupar varios bloques separados de almacenamiento real.

Los bloques:
* No necesitan ser de igual tamaño.
* Los bloques separados no necesitan ser adyacentes.
* Deben estar compuestos de posiciones contiguas de almacenamiento.

Se complica la protección de bloques de memoria de un proceso de usuario.
Es más difícil limitar el rango de acceso de cualquier programa.
Un esquema posible de protección es el uso de claves de protección del almacenamiento.
* Las claves están bajo el control estricto del S. O.
* Un programa de usuario, a quien corresponde una cierta clave en la cpu, solo puede hacer referencia a los otros bloques del almacenamiento con igual clave de protección.

Un proceso solo puede ejecutarse si su segmento actual (como mínimo) está en el almacenamiento primario.
Los segmentos se transfieren del almacenamiento secundario al primario como unidades completas.
Un nuevo segmento puede ser colocado en una serie disponible de posiciones contiguas del almacenamiento primario de tamaño suficiente para alojar al segmento.
La traducción dinámica de direcciones utiliza una “tabla de mapa de segmentos”.

jueves, 2 de julio de 2009

PROCESOS CONCURRENTES

LOS CLÁSICOS PROBLEMAS DE LA SINCRONIZACIÓN DE PROCESOS.

El del fumador de cigarros: Considere un sistema con tres procesos fumadores y un proceso agente. Cada fumador está continuamente enrollando y fumando cigarrillos. Sin embargo, para enrollar y fumar un cigarrillo, el fumador necesita tres ingredientes: tabaco, papel, y fósforos. Uno de los procesos fumadores tiene papel, otro tiene el tabaco y el tercero los fósforos. El agente tiene una cantidad infinita de los tres materiales. El agente coloca dos de los ingredientes sobre la mesa. El fumador que tiene el ingrediente restante enrolla un cigarrillo y se lo fuma, avisando al agente cuando termina. Entonces, el agente coloca dos de los tres ingredientes y se repite el ciclo.

La panadería de Lamport: En este problema una panadería tiene una variedad de panes y pasteles vendidos por n vendedores. Cada uno de los cuales toma un número al entrar. El cliente espera hasta oír su número. Cuando el vendedor se desocupa, llama al siguiente numero.


Los filósofos que cenan (sabios): Hay cinco filósofos chinos que se pasan sus vidas pensando y comiendo. Comparten una mesa circular, alrededor de la cual se sientan. En su centro se encuentra con una provisión infinita de arroz, y sobre ella hay cinco palitos, uno de cada lado de los filósofos. Cuando un filósofo piensa, no interactúa con sus colegas. De vez en cuando, un filósofo tiene hambre y trata de levantar los dos palitos más cercanos a él. Un filósofo puede levantar un palito a la vez, y no puede tomar un palito que ya está en la mano de un vecino. Cuando un filósofo tiene ambos palitos, puede comer. Cuando termino de hacerlo, deja sus dos palitos y comienza a pensar de nuevo.


El barbero dormilón: Una peluquería tiene un barbero, una silla de peluquero y n sillas para que se sienten los clientes en espera, si es que los hay. Si no hay clientes presentes, el barbero se sienta en su silla de peluquero y se duerme. Cuando llega un cliente, este debe despertar al barbero dormilón. Si llegan más clientes mientras el barbero corta el cabello de un cliente, estos deben esperar sentados (si hay sillas desocupadas) o salirse de la peluquería (si todas las sillas están ocupadas). El problema consiste en programar al barbero y los clientes sin entrar en condición de competencia.


Lectores y escritores: Imaginemos una enorme base de datos, como por ejemplo un sistema de reservaciones de en una línea aérea, con muchos procesos en competencia, que intentan leer y escribir en ella. Se puede aceptar que varios procesos lean la base de datos al mismo tiempo, pero si uno de los procesos está escribiendo, (es decir modificando) la base de datos, ninguno de los demás procesos deberá tener acceso a esta, ni siquiera los lectores. El problema es como programar a los lectores y escritores.


Productor/Consumidor: También conocido como bounded buffer problem o problema del buffer limitado. Dos procesos comparten un almacén (buffer) de tamaño fijo. Uno de ellos, el productor, coloca información en el almacén (buffer) mientras que el otro, el consumidor, la obtiene de él. Si el productor desea colocar un nuevo elemento, y el almacén se encuentra lleno, este deberá irse a \dormir". El consumidor despertara al productor cuando elimine un elemento del almacén. De forma análoga, si el almacén esta vació y el consumidor desea eliminar un elemento del almacén, este debe \dormirse" hasta que el productor coloque algo en el almacén.


EXCLUSIÓN MUTUA.

Los algoritmos de exclusión mutua (comúnmente abreviada como mutex por mutual exclusión) se usan en programación concurrente para evitar que fragmentos de código conocidos como secciones críticas accedan al mismo tiempo a recursos que no deben ser compartidos.
a mayor parte de estos recursos son las señales, contadores, colas y otros datos que se emplean en la comunicación entre el código que se ejecuta cuando se da servicio a una interrupción y el código que se ejecuta el resto del tiempo. Se trata de un problema de vital importancia porque, si no se toman las precauciones debidas, una interrupción puede ocurrir entre dos instrucciones cualesquiera del código normal y esto puede provocar graves fallos.
La técnica que se emplea por lo común para conseguir la exclusión mutua es inhabilitar las interrupciones durante el conjunto de instrucciones más pequeño que impedirá la corrupción de la estructura compartida (la sección crítica). Esto impide que el código de la interrupción se ejecute en mitad de la sección crítica.
En un sistema multiprocesador de memoria compartida, se usa la operación indivisible test-and-set sobre una bandera, para esperar hasta que el otro procesador la despeje. La operación test-and-set realiza ambas operaciones sin liberar el bus de memoria a otro procesador. Así, cuando el código deja la sección crítica, se despeja la bandera. Esto se conoce como spin lock o espera activa.
La mayoría de los métodos de exclusión mutua clásicos intentan reducir la latencia y espera activa mediante las colas y cambios de contexto. Algunos investigadores afirman que las pruebas indican que estos algoritmos especiales pierden más tiempo del que ahorran.
A pesar de todo lo dicho, muchas técnicas de exclusión mutua tienen efectos colaterales. Por ejemplo, los semáforos permiten interbloqueos (deadlocks) en los que un proceso obtiene un semáforo, otro proceso obtiene el semáforo y ambos se quedan a la espera de que el otro proceso libere el semáforo. Otros efectos comunes incluyen la inanición, en el cual un proceso esencial no se ejecuta durante el tiempo deseado, y la inversión de prioridades, en el que una tarea de prioridad elevada espera por otra tarea de menor prioridad, así como la latencia alta en la que la respuesta a las interrupciones no es inmediata.


SECCIÓN CRÍTICA.

En programación concurrente, se define como a la porción de código de un programa de computador el cual accede a un recurso compartido (estructura de datos ó dispositivo) que no debe de ser accedido por mas de un hilo en ejecución (thread). La sección crítica por lo general termina en un tiempo determinado y el hilo, proceso ó tarea solo tendrá que esperar un período determinado de tiempo para entrar. Se necesita de un mecanismo de sincronización en la entrada y salida de la sección crítica para asegurar la utilización exclusiva del recurso, por ejemplo un semáforo.
El acceso concurrente se controla teniendo cuidado de las variables que se modifican dentro y fuera de la sección crítica. La sección crítica se utiliza por lo general cuando un programa multihilo actualiza múltiples variables sin un hilo de ejecución separado que lleve los cambios conflictivos a esos datos. Una situación similar, la sección crítica puede ser utilizada para asegurarse de que un recurso compartido, por ejemplo, una impresora, puede ser accedida por un solo proceso a la vez.
La manera en como se implementan las secciones puede variar dependiendo de los diversos sistemas operativos.
Sólo un proceso puede estar en una sección crítica a la vez.



Modelo de sección crítica.

El modelo de sección crítica que vamos a utilizar sigue el siguiente protocolo genérico:
Entrar_SC(esta_SC) /* Solicitud de ejecutar esta_SC */
/* código de esta_SC */
Dejar_SC(esta_SC) /* Otro proceso puede ejecutar esta_SC */
Es decir, cuando un proceso quiere entrar a la sección crítica:
(1) ejecuta Entrar_SC(), y si la sección crítica está ocupada el proceso espera;
(2) ejecuta la sección crítica;
(3) ejecuta Dejar_SC(), permitiendo que entre uno de los procesos en espera.
La decisión de qué proceso es el seleccionado para entrar en el paso (3) puede tener consecuencias importantes, como se comentará más adelante. En general, puede asumirse disciplina FIFO.
Un aspecto fundamental es cómo se realiza la espera en Entrar_SC(), lo que determina el tipo de mecanismo de sincronización que se debe utilizar. Esto dependerá del tiempo que el proceso deba esperar para entrar a la sección crítica. La Figura C muestra un ejemplo de utilización de una sección crítica para implementar sincronización productor-consumidor. Hay que advertir que este ejemplo sólo es válido para un productor y un consumidor. Con n productores y m consumidores se producirían condiciones de carrera. Se propone como ejercicio la modificación de este código para el caso general.