Fondo Musical

sábado, 9 de julio de 2016

INTERBLOQUEOS


Los sistemas computacionales están llenos de recursos que pueden ser utilizados por sólo un proceso a la vez. Algunos ejemplos comunes son las impresoras, las unidades de cinta y las ranuras en los tableros internos del sistema.
El proceso A pide permiso para utilizar el escáner y se le otorga.
 El proceso B se programa de manera distinta y solicita primero el grabador de CDs, y también se le otorga. Ahora A pide el grabador de CDs, pero la petición se rechaza hasta que B lo libere. Por desgracia, en vez de liberar el grabador de CD, B pide el escáner.
 En este punto ambos procesos están bloqueados y permanecerán así para siempre. A esta situación se le conoce como interbloqueo.
Los interbloqueos también pueden ocurrir entre máquinas A menudo, los dispositivos como escáneres, grabadores de CD, impresoras y unidades de cinta se conectan a la red como recursos compartidos, disponibles para cualquier usuario en cualquier equipo. Si estos dispositivos se pueden reservar de manera remota (es decir, desde el equipo doméstico del usuario), pueden ocurrir los mismos tipos de interbloqueos antes descritos. Las situaciones más complicadas pueden ocasionar interbloqueos que involucren a tres, cuatro o más dispositivos y usuarios.
Los interbloqueos pueden ocurrir en una variedad de situaciones, además de solicitar dispositivos de E/S dedicados.
Si el proceso A bloquea el registro R1 y el proceso B bloquea el registro R2, y después cada proceso trata de bloquear el registro del otro, también tenemos un interbloqueo. Por ende, los interbloqueos pueden ocurrir en los recursos de hardware o de software.
Se ha escrito mucho sobre los interbloqueos.
Dos bibliografías sobre el tema han aparecido en Operating Systems Review y deben consultarse en busca de referencias (Newton, 1979; y Zobel, 1983). Aunque estas bibliografías son antiguas, la mayor parte del trabajo sobre los interbloqueos se hizo mucho antes de 1980, por lo que aún son de utilidad.

Recursos
Una clase principal de interbloqueos involucra a los recursos, Los interbloqueos pueden ocurrir cuando a los procesos se les otorga acceso exclusivo a los dispositivos, registros de datos, archivos, etcétera. Para que el análisis sobre los interbloqueos sea lo más general posible, nos referiremos a los objetos otorgados como recursos Un recurso puede ser un dispositivo de hardware (por ejemplo, una unidad de cinta) o una pieza de información (como un registro bloqueado en una base de datos). En resumen, un recurso es cualquier cosa que se debe adquirir, utilizar y liberar con el transcurso del tiempo.

Recursos apropiativos y no apropiativos
Los recursos son de dos tipos: apropiativos y no apropiativos. Un recurso apropiativo es uno que se puede quitar al proceso que lo posee sin efectos dañinos. La memoria es un ejemplo de un recurso apropiativo.
Un recurso no apropiativo es uno que no se puede quitar a su propietario actual sin hacer que el cómputo falle. Si un proceso ha empezado a quemar un CD-ROM y tratamos de quitarle de manera repentina el grabador de CD y otorgarlo a otro proceso, se obtendrá un CD con basura.
En general, los interbloqueos involucran a los recursos no apropiativos. Los interbloqueos potenciales que pueden involucrar a los recursos apropiativos por lo general se pueden resolver mediante la reasignación de los recursos de un proceso a otro. Por ende, nuestro análisis se enfocará en los recursos no apropiativos.
La secuencia de eventos requerida para utilizar un recurso se proporciona a continuación, en un formato abstracto.
1. Solicitar el recurso.
2. Utilizar el recurso.
3. Liberar el recurso.

Adquisición de recursos
Para ciertos tipos de recursos, como los registros de una base de datos, es responsabilidad de los procesos de usuario administrar su uso. Una manera de permitir que los usuarios administren los recursos es asociar un semáforo con cada recurso. Estos semáforos se inicializan con 1. Se pueden utilizar mutexes de igual forma. Los tres pasos antes listados se implementan como una operación down en el semáforo para adquirir el recurso, usarlo y finalmente realizar una operación up en el recurso para liberarlo.
Algunas veces los procesos necesitan dos o más recursos. Se pueden adquirir de manera secuencial. Si se necesitan más de dos recursos, sólo se adquieren uno después del otro. Mientras sólo haya un proceso involucrado, todo funciona sin problemas.

INTRODUCCIÓN A LOS INTERBLOQUEOS
El interbloqueo se puede definir formalmente de la siguiente manera:
Un conjunto de procesos se encuentra en un interbloqueo si cada proceso en el conjunto está esperando un evento que sólo puede ser ocasionado por otro proceso en el conjunto
Debido a que todos los procesos están en espera, ninguno de ellos producirá alguno de los eventos que podrían despertar a cualquiera de los otros miembros del conjunto, y todos los procesos seguirán esperando para siempre.
El evento por el que cada proceso espera es la liberación de algún recurso que actualmente es poseído por otro miembro del conjunto.
El número de procesos y el número de cualquier tipo de recursos poseídos y solicitados es irrelevante. Este resultado se aplica a cualquier tipo de recurso, tanto de hardware como de software. A este tipo de interbloqueo se le conoce como interbloqueo de recursos.

Condiciones para los interbloqueos de recursos
Coffman y colaboradores (1971) mostraron que deben aplicarse cuatro condiciones para un interbloqueo
(De recursos):
|1. Condición de exclusión mutua. Cada recurso se asigna en un momento dado a sólo un proceso, o está disponible.
2. Condición de contención y espera. Los procesos que actualmente contienen recursos que se les otorgaron antes pueden solicitar nuevos recursos.
3. Condición no apropiativa. Los recursos otorgados previamente no se pueden quitar a un proceso por la fuerza. Deben ser liberados de manera explícita por el proceso que los contiene.
4. Condición de espera circular. Debe haber una cadena circular de dos o más procesos, cada uno de los cuales espera un recurso contenido por el siguiente miembro de la cadena.
Las cuatro condiciones deben estar presentes para que ocurra un interbloqueo.
  
Modelado de interbloqueos
Holt (1972) mostró cómo se pueden modelar estas cuatro condiciones mediante el uso de gráficos dirigidos.
Los gráficos tienen dos tipos de nodos: procesos, que se muestran como círculos, y recursos, que se muestran como cuadros. Un arco dirigido de un nodo de recurso (cuadro) a un nodo de proceso (círculo) significa que el recurso fue solicitado previamente por, y asignado a, y actualmente es contenido por ese proceso.


        EL ALGORITMO DE LA AVESTRUZ
El método más simple es el algoritmo de la avestruz: meta su cabeza en la arena y pretenda que no hay ningún problema.† Las personas reaccionan a esta estrategia de diversas formas. Los matemáticos la encuentran totalmente inaceptable y dicen que los interbloqueos se deben prevenir a toda costa; los ingenieros preguntan con qué frecuencia se espera el problema, con qué frecuencia falla el sistema por otras razones y qué tan grave es un interbloqueo. Si ocurren interbloqueos en promedio de una vez cada cinco años, pero los fallos del sistema debido al hardware, errores del compilador y errores en el sistema operativo ocurren una vez por semana, la mayoría de los ingenieros no estarán dispuestos a reducir considerablemente el rendimiento por la conveniencia de eliminar los interbloqueos.
Para que este contraste sea más específico, considere un sistema operativo que bloquea al proceso llamador cuando no se puede llevar a cabo una llamada a los sistemas open en un dispositivo físico, como una unidad de CD-ROM o una impresora, debido a que el dispositivo está muy ocupado.
Por lo general es responsabilidad del driver (controlador) de dispositivos decidir qué acción tomar bajo tales circunstancias. Bloquear o devolver una clave de error son dos posibilidades obvias. Si un proceso abre exitosamente la unidad de CD-ROM y otro la impresora, y después cada proceso trata de abrir el otro recurso y se bloquea en el intento, tenemos un interbloqueo. Pocos sistemas actuales detectarán esto.

DETECCIÓN Y RECUPERACIÓN DE UN INTERBLOQUEO
Una segunda técnica es la detección y recuperación. Cuando se utiliza esta técnica, el sistema no trata de evitar los interbloqueos. En vez de ello, intenta detectarlos cuando ocurran y luego realiza cierta acción para recuperarse después del hecho
Detección de interbloqueos con un recurso de cada tipo sólo existe un recurso de cada tipo. Dicho sistema podría tener un escáner, un grabador de CD, un trazador (plotter) y una unidad de cinta, pero no más que un recurso de cada clase.
Para un sistema así, podemos construir un gráfico de recursos.
Si este gráfico contiene uno o más ciclos, existe un interbloqueo. Cualquier proceso  que forme parte de un ciclo está en interbloqueo. Si no existen ciclos, el sistema no está en interbloqueo.
Como ejemplo de un sistema más complejo que los que hemos analizado hasta ahora, considere un sistema con siete procesos, A a G, y seis recursos, R a W. El estado de cuáles recursos están contenidos por algún proceso y cuáles están siendo solicitados es el siguiente:
1. El proceso A contiene a R y quiere a S.
2. El proceso B no contiene ningún recurso pero quiere a T.
3. El proceso C no contiene ningún recurso pero quiere a S.
4. El proceso D contiene a U y quiere a S y a T.
5. El proceso E contiene a T y quiere a V.
6. El proceso F contiene a W y quiere a S.
7. El proceso G contiene a V y quiere a U.


 


Es relativamente fácil distinguir los procesos en interbloqueo a simple vista a partir de un sencillo gráfico, para usar este método en sistemas reales necesitamos un algoritmo formal para la detección de interbloqueos. Hay muchos algoritmos conocidos para detectar ciclos en gráficos dirigidos. A continuación veremos un algoritmo simple que inspecciona un gráfico y termina al haber encontrado un ciclo, o cuando ha demostrado que no existe ninguno. Utiliza cierta estructura dinámica de datos: L, una lista de nodos, así como la lista de arcos. Durante el algoritmo, los arcos se marcarán para indicar que ya han sido inspeccionados, para evitar repetir inspecciones.
El algoritmo opera al llevar a cabo los siguientes pasos, según lo especificado:
1. Para cada nodo N en el gráfico, realizar los siguientes cinco pasos con N como el nodo inicial.
2. Inicializar L con la lista vacía y designar todos los arcos como desmarcados.
3. Agregar el nodo actual al final de L y comprobar si el nodo ahora aparece dos veces en L.
Si lo hace, el gráfico contiene un ciclo (listado en L) y el algoritmo termina.
4. Del nodo dado, ver si hay arcos salientes desmarcados. De ser así, ir al paso 5; en caso contrario, ir al paso
5. Elegir un arco saliente desmarcado al azar y marcarlo. Después seguirlo hasta el nuevo nodo actual e ir al paso 3.
6. Si este nodo es el inicial, el gráfico no contiene ciclos y el algoritmo termina. En caso contrario, ahora hemos llegado a un punto muerto. Eliminarlo y regresar al nodo anterior; es decir, el que estaba justo antes de éste, hacerlo el nodo actual e ir al paso 3.
Lo que hace este algoritmo es tomar cada nodo en turno, como la raíz de lo que espera sea un árbol, y realiza una búsqueda de un nivel de profundidad en él. Si alguna vez regresa a un nodo que ya se haya encontrado, entonces ha encontrado un ciclo. Si agota todos los arcos desde cualquier nodo dado, regresa al nodo anterior. Si regresa hasta la raíz y no puede avanzar más, el subgráfico que se puede alcanzar desde el nodo actual no contiene ciclos. Si esta propiedad se aplica para todos los nodos, el gráfico completo está libre de ciclos, por lo que el sistema no está en interbloqueo.

Detección del interbloqueo con varios recursos de cada tipo
Cuando existen varias copias de algunos de los recursos, se necesita un método distinto para detectar interbloqueos. Ahora presentaremos un algoritmo basado en matrices para detectar interbloqueos entre n procesos, de P1 a Pn. Hagamos que el número de clases de recursos sea m, con E1 recursos de la clase 1, E2 recursos de la clase 2 y en general, Ei recursos de la clase i (1 ≤i ≤m). E es el vector de recursos existentes. Este vector proporciona el número total de instancias de cada recurso en existencia. Por ejemplo, si la clase 1 son las unidades de cinta, entonces E1 _ 2 significa que el sistema tiene dos unidades de cinta.
En cualquier instante, algunos de los recursos están asignados y no están disponibles. Hagamos que A sea el vector de recursos disponibles, donde Ai proporciona el número de instancias del recurso i que están disponibles en un momento dado (es decir, sin asignar). Si ambas de nuestras unidades de cinta están asignadas, A1 será 0.
Ahora necesitamos dos arreglos: C, la matriz de asignaciones actuales y R, la matriz de peticiones.
La i-ésima fila de C nos indica cuántas instancias de cada clase de recurso contiene Pi en un momento dado. Así Cij es el número de instancias del recurso j que están contenidas por el proceso i. De manera similar, Rij es el número de instancias del recurso j que desea Pi. Estas cuatro estructuras de datos

El algoritmo de detección de interbloqueos se muestra a continuación.
1. Buscar un proceso desmarcado, Pi, para el que la i-ésima fila de R sea menor o igual que A.
2. Si se encuentra dicho proceso, agregar la i-ésima fila de C a A, marcar el proceso y regresar al paso 1.
3. Si no existe dicho proceso, el algoritmo termina.

RECUPERACION DE INTERBLOQUEOS

Un sistema que pretenda recuperarse del interbloqueo, debe invocar a un algoritmo de detección cuando lo considere oportuno.
 Formas de intentar la recuperación:
 Terminación de procesos
 Expropiación de recursos

Terminación de procesos
 Matando a todos los procesos implicados (drástico)
 Matando a uno de los procesos ¿cuál?
 El que más recursos libere
 El que menos tiempo lleve en ejecución...
 Retrocediendo la ejecución de algún proceso (rollback)
 Muy complicado de implementar y necesita que el programa esté diseñado para que pueda retroceder

Expropiación de recursos
 Selección de la víctima
 ¿Qué recursos y de que procesos se expropian?
 Retroceso
 Si expropiamos un recurso de un proceso, ¿qué hacemos con ese proceso?
 En ambos casos (terminación de procesos o expropiación de recursos) hay que tener cuidado de no provocar la inanición de procesos

Recuperación por medio de apropiación

En algunos casos puede ser posible quitar temporalmente un recurso a su propietario actual y otorgarlo a otro proceso. En muchos casos se puede requerir intervención manual, en especial en los sistemas operativos de procesamiento por lotes que se ejecutan en mainframes.

Recuperación a través del retroceso
Realizar puntos de comprobación en un proceso significa que su estado se escribe en un archivo para poder reiniciarlo más tarde. El punto de comprobación no sólo contiene la imagen de la memoria, sino también el estado del recurso; en otras palabras, qué recursos están asignados al proceso en un momento dado.
Para realizar la recuperación, un proceso que posee un recurso necesario se revierte a un punto en el tiempo antes de que haya adquirido ese recurso, para lo cual se inicia uno de sus puntos de comprobación anteriores.

Recuperación a través de la eliminación de procesos
La forma más cruda y simple de romper un interbloqueo es eliminar uno o más procesos. Una posibilidad es eliminar a uno de los procesos en el ciclo.
En este método, el proceso a eliminar se elige con cuidado, debido a que está conteniendo recursos que necesita cierto proceso en el ciclo.
Donde sea posible, es mejor eliminar un proceso que se pueda volver a ejecutar desde el principio sin efectos dañinos.
Un proceso que actualiza una base de datos no siempre se puede ejecutar una segunda vez en forma segura. Si el proceso agrega 1 a algún campo de una tabla en la base de datos, al ejecutarlo una vez, después eliminarlo y volverlo a ejecutar de nuevo, se agregará 2 al campo, lo cual es incorrecto.

CÓMO EVITAR INTERBLOQUEOS
Con la evitación no se tienen reglas estáticas a los procesos, sino que el sistema operativo analiza cada petición de recursos y determina si el sistema quedará en un estado estable o inestable, en este último caso, se deniega la petición, posponiéndola temporalmente.

Conceptos
La evitación se basa en los siguientes conceptos:
Estado de asignación de recursos: Número de recursos asignados, disponibles y máximo de recursos posibles por proceso.
Secuencia segura: Secuencia de finalización de procesos, tal que todos los procesos puedan finalizar exitosamente, iniciando en un determinado estado de asignación de recursos
Estado seguro de asignación de recursos: Estado de asignación de recursos, donde existe al menos una secuencia segura.
Estado inseguro de asignación de recursos: No existe ninguna secuencia segura. Obsérvese, que aunque un estado inseguro no implica que exista interbloqueo, talvez una secuencia determinada de eventos lleve a uno.
Estados seguros e inseguros
Se dice que un estado es seguro si hay cierto orden de programación en el que se puede ejecutar cada proceso hasta completarse, incluso aunque todos ellos solicitaran de manera repentina su número máximo de recursos de inmediato.
Un estado inseguro no es un estado en interbloqueo, la diferencia entre un estado seguro y uno inseguro es que, desde un estado seguro, el sistema puede garantizar que todos los procesos terminarán; desde un estado inseguro, no se puede dar esa garantía.



El algoritmo del banquero para un solo recurso

Dijkstra (1965) ideó un algoritmo de programación que puede evitar interbloqueos; este algoritmo se conoce como el algoritmo del banquero y es una extensión del algoritmo de detección de interbloqueos.
Se modela de la forma en que un banquero de una pequeña ciudad podría tratar con un grupo de clientes a los que ha otorgado líneas de crédito. Lo que hace el algoritmo es comprobar si al otorgar la petición se produce un estado inseguro. Si es así, la petición se rechaza. Si al otorgar la petición se produce un estado seguro, se lleva a cabo.
En la imagen (a) podemos ver cuatro clientes, A, B, C y D, cada uno de los cuales ha recibido un cierto número de unidades de crédito (por ejemplo, 1 unidad es 1K dólares). El banquero sabe que no todos los clientes necesitan su crédito máximo de inmediato, por lo que ha reservado sólo 10 unidades en vez de 22 para darles servicio (en esta analogía, los clientes son procesos, las unidades son, por ejemplo, unidades de cinta, y el banquero es el sistema operativo).



Los clientes hacen sus respectivas labores, pidiendo préstamos de vez en cuando (es decir, solicitando recursos).
Este estado es seguro debido a que, con dos unidades restantes, el banquero puede retrasar cualquier petición excepto la de C, con lo cual deja que C termine y libere todos sus cuatro recursos. Con cuatro unidades a la mano, el banquero puede dejar que D o B tengan las unidades necesarias, y así en lo sucesivo. Considere lo que ocurriría si se otorgara una petición de B por una o más unidades en la (b). Tendríamos la situación de la (c), que es insegura. Si todos los clientes pidieran de manera repentina sus préstamos máximos, el banquero no podría satisfacer a ninguno de ellos, y tendríamos un interbloqueo.

El algoritmo del banquero considera cada petición a medida que va ocurriendo, y analiza si al otorgarla se produce un estado seguro. Si es así, se otorga la petición; en caso contrario, se pospone hasta más tarde. Para ver si un estado es seguro, el banquero comprueba si tiene los suficientes recursos para satisfacer a algún cliente.

El algoritmo del banquero para varios recursos

El algoritmo del banquero se puede generalizar para manejar varios recursos. La figura muestra cómo funciona.
En la figura se muestran dos matrices. La de la izquierda muestra cuántas instancias de cada recurso están asignadas en un momento dado a cada uno de los cinco procesos. La matriz de la derecha muestra cuántos recursos sigue necesitando cada proceso para poder completarse.



Al igual que en el caso con un solo recurso, los procesos deben declarar sus necesidades totales de recursos antes de ejecutarse, por lo que el sistema puede calcular la matriz derecha en cada instante.
Los tres vectores a la derecha de la figura muestran los recursos existentes (E), los recursos poseídos
(P) y los recursos disponibles (A), respectivamente. De E podemos ver que el sistema tiene seis unidades de cinta, tres trazadores, cuatro impresoras y dos unidades de CD-ROM. De éstos, ya hay asignados cinco unidades de cinta, tres trazadores, dos impresoras y dos unidades de CD-ROM.


Ahora se puede declarar el algoritmo para comprobar si un estado es seguro.
1. Buscar una fila R, cuyas necesidades de recursos no satisfechas sean menores o iguales que A. Si no existe dicha fila, el sistema entrará en interbloqueo en un momento dado, debido a que ningún proceso se podrá ejecutar hasta completarse (suponiendo que los procesos mantienen todos los recursos hasta que terminan).

2. Suponer que el proceso seleccionado de la fila solicita todos los recursos que necesita (lo que se garantiza que es posible) y termina. Marcar ese proceso como terminado y agregar todos sus recursos al vector A.

3. Repetir los pasos 1 y 2 hasta que todos los procesos se marquen como terminados (en cuyo caso el estado inicial era seguro) o hasta que no haya ningún proceso cuyas necesidades de recursos se puedan satisfacer (en cuyo caso hay un interbloqueo).


CÓMO PREVENIR INTERBLOQUEOS

Habiendo visto que evitar los interbloqueos es algo en esencia imposible, debido a que se requiere información sobre las peticiones futuras, que no se conocen, ¿cómo evitan los sistemas reales el interbloqueo?
La respuesta es volver a las cuatro condiciones establecidas por Coffman y colaboradores
(1971) para ver si pueden proporcionarnos una pista.

Cómo atacar la condición de exclusión mutua

Concepto de exclusión mutua:
Consiste en que un solo proceso excluye temporalmente a todos los demás para usar un recurso compartido de forma que garantice la integridad del sistema.

Concepto de sección critica:
Es la parte del programa con un comienzo y un final claramente marcados que generalmente contiene la actualización de una o más variables compartidas.
Para que una solución al problema de la exclusión mutua sea válida, se tienen que cumplir una serie de condiciones:
Hay que garantizar la exclusión mutua entre los diferentes procesos a la hora de acceder al recurso compartido. No puede haber en ningún momento dos procesos dentro de sus respectivas secciones críticas.
No se deben hacer suposiciones en cuanto a la velocidad relativa de los procesos en conflicto.
Ningún proceso que esté fuera de su sección crítica debe interrumpir a otro para el acceso a la sección crítica.
Cuando más de un proceso desee entrar en su sección crítica, se le debe conceder la entrada en un tiempo finito, es decir, que nunca se le tendrá esperando en un bucle que no tenga final.
REQUISITOS PARA LA EXCLUSIÓN MUTUA
  
 Sólo un proceso, de todos los que poseen secciones críticas por el mismo recurso compartido, debe tener permiso para entrar en ella en un momento dado.Un proceso que se interrumpe en una sección no crítica debe hacerlo sin interferir con los otros procesos.
  Un proceso no debe poder solicitar acceso a una sección crítica para después ser demorado indefinidamente, no puede permitirse el interbloqueo o la inanición.
 Si ningún proceso está en su sección crítica, cualquier proceso que solicite entrar en la suya debe poder hacerlo sin demora.
No se debe suponer sobre la velocidad relativa de los procesos o el número de procesadores.
6  Un proceso permanece en su sección crítica por un tiempo finito.
Una manera de satisfacer los requisitos de exclusión mutua es dejar la responsabilidad a los procesos que deseen ejecutar concurrentemente. Tanto si son programas del sistema como de aplicación, los procesos deben coordinarse unos con otros para cumplir la exclusión mutua, sin ayuda del lenguaje de programación o del sistema operativo. Estos métodos se conocen como soluciones por software.


Si podemos evitar que los procesos que contienen recursos esperen por más recursos, podemos eliminar los interbloqueos. Una forma de lograr esta meta es requerir que todos los procesos soliciten todos sus recursos antes de empezar su ejecución. Si completa al proceso se le asignará lo que necesite y podrá ejecutarse hasta completarse. Si uno o más recursos están ocupados, no se asignará nada y el proceso sólo esperará.

Un problema inmediato con este método es que muchos procesos no saben cuántos recursos necesitarán hasta que hayan empezado a ejecutarse. Otro problema es que los recursos no se utilizarán de una manera óptima con este método.
Sin embargo, algunos sistemas de procesamiento por lotes de mainframes requieren que el usuario liste todos los recursos en la primera línea de cada trabajo.
Una manera ligeramente distinta de romper la condición de contención y espera es requerir que un proceso que solicita un recurso libere temporalmente todos los recursos que contiene en un momento dado. Después puede tratar de obtener todo lo que necesite a la vez.

Cómo atacar la condición no apropiativa
Si a un proceso se le ha asignado la impresora y está a la mitad de imprimir su salida, quitarle la impresora a la fuerza debido a que el trazador que necesita no está disponible es algo engañoso como máximo, e imposible en el peor caso. Sin embargo, ciertos recursos se pueden virtualizar para evitar esta situación. Al colocar en una cola de impresión en el disco la salida de la impresora y permitir que sólo el demonio de impresión tenga acceso a la impresora real, se eliminan los interbloqueos que involucran a la impresora, aunque se crea uno para el espacio en disco.

Cómo atacar la condición de espera circular

La espera circular se puede eliminar de varias formas. Una de ellas es simplemente tener una regla que diga que un proceso tiene derecho sólo a un recurso en cualquier momento. Si necesita un segundo recurso, debe liberar el primero.
Otra manera de evitar la espera circular es proporcionar una numeración global de todos los recursos, como se muestra en la figura




Con esta regla, el gráfico de asignación de recursos nunca puede tener ciclos. Veamos por qué es esto cierto para el caso de dos procesos, en la figura (b). Podemos obtener un interbloqueo sólo si A solicita el recurso j y B solicita el recurso i. Suponiendo que i y j sean recursos distintos, tendrán diferentes números. Si i > j, entonces A no puede solicitar a j debido a que es menor de lo que ya tiene. Si i < j, entonces B no puede solicitar a i debido a que es menor de lo que ya tiene. De cualquier forma, el interbloqueo es imposible.

Con más de dos procesos se aplica la misma lógica.
Una variación menor de este algoritmo es retirar el requerimiento de que los recursos se adquieran en una secuencia cada vez más estricta, y simplemente insistir que ningún proceso puede solicitar un recurso menor del que ya contiene.


Los diversos métodos para evitar el interbloqueo se definen en la siguiente imagen:

 







Bloqueo de dos fases

Aunque los métodos para evitar y prevenir los interbloqueos no son muy prometedores en el caso general, para aplicaciones específicas se conocen muchos algoritmos excelentes de propósito especial. Como ejemplo, en muchos sistemas de bases de datos, una operación que ocurre con frecuencia es solicitar bloqueos sobre varios registros y después actualizar todos los registros bloqueados. Cuando hay varios procesos en ejecución al mismo tiempo, hay un peligro real de interbloqueo.
Este método se le conoce como bloqueo de dos fases. El proceso trata de bloquear todos los registros que necesita, uno a la vez.
Si tiene éxito pasa a la segunda fase, realizando sus actualizaciones y liberando los bloqueos. No se realiza ningún trabajo real en la primera fase.
Si durante la primera fase se necesita cierto registro que ya esté bloqueado, el proceso sólo libera todos sus bloqueos e inicia la primera fase desde el principio.

Interbloqueos de comunicaciones

Otro tipo de interbloqueo puede ocurrir en los sistemas de comunicaciones (como las redes), en donde dos o más procesos se comunican mediante el envío de mensajes.
Un arreglo común es que el proceso A envía un mensaje de petición al proceso B, y después se bloquea hasta que B envía de vuelta un mensaje de respuesta. Suponga que el mensaje de petición se pierde. A se bloquea en espera de la respuesta. B se bloquea en espera de una petición para que haga algo. Tenemos un interbloqueo.
Los interbloqueos de comunicación no se pueden evitar mediante el ordenamiento de recursos (ya que no hay ninguno), ni se puede evitar mediante una programación cuidadosa (ya que no hay momentos en los que se puede posponer una petición). Por fortuna hay otra técnica que por lo general se puede utilizar para romper los interbloqueos de comunicación: los tiempos de espera. En la mayoría de los sistemas de comunicación de red, cada vez que se envía un mensaje del que se espera una respuesta, también se inicia un temporizador. Si el temporizador termina su conteo antes de que llegue la respuesta, el emisor del mensaje asume que éste se ha perdido y lo envía de nuevo (una y otra vez, si es necesario). De esta forma se evita el interbloqueo.




Bloqueo activo
Esta estrategia se utiliza a menudo cuando se va a usar la exclusión mutua por un tiempo muy corto, y la sobrecarga de la suspensión es grande en comparación con realizar el trabajo. Considere una primitiva atómica en la que el proceso que llama prueba un mutex y lo sostiene o devuelve una falla.
El bloqueo activo puede ocurrir en formas sorprendentes. En algunos sistemas, el número total de procesos permitidos se determina con base en el número de entradas en la tabla de procesos.
Así, las entradas de la tabla de procesos son recursos finitos. Si una operación fork falla debido a que la tabla está llena, un método razonable para el programa que realiza la operación fork es esperar un tiempo aleatorio y probar de nuevo.

Inanición

Un problema muy relacionado con el interbloqueo y el bloqueo activo es la inanición. En un sistema dinámico, las peticiones de recursos ocurren todo el tiempo. Se necesita cierta política para decidir acerca de quién obtiene qué recurso y cuándo. Esta política, aunque parece razonable, puede ocasionar que ciertos procesos nunca reciban atención, aun cuando no estén en interbloqueo.
Un posible algoritmo de asignación es otorgar la impresora al proceso con el archivo más pequeño a imprimir
Este método maximiza el número de clientes satisfechos y parece razonable. Ahora considere lo que ocurre en un sistema ocupado, cuando un proceso tiene que imprimir un archivo enorme. Cada vez que la impresora esté libre, el sistema buscará y elegirá el proceso con el archivo más pequeño.

La inanición se puede evitar mediante el uso de una política de asignación de recursos del tipo “primero en llegar, primero en ser atendido”. Con este método, el proceso que espere más tiempo será el que se atienda primero. A su debido tiempo, cualquier proceso dado se convertirá en el más antiguo y, por ende, obtendrá el recurso que necesita.

domingo, 3 de julio de 2016

ADMINISTRACIÓN Y OPTIMIZACIÓN DE SISTEMAS DE ARCHIVOS

Administración del espacio en disco
Por lo general los archivos se almacenan en disco, así que la administración del espacio en disco es una cuestión importante para los diseñadores de sistemas de archivos.
Hay dos estrategias generales posibles para almacenar un archivo de n bytes: se asignan n bytes consecutivos de espacio en disco el archivo se divide en varios bloques (no necesariamente) contiguos.

Almacenar un archivo como una secuencia contigua de bytes tiene el problema obvio de que si un archivo crece, probablemente tendrá que moverse en el disco.

El mismo problema se aplica a los segmentos en memoria, excepto que la operación de mover un segmento en memoria es rápida, en comparación con la operación de mover un archivo de una posición en el disco a otra.

Tamaño de bloque
Dada la forma en que están organizados los discos, el sector, la pista y el cilindro son candidatos obvios para la unidad de asignación En un sistema de paginación, el tamaño de la página también es uno de los principales contendientes.

En un sistema de paginación, el tamaño de la página también es uno de los principales contendientes.



También significa que los pequeños archivos desperdician una gran cantidad de espacio en disco. Por otro lado, un tamaño de bloque pequeño significa que la mayoría de los archivos abarcarán varios bloques y por ende, necesitan varias búsquedas y retrasos rotacionales para leerlos la unidad de asignación es demasiado grande, desperdiciamos espacio; si es demasiado pequeña, desperdiciamos tiempo


Donde para cada tamaño de archivo de una potencia de dos, se lista el porcentaje de todos los archivos menores o iguales a éste para cada uno de los tres conjuntos de datos. Por ejemplo, en el 2005 el 59.13% de todos los archivos en la VU eran de 4 KB o menores y el 90.84% de todos los archivos eran de 64 KB o menores.
Por una parte, con un tamaño de bloque de 1 KB sólo entre 30 y 50% de todos los archivos caben en un solo bloque, mientras que con un bloque de 4 KB, el porcentaje de archivos que caben en un bloque aumenta hasta el rango entre 60 y 70%. Los demás datos en el artículo muestran que con un bloque de 4 KB, 93% de los bloques de disco son utilizados por 10% de los archivos más grandes.

Utilizar un bloque pequeño significa que cada archivo consistirá de muchos bloques. Cada bloque normalmente se requiere una búsqueda y un retraso rotacional, por lo que la acción de leer un archivo que consista de muchos bloques pequeños será lenta.
Como ejemplo, considere un disco con 1 MB por pista, un tiempo de rotación de 8.33 mseg y un tiempo de búsqueda promedio de 5 mseg. El tiempo en milisegundos para leer un bloque de k bytes es entonces la suma de los tiempos de búsqueda, de retraso rotacional y de transferencia:

5 + 4.165 + (k/1000000) =8.33


La curva sólida (escala del lado izquierdo) da la velocidad de datos del disco. La curva punteada (escala del lado derecho) da la eficiencia del espacio de disco. Todos los archivos son de 4 KB.
Los bloques pequeños son malos para el rendimiento pero buenos para el uso del espacio en el disco.

Cuando escribimos unos cuantos caracteres en el editor de texto bloc de notas (notepad), al guardar esto a un archivo se activarán 26 llamadas al sistema, incluyendo 3 intentos de apertura fallidos, 1 sobrescritura de archivo y 4 secuencias adicionales de abrir y cerrar.
Registro de bloques libres

Una vez que se ha elegido un tamaño de bloque, la siguiente cuestión es cómo llevar registro de los bloques libres.

Hay dos métodos utilizados ampliamente:
1.    Lista enlazada de bloques de disco.
2.    El mapa de bits.


1.- Cada bloque contiene tantos números de bloques de disco libres como pueda. Con un bloque de 1 KB y un número de bloque de disco de 32 bits, cada bloque en la lista de bloques libres contiene los números de 255 bloques libres considere un disco de 500 GB, que tiene aproximadamente 488 millones de bloques de disco. Para almacenar todas estas direcciones a 255 por bloque, se requiere una cantidad aproximada de 1.9 millones de bloques.

Se utiliza una lista enlazada de bloques de disco que contienen números de bloques libres. Se almacenan tantos números como se pueda en cada bloque. Para agilizar el proceso de búsqueda de un bloque libre, se mantiene uno o más bloques en memoria, dejando el resto en disco.
La desventaja es que cuando el bloque esta por llenarse puede provocar muchas operaciones de I/O al buscar otro bloque, producto de una serie de creaciones y eliminaciones de archivos y directorios.


2.- Un disco con n bloques requiere un mapa de bits con n bits. Los bloques libres se representan mediante 1s en el mapa, los bloques asignados mediante 0s (o viceversa).Para nuestro disco de 500 GB de ejemplo, necesitamos 488 millones de bits para el mapa, que requieren poco menos de 60,000 bloques de 1 KB para su almacenamiento.
No es sorpresa que el mapa de bits requiera menos espacio, ya que utiliza 1 bit por bloque, en comparación con 32 bits en el modelo de la lista enlazada.
Se crea un mapa donde se representa a cada bloque disponible con 1 bit.
Es muy eficiente en espacio, al emplear 1 bit en lugar de una palabra, excepto cuando el disco está lleno, caso en el cual la lista es más pequeña.
Al igual que la lista, se puede dejar solo una porción del mapa en memoria y el resto en disco.

Sólo si el disco está casi lleno (es decir, que tenga pocos bloques libres) es cuando el esquema de la lista enlazada requiere menos bloques que el mapa de bits.

Cuotas de disco.

Una cuota de disco es un límite establecido por el administrador del sistema que restringe ciertos aspectos del uso del sistema de archivos en los sistemas operativos modernos. El objetivo de la utilización de las cuotas de disco es limitar la asignación de espacio en el disco duro de una manera razonable.

Tipos de cuotas

Hay dos tipos básicos de las cuotas de disco. La primera, conocida como cuota de uso o cuota de bloques, limita la cantidad de espacio en disco que puede ser utilizado. La segunda, conocida como cuota de archivo o de inodo, limita el número de archivos y directorios que se pueden crear.
Además, los administradores suelen definir un nivel de advertencia, o cuota blanda, en la que se informa al usuario que se están acercando a su límite, que es menor que el límite efectivo, o cuota dura. También puede haber un intervalo de gracia pequeño, lo que permite a los usuarios violar temporalmente sus cuotas en ciertas cantidades, si es necesario. Cuando una cuota blanda es violada, el sistema envía normalmente al usuario (y en ocasiones al administrador también) algún tipo de mensaje.



Respaldos del sistema operativo

Una "copia de seguridad", "copia de respaldo" o también llamado "backup en tecnologías de la información e informática es una copia de los datos originales que se realiza con el fin de disponer de un medio para recuperarlos en caso de su pérdida. Las copias de seguridad son útiles ante distintos eventos y usos: recuperar los sistemas informáticos y los datos de una catástrofe informática, natural o ataque; restaurar una pequeña cantidad de archivos que pueden haberse eliminado accidentalmente, corrompido, infectado por un virus informático u otras causas; guardar información histórica de forma más económica que los discos duros y además permitiendo el traslado a ubicaciones distintas de la de los datos originales
Si el sistema de archivos de una computadora se pierde de manera irrevocable, ya sea debido a hardware o software, será difícil restaurar toda la información, llevará mucho tiempo y en muchos casos, podrá ser imposible.
Por lo general se realizan respaldos en cinta para manejar uno de dos problemas potenciales:
1. Recuperarse de un desastre.
2. Recuperarse de la estupidez.
El primer problema trata acerca de cómo hacer que la computadora vuelva a funcionar después de una falla general en el disco, un incendio, una inundación o cualquier otra catástrofe natural. En la práctica estas cosas no ocurren muy a menudo, razón por la cual muchas personas no se preocupan por realizar respaldos. Estas personas además tienden a no tener seguros contra incendios en sus hogares por la misma razón.
La segunda razón es que a menudo los usuarios remueven de manera accidental archivos, que más tarde vuelven a necesitar. Este problema ocurre con tanta frecuencia que cuando se “elimina” un archivo en Windows, no se elimina del todo, sino que sólo se mueve a un directorio especial, conocido como Papelera de reciclaje, para que pueda restaurarse con facilidad en un momento posterior.
Los respaldos llevan este principio más allá y permiten que los archivos que se removieron hace días, o incluso semanas, se restauren desde las cintas de respaldo antiguas.

Los respaldos llevan este principio más allá y permiten que los archivos que se removieron hace días, o incluso semanas, se restauren desde las cintas de respaldo antiguas. Para realizar un respaldo se requiere mucho tiempo y se ocupa una gran cantidad de espacio, por lo que es importante hacerlo con eficiencia y conveniencia. Estas consideraciones dan pie a las siguientes cuestiones. En primer lugar, ¿debe respaldarse el sistema completo o sólo parte de él? en muchas instalaciones, los programas ejecutables (binarios) se mantienen en una parte limitada del árbol del sistema de archivos. No es necesario respaldar esos archivos si pueden volver a instalarse de los CD-ROM de los fabricantes. Además, la mayoría de los sistemas tienen un directorio para los archivos temporales. Por lo general no hay razón para respaldarlos tampoco. En UNIX, todos los archivos especiales (dispositivos de E/S) se mantienen en un directorio /dev. No sólo es innecesario respaldar este directorio, sino que es bastante peligroso debido a que el programa de respaldo se quedaría paralizado para siempre si tratara de leer cada uno de estos archivos hasta que se completaran.
En resumen, por lo general es conveniente respaldar sólo directorios específicos y todo lo que contengan, en vez de respaldar todo el sistema de archivos.
Las densidades de las cintas no están mejorando con tanta rapidez como las densidades de los discos. Esto conlleva gradualmente a una situación en la que tal vez el respaldo de un disco muy grande requiera de varias cintas. Aunque hay robots disponibles para cambiar las cintas de manera  automática, si esta tendencia continúa, en un momento dado las cintas serán demasiado pequeñas como para utilizarlas como medio de respaldo. En ese caso, la única forma de respaldar un disco será en otro disco. Aunque utilizar el método de reflejar cada disco con un repuesto es una posibilidad, en el capítulo 5 analizaremos esquemas más sofisticados, conocidos como RAIDs.





Consistencia de sistemas de archivo
Muchos sistemas de archivos leen bloques, los modifican y los escriben posteriormente. Si el sistema falla antes de escribir todos los bloques modificados, el sistema de archivos puede quedar en un estado inconsistente. Este problema es muy crítico si algunos de los bloques que no se han escrito son bloques de nodos-i, bloques de directorios o bloques que contienen la lista de bloques libres.
Se pueden realizar dos tipos de verificaciones de consistencia: archivos y bloques. Para comprobarla consistencia de los bloques, el programa crea dos tablas, cada una de las cuales contiene un contador para cada bloque, que al principio se establece en 0. Los contadores en la primera tabla llevan el registro de cuántas veces está presente cada bloque en un archivo; los contadores en la segunda tabla registran con qué frecuencia está presente cada bloque en la lista de bloques libres (o en el mapa de bits de bloques libres).

Además de verificar que cada bloque se haya contabilizado apropiadamente, el verificador del sistema de archivos también verifica el sistema de directorios. Utiliza también una tabla de contadores, pero éstos son por archivo, no por bloque. Empieza en el directorio raíz y desciende recursivamente por el árbol, inspeccionando cada directorio en el sistema de archivos. Para cada nodo-i en cada directorio, incrementa un contador para la cuenta de uso de ese archivo.
Cuando el verificador termina, tiene una lista indexada por número de nodo-i, que indica cuántos directorios contienen cada archivo. Después compara estos números con las cuentas de vínculos almacenadas en los mismos nodos-i.
En un sistema de archivos consistentes, ambas cuentas concordarán. Sin embargo, pueden ocurrir dos tipos de errores: que la cuenta de vínculos en el nodo-i sea demasiado alta o demasiado baja.
Si la cuenta de vínculos es mayor que el número de entradas en el directorio, entonces aun si se remueven todos los archivos de los directorios, la cuenta seguirá siendo distinta de cero y el nodo-i no se removerá. No es grave, pero desperdicia espacio en el disco con archivos que no están en ningún directorio.
El otro error es potencialmente catastrófico. Si dos entradas en el directorio están vinculados a un archivo, pero el nodo-i dice que sólo hay una, cuando se elimine una de las dos entradas del directorio, la cuenta de nodos-i será cero. Cuando una cuenta de nodos-i queda en cero, el sistema de archivos la marca como no utilizada y libera todos sus bloques. Esta acción hará que uno de los directorios apunte ahora a un nodo-i sin utilizar, cuyos bloques pueden asignarse pronto a otros archivos.

Rendimiento del sistema de archivos
El acceso al disco es mucho más lento que el acceso a la memoria. Para leer una palabra de memoria de 32 bits se podrían requerir 10 nseg. La lectura de un disco duro se podría realizar a 100 MB/seg, que es cuatro veces más lenta que la de la palabra de 32 bits, pero a esto se le debe agregar de 5 a 10 mseg para realizar una búsqueda hasta la pista y después esperar a que se coloque el sector deseado bajo la cabeza de lectura.
Uso de caché
La técnica más común utilizada para reducir los accesos al disco es la caché de bloques o caché de búfer (caché se deriva del francés cacher, que significa ocultar). En este contexto, una caché es una colección de bloques que pertenecen lógicamente al disco, pero se mantienen en memoria por cuestiones de rendimiento. Un algoritmo común es verificar todas las peticiones de lectura para ver si el bloque necesario está en la caché. Si está, la petición de lectura se puede satisfacer sin necesidad de acceder al disco. Si el bloque no está en la caché, primero se lee en la caché y después se copia a donde sea necesario. Las peticiones posteriores de ese mismo bloque se pueden satisfacer desde la caché. Como hay muchos bloques (a menudo miles) en la caché, se necesita cierta forma de determinar con rapidez si cierto bloque está presente. La forma usual es codificar en hash la dirección de dispositivo y de disco, buscando el resultado en una tabla de hash. Todos los bloques con el mismo valor de hash se encadenan en una lista enlazada, de manera que se pueda seguir la cadena de colisiones.

Lectura adelantada por bloque

Una segunda técnica para mejorar el rendimiento percibido por el sistema de archivos es tratar de colocar bloques en la caché antes de que se necesiten, para incrementar la proporción de aciertos.
En especial, muchos archivos se leen en forma secuencial.
Desde luego que esta estrategia de lectura adelantada sólo funciona para los archivos que se leen en forma secuencial. Si se accede a un archivo en forma aleatoria, la lectura adelantada no ayuda. De hecho afecta, ya que ocupa ancho de banda del disco al leer bloques inútiles y eliminar bloques potencialmente útiles de la caché

Reducción del movimiento del brazo del disco.

El uso de caché y la lectura adelantada no son las únicas formas de incrementar el rendimiento del sistema de archivos. Otra técnica importante es reducir la cantidad de movimiento del brazo del disco, al colocar los bloques que tengan una buena probabilidad de utilizarse en secuencia cerca unos de otros, de preferencia en el mismo cilindro.
Una variación en el mismo tema es tomar en cuenta el posicionamiento rotacional. Al asignar bloques, el sistema intenta colocar bloques consecutivos en un archivo en el mismo cilindro.








Desfragmentación de discos
Cuando el sistema operativo se instala por primera vez, los programas y archivos que necesita se instalan en forma consecutiva, empezando al principio del disco, cada uno siguiendo directamente del anterior. Todo el espacio libre en el disco está en una sola unidad contigua que va después de los archivos instalados. Sin embargo, a medida que transcurre el tiempo se crean y eliminan archivos, generalmente el disco se fragmenta mucho, con archivos y huecos esparcidos por todas partes
El rendimiento se puede restaurar moviendo archivos para hacerlos contiguos y colocando todo el espacio libre (o al menos la mayoría) en una o más regiones contiguas en el disco. Windows tiene un programa llamado defrag, el cual realiza esto.
La desfragmentación funciona mejor en los sistemas de archivos que tienen una buena cantidad de espacio libre en una región continua al final de la partición. Este espacio permite al programa de desfragmentación seleccionar archivos fragmentados cerca del inicio de la partición, copiando todos sus bloques al espacio libre. Esta acción libera un bloque contiguo de espacio cerca del inicio de la partición en la que se pueden colocar los archivos originales u otros en forma contigua. Después, el proceso se puede repetir con el siguiente pedazo de espacio en el disco y así en lo sucesivo.
Algunos archivos no se pueden mover, incluyendo el archivo de paginación, el de hibernación y el registro por bitácora, ya que la administración requerida para ello es más problemática de lo que ayuda.


En algunos sistemas, éstas son áreas contiguas de tamaño fijo de todas formas, por lo que no se tienen que desfragmentar. La única vez cuando su falta de movilidad representa un problema es cuando se encuentran cerca del final de la partición y el usuario desea reducir su tamaño Los sistemas de archivos de Linux (en especial ext2 y ext3) por lo general sufren menos por la desfragmentación que los sistemas Windows debido a la forma en que se seleccionan los bloques de disco, por lo que raras veces se requiere una desfragmentación manual.