domingo, 31 de octubre de 2010

3.3 Bloqueo Mutuo

Los sistema de las computadoras tienen muchos recursos que a su vez solo pueden ser utilizados por un proceso a la vez.

Un proceso necesita permiso exclusivo para varios recursos no a un solo recurso específico.

Los bloqueos mutuos pueden ocurrir de muchas maneras, principalmente cuando se le otorga a los procesos acceso a dispositivos E/S de uso exclusivo.

Un bloqueo mutuo también es conocido como interbloqueo es el bloqueo permanente de uno o varios procesos de ejecución donde compiten por un recurso del sistema.

Recursos

Un recurso puede ser un dispositivo de hardware o algún elemento de información. Un recurso solo puede ser usado por un proceso durante un instante cuando el recurso esté disponible.

Los recursos pueden ser de dos tipos: el primero es el expropiable y el otro es el No expropiable. El recurso expropiable es aquel que se le puede quitar al proceso poseedor el recurso que tiene en su poder sin que ocurran cambios.

Un recurso no expropiable no se le puede quitar a su poseedor actual, es decir, al proceso que lo tiene.

La secuencia de eventos que se requiere para poder usar un recurso es la siguiente:

1. Solicitar el recurso

2. Usar el recurso

3. Liberar el recurso

Si el recurso no está disponible cuando se lo solicita:

  • El proceso solicitante debe esperar.
  • En algunos SO el proceso se bloquea automáticamente y se despierta cuando dicho recurso está disponible.
  • En otros SO la solicitud falla y el proceso debe esperar para luego intentar nuevamente.

Principios del bloqueo mutuo

El bloqueo mutuo puede definirse de la siguiente manera:

Un conjunto de procesos se encuentra en bloqueo mutuo, si cada conjunto del proceso se encuentra esperando un evento que solo otro proceso del conjunto puede causar.

Condiciones para el bloqueo mutuo.
- Exclusión mutua: solo un proceso por vez puede usar el recurso.
- Retención y espera: debe existir un proceso que esté reteniendo por lo menos un recurso y esté esperando adquirir recursos adicionales que en ese momento estén siendo retenidos por otro proceso.
- No apropiación: un recurso solo puede ser liberado voluntariamente por el proceso que lo está reteniendo, una vez que dicho proceso ha completado su tarea.
- Espera circular: debe existir una cadena circular de procesos en la que cada uno mantiene a uno o más recursos que son requeridos por el siguiente proceso de la cadena.

Son cuatros las estrategias que se usan para controlar el bloqueo mutuo:

1. Hacer caso del problema

2. Detección y recuperación

3. Evitarlos dinámicamente mediante una cuidadosa asignación de recursos.

4. Prevención mediante la negación estructural de una de las cuatro condiciones necesarias.

El algoritmo del avestruz

El punto de vista más simple es pretender que no existe el problema

Esta estrategia puede generar distintas reacciones:

  • Matemáticamente es inaceptable, considerándose que los bloqueos deben evitarse a toda costa.
  • Desde la ingeniería de software podría considerarse cuál es la frecuencia esperada del problema, cuáles son sus consecuencias esperadas, cuáles son las frecuencias esperadas de fallas de otro tipo, etc.

Algunos SO soportan potencialmente bloqueos que ni siquiera se detectan, ya que se rompen automáticamente.

Los SO. que ignoran el problema de los bloqueos asumen la siguiente hipótesis:

  • La mayoría de los usuarios preferiría un bloqueo ocasional, en vez de una regla que restringiera a todos los usuarios en el uso de los distintos tipos de recursos.

El problema es que se debe pagar un cierto precio para encarar el problema del bloqueo:

  • En restricciones para los procesos.
  • En el uso de recursos.

Se presenta una contradicción entre la conveniencia y lo que es correcto.

Es muy difícil encontrar teóricamente soluciones prácticas de orden general aplicables a todos los tipos de SO.

Un criterio de orden general utilizado por los SO que no hacen tratamiento específico del bloqueo consiste en:

  • Intentar acceder al recurso compartido.
  • De no ser factible el acceso:
    • Esperar un tiempo aleatorio.
    • Reintentar nuevamente.

Detección y recuperación

En esta segunda estrategia, el sistema no realiza otra cosa que no sea vigilar las peticiones y liberar los recursos.

El SO no intenta evitar los bloqueos:

  • Intenta detectar cuando han ocurrido.
  • Acciona para recuperarse después del hecho.

La detección del bloqueo es el proceso de:

  • Determinar si de hecho existe o no un bloqueo.
  • Identificar cuáles son los procesos y recursos implicados en el bloqueo.

Los algoritmos de detección de bloqueos implican cierta sobrecarga en tiempo de ejecución.

Prevención de Bloqueos

Si se puede garantizar que al menos una de las cuatro condiciones de Coffman para el bloqueo nunca se satisface, entonces los bloqueos serán imposibles por razones estructurales.

Havender sugirió las siguientes estrategias para evitar varias de las condiciones de bloqueo:

  • Cada proceso:
    • Deberá pedir todos sus recursos requeridos de una sola vez.
    • No podrá proceder hasta que le hayan sido asignados.
  • Si a un proceso que mantiene ciertos recursos se le niega una nueva petición, este proceso deberá:
    • Liberar sus recursos originales.
    • En caso necesario, pedirlos de nuevo junto con los recursos adicionales.
  • Se impondrá la ordenación lineal de los tipos de recursos en todos los procesos:
    • Si a un proceso le han sido asignados recursos de un tipo dado, en lo sucesivo solo podrá pedir aquellos recursos de los tipos que siguen en el ordenamiento.

Havender no presenta una estrategia contra el uso exclusivo de recursos por parte de los procesos, pues se desea permitir el uso de recursos dedicados.

Prevención de la Condición de Exclusión Mutua

Si ningún recurso se asignara de manera exclusiva a un solo proceso, nunca tendríamos bloqueos, pero esto es imposible de aplicar, en especial en relación a ciertos tipos de recursos, que en un momento dado no pueden ser compartidos (ej.: impresoras).

Se debe:

  • Evitar la asignación de un recurso cuando no sea absolutamente necesario.
  • Intentar asegurarse de que los menos procesos posibles puedan pedir el recurso.

Prevención de la Condición “detenerse y esperar” o “espera por”

Si se puede evitar que los procesos que conservan recursos esperen más recursos, se pueden eliminar los bloqueos.

Una forma es exigir a todos los procesos que soliciten todos los recursos antes de iniciar su ejecución; si un proceso no puede disponer de todos los recursos, deberá esperar, pero sin retener recursos afectados.

Un problema es que muchos procesos no saben el número de recursos necesarios hasta iniciar su ejecución.

Otro problema es que puede significar desperdicio de recursos, dado que todos los recursos necesarios para un proceso están afectados al mismo desde su inicio hasta su finalización.

Otro criterio aplicable consiste en:

  • Exigir a un proceso que solicita un recurso que libere en forma temporal los demás recursos que mantiene en ese momento.
  • Hacer que el proceso intente luego recuperar todo al mismo tiempo.

Prevención de la Condición de “no apropiación”

Una de las estrategias de Havender requiere que cuando a un proceso que mantiene recursos le es negada una petición de recursos adicionales; deberá liberar sus recursos y si es necesario pedirlos de nuevo junto con los recursos adicionales.

La implementación de esta estrategia niega la condición de “no apropiación” y los recursos pueden ser retirados de los procesos que los retienen antes de la terminación de los procesos.

El problema consiste en que el retiro de ciertos recursos de un proceso puede significar:

  • La pérdida del trabajo efectuado hasta ese punto.
  • La necesidad de repetirlo luego.

Una consecuencia seria es la posible postergación indefinida de un proceso.

Prevención de la Condición de “espera circular”

Una forma es que un proceso solo está autorizado a utilizar un recurso en cada momento:

  • Si necesita otros recursos, debe liberar el primero.
  • Esto resulta inaceptable para muchos procesos.

Otra forma es la siguiente:

  • Todos los recursos se numeran globalmente.
  • Los procesos pueden solicitar los recursos en cualquier momento:
    • Las solicitudes se deben hacer según un cierto orden numérico (creciente) de recurso; debido a lo cual la gráfica de asignación de recursos no tendrá ciclos.
  • En cada instante uno de los recursos asignados tendrá el número más grande:
    • El proceso que lo posea no pedirá un recurso ya asignado.
    • El proceso terminará o solicitará recursos con números mayores , que estarán disponibles:
      • Al concluir liberará sus recursos.
      • Otro proceso tendrá el recurso con el número mayor y también podrá terminar.
      • Todos los procesos podrán terminar y no habrá bloqueo.

Una variante consiste en eliminar el requisito de adquisición de recursos en orden creciente:

  • Ningún proceso debe solicitar un recurso con número menor al que posee en el momento.

El problema es que en casos reales podría resultar imposible encontrar un orden que satisfaga a todos los procesos.

Evitar los bloqueos mutuos

En este análisis se supone implícitamente que si un proceso solicita recursos, los solicita todos al mismo tiempo:

  • En la mayoría de los sistemas los recursos se solicitan uno a la vez.
  • El SO debe poder:
    • Decidir si el otorgamiento de un recurso es seguro o no.
    • Asignarlo solo en caso de que sea seguro.

El objetivo es evitar el bloqueo haciendo la elección correcta todo el tiempo, pero para evitar los bloqueos se requiere de cierta información de antemano.

El Algoritmo del Banquero para solo un recurso

Es un algoritmo de planificación que puede evitar los bloqueos.

En la analogía:

  • Los clientes son los procesos, las unidades de crédito son los recursos del sistema y el banquero es el SO.
  • El banquero sabe que no todos los clientes necesitaran su crédito máximo otorgado en forma inmediata, por ello reserva menos unidades (recursos) de las totales necesarias para dar servicio a los clientes.

Un estado inseguro no tiene que llevar a un bloqueo.

El algoritmo del banquero consiste en:

  • Estudiar cada solicitud al ocurrir ésta.
  • Ver si su otorgamiento conduce a un estado seguro:
    • En caso positivo, se otorga la solicitud.
    • En caso negativo, se la pospone.
  • Para ver si un estado es seguro:
    • Verifica si tiene los recursos suficientes para satisfacer a otro cliente:
      • En caso afirmativo, se supone que los préstamos se pagarán.
      • Se verifica al siguiente cliente cercano al límite y así sucesivamente.
    • Si en cierto momento se vuelven a pagar todos los créditos, el estado es seguro y la solicitud original debe ser aprobada.

Trayectorias de Recursos

Los principales algoritmos para evitar los bloqueos se basan en el concepto de estados seguros

El Algoritmo del Banquero para varios recursos

Acá también los procesos deben establecer sus necesidades totales de recursos antes de su ejecución y dada una matriz de recursos asignados, el S. O. debe poder calcular en cualquier momento la matriz de recursos necesarios.

El algoritmo para determinar si un estado es seguro o no es el siguiente:

1. Se busca un renglón “R” cuyas necesidades de recursos no satisfechas sean menores o iguales que “A”:

o Si no existe tal renglón, el sistema se bloqueará en algún momento y ningún proceso podrá concluirse.

2. Supongamos que el proceso del renglón elegido solicita todos los recursos que necesita y concluye:

o Se señala el proceso como concluido y se añaden sus recursos al vector “A”.

3. Se repiten los pasos 1 y 2:

o Hasta que todos los procesos queden señalados como concluidos, en cuyo caso, el estado inicial era seguro, o

o Hasta que ocurra un bloqueo, en cuyo caso, no lo era.

3.2 Principios del Software de E/S

La idea básica es organizar el software como una serie de capas:

  • Las capas inferiores se encarguen de ocultar las peculiaridades del hardware a las capas superiores.
  • Las capas superiores deben presentar una interfaz agradable, limpia y regular a los usuarios

Objetivos del software de E/S

Un concepto clave del diseño del software de E/S se conoce como independencia del dispositivo.

  • Debe ser posible escribir programas que se puedan utilizar con archivos en distintos dispositivos, sin tener que modificar los programas para cada tipo de dispositivo.
  • El problema debe ser resuelto por el SO

El objetivo de lograr nombres uniformes está muy relacionado con el de independencia del dispositivo.

Todos los archivos y dispositivos adquieren direcciones de la misma forma, es decir mediante el nombre de su ruta de acceso.

Otro aspecto importante del software de E/S es el manejo de errores.

  • Generalmente los errores deben manejarse lo más cerca posible del hardware.
  • Solo si los niveles inferiores no pueden resolver el problema, se informa a los niveles superiores.
  • Generalmente la recuperación se puede hacer en un nivel inferior y de forma transparente.

Otro aspecto importante es si las transferencias son síncronas (por bloqueo) o asíncronas (controladas por interrupciones).

  • La mayoría de la E/S es asíncrona: la CPU inicia la transferencia y realiza otras tareas hasta una interrupción.
  • La programación es más fácil si la E/S es síncrona (por bloques): el programa se suspende automáticamente hasta que los datos estén disponibles en el buffer.

El sistema operativo se encarga de hacer que operaciones controladas por interruptores parezcan del tipo de bloques para el usuario.

También el sistema operativo debe administrar los dispositivos compartidos (ej.: discos) y los de uso exclusivo (ej.: impresoras).

Estos objetivos se pueden lograr de una forma lógica y eficiente estructurando el software de E/S en cuatro capas:

1. Manejadores de interrupciones (capa inferior)

2. Controladores de dispositivos en software

3. Software del sistema operativo independiente del software

4. software de usuario (capa superior)

Manejo de interrupciones

Las interrupciones son desagradables pero inevitables, y deben ocultarse en las profundidades del sistema operativo, con el fin de reducir al mínimo las partes del sistema que tienen conocimientos de ella.

La mejor forma de ocultarlas es hacer que cada proceso inicie un bloqueo de operación de WS hasta que la E/S se haya llevado a cabo y la interrupción ocurra.

En algunos sistemas se ejecutara un UP con un semáforo; en otros, se ejecutara un SIGNAL con una variable de condición en el monitor. En otros más, se enviara un mensaje al proceso de bloqueo.

Controladores de Dispositivos

Todo el código que depende de los dispositivos aparece en los manejadores de dispositivos.

Cada controlador posee uno o más registros de dispositivos:

  • Se utilizan para darle los comandos.
  • Los manejadores de dispositivos proveen estos comandos y verifican su ejecución adecuada.

La labor de un manejador de dispositivos es la de:

  • Aceptar las solicitudes abstractas que le hace el software independiente del dispositivo.
  • Verificar la ejecución de dichas solicitudes.

Si al recibir una solicitud el manejador está ocupado con otra solicitud, agregara la nueva solicitud a una cola de solicitudes pendientes.

La solicitud de E/S, por ej. Para un disco, se debe traducir de términos abstractos a términos concretos:

  • El manejador de disco debe:
    • Estimar el lugar donde se encuentra en realidad el bloque solicitado.
    • Verificar si el motor de la unidad funciona.
    • Verificar si el brazo está colocado en el cilindro adecuado, etc.
    • Resumiendo: debe decidir cuáles son las operaciones necesarias del controlador y su orden.
    • Envía los comandos al controlador al escribir en los registros de dispositivo del mismo.
    • Frecuentemente el manejador del dispositivo se bloquea hasta que el controlador realiza cierto trabajo; una interrupción lo libera de este bloqueo.
    • Al finalizar la operación debe verificar los errores.
    • Si todo está bien transferirá los datos al software independiente del dispositivo.
    • Regresa información de estado sobre los errores a quien lo llamó.
    • Inicia otra solicitud pendiente o queda en espera.

Software de E/S Independiente del Dispositivo

Funciones generalmente realizadas por el software independiente del dispositivo:

  • Interfaz uniforme para los manejadores de dispositivos.
  • Nombres de los dispositivos.
  • Protección del dispositivo.
  • Proporcionar un tamaño de bloque independiente del dispositivo.
  • Uso de buffers.
  • Asignación de espacio en los dispositivos por bloques.
  • Asignación y liberación de los dispositivos de uso exclusivo.
  • Informe de errores.

Las funciones básicas del software independiente del dispositivo son:

  • Efectuar las funciones de E/S comunes a todos los dispositivos.
  • Proporcionar una interfaz uniforme del software a nivel usuario.

El software independiente del dispositivo asocia los nombres simbólicos de los dispositivos con el nombre adecuado.

Un nombre de dispositivo determina de manera única el nodo-i de un archivo especial:

  • Este nodo-i contiene el número principal del dispositivo, que se utiliza para localizar el manejador apropiado.
  • El nodo-i contiene también el número secundario de dispositivo, que se transfiere como parámetro al manejador para determinar la unidad por leer o escribir.

El software independiente del dispositivo debe:

  • Ocultar a los niveles superiores los diferentes tamaños de sector de los distintos discos.
  • Proporcionar un tamaño uniforme de los bloques, por ej.: considerar varios sectores físicos como un solo bloque lógico.

Software de E/S en el Espacio del Usuario

La mayoría del software de E/S está dentro del SO

Una pequeña parte consta de bibliotecas ligadas entre sí con los programas del usuario.

La biblioteca estándar de E/S contiene varios procedimientos relacionados con E/S y todos se ejecutan como parte de los programas del usuario.

Otra categoría importante de software de E/S a nivel usuario es el sistema de spooling.

El spooling es una forma de trabajar con los dispositivos de e /s de uso exclusivo en un sistema de multiprogramación:

  • El ejemplo típico lo constituye la impresora de líneas.
  • Los proceso de usuario no abren el archivo correspondiente a la impresora.
  • Se crea un proceso especial, llamado demonio en algunos sistemas.
  • Se crea un directorio de spooling.

Para imprimir un archivo:

  • Un proceso genera todo el archivo por imprimir y lo coloca en el directorio de spooling.
  • El proceso especial, único con permiso para utilizar el archivo especial de la impresora, debe imprimir los archivos en el directorio.
  • Se evita el posible problema de tener un proceso de usuario que mantenga un recurso tomado largo tiempo.

Un esquema similar también es aplicable para la transferencia de archivos entre equipos conectados:

  • Un usuario coloca un archivo en un directorio de spooling de la red.
  • Posteriormente, el proceso especial lo toma y transmite. Un ej. son los sistemas de correo electrónico.

3.1 Principios del Hardware de E/S

El enfoque que se considerará tiene que ver con la interfaz que desde el hardware se presenta al software:

  • Comandos que acepta el hardware.
  • Funciones que realiza.
  • Errores que puede informar.

Dispositivos de E/S

Se pueden clasificar en dos grandes categorías:

  • Dispositivos de bloque.
  • Dispositivos de caracter

Las principales características de los dispositivos de bloque son:

  • La información se almacena en bloques de tamaño fijo.
  • Cada bloque tiene su propia dirección.
  • Los tamaños más comunes de los bloques van desde los 128 bytes hasta los 1.024 bytes.
  • Se puede leer o escribir en un bloque de forma independiente de los demás, en cualquier momento.
  • Un ejemplo típico de dispositivos de bloque son los discos.

Las principales características de los dispositivos de caracter son:

  • La información se transfiere como un flujo de caracteres, sin sujetarse a una estructura de bloques.
  • No se pueden utilizar direcciones.
  • No tienen una operación de búsqueda.
  • Un ejemplos típico de dispositivos de caracter son las impresoras de línea, terminales, interfaces de una red, ratones, etc.

Algunos dispositivos no se ajustan a este esquema de clasificación, por ejemplo los relojes, que no tienen direcciones por medio de bloques y no generan o aceptan flujos de caracteres.

El sistema de archivos solo trabaja con dispositivos de bloque abstractos, por lo que encarga la parte dependiente del dispositivo a un software de menor nivel, el software manejador del dispositivo.

Controladores de Dispositivos

Las unidades de E/S generalmente constan de:

  • Un componente mecánico.
  • Un componente electrónico, el controlador del dispositivo o adaptador.

Muchos controladores pueden manejar más de un dispositivo.

El S. O. generalmente trabaja con el controlador y no con el dispositivo.

Los modelos más frecuentes de comunicación entre la CPU y los controladores son:

  • Para la mayoría de las micro y mini computadoras:
    • Modelo de bus del sistema.
  • Para la mayoría de los mainframes:
    • Modelo de varios buses y computadoras especializadas en E/S llamadas canales de E/S.

La interfaz entre el controlador y el dispositivo es con frecuencia de muy bajo nivel:

  • La comunicación es mediante un flujo de bits en serie que:
    • Comienza con un preámbulo.
    • Sigue con una serie de bits (de un sector de disco, por ej.).
    • Concluye con una suma para verificación o un código corrector de errores.
  • El preámbulo:
    • Se escribe al dar formato al disco.
    • Contiene el número de cilindro y sector, el tamaño de sector y otros datos similares.

El controlador debe:

  • Convertir el flujo de bits en serie en un bloque de bytes.
  • Efectuar cualquier corrección de errores necesaria.
  • Copiar el bloque en la memoria principal.

Cada controlador posee registros que utiliza para comunicarse con la CPU:

  • Pueden ser parte del espacio normal de direcciones de la memoria: E/S mapeada a memoria.
  • Pueden utilizar un espacio de direcciones especial para la E/S, asignando a cada controlador una parte de él.

El S. O. realiza la e/s al escribir comandos en los registros de los controladores; los parámetros de los comandos también se cargan en los registros de los controladores.

Al aceptar el comando, la CPU puede dejar al controlador y dedicarse a otro trabajo.

Al terminar el comando, el controlador provoca una interrupción para permitir que el S. O.:

  • Obtenga el control de la CPU.
  • Verifique los resultados de la operación.

La CPU obtiene los resultados y el estado del dispositivo al leer uno o más bytes de información de los registros del controlador.

Acceso Directo a Memoria (DMA)

Muchos controladores, especialmente los correspondientes a dispositivos de bloque, permiten el DMA.

Si se lee el disco sin DMA:

  • El controlador lee en serie el bloque (uno o más sectores) de la unidad:
    • La lectura es bit por bit.
    • Los bits del bloque se graban en el buffer interno del controlador.
  • Se calcula la suma de verificación para corroborar que no existen errores de lectura.
  • El controlador provoca una interrupción.
  • El S. O. lee el bloque del disco por medio del buffer del controlador:
    • La lectura es por byte o palabra a la vez.
    • En cada iteración de este ciclo se lee un byte o una palabra del registro del controlador y se almacena en memoria.
  • Se desperdicia tiempo de la CPU.

DMA se ideó para liberar a la CPU de este trabajo de bajo nivel.

La CPU le proporciona al controlador:

  • La dirección del bloque en el disco.
  • La dirección en memoria adonde debe ir el bloque.
  • El número de bytes por transferir.

Luego de que el controlador leyó todo el bloque del dispositivo a su buffer y de que corroboró la suma de verificación:

  • Copia el primer byte o palabra a la memoria principal.
  • Lo hace en la dirección especificada por medio de la dirección de memoria de DMA.
  • Incrementa la dirección DMA y decrementa el contador DMA en el número de bytes que acaba de transferir.
  • Se repite este proceso hasta que el contador se anula y por lo tanto el controlador provoca una interrupción.
  • Al iniciar su ejecución el S. O. luego de la interrupción provocada, no debe copiar el bloque en la memoria, porque ya se encuentra ahí

El controlador necesita un buffer interno porque una vez iniciada una transferencia del disco:

  • Los bits siguen llegando del disco constantemente.
  • No interesa si el controlador está listo o no para recibirlos.
  • Si el controlador intentara escribir los datos en la memoria directamente:
    • Tendría que recurrir al bus del sistema para c / u de las palabras (o bytes) transferidas.
    • El bus podría estar ocupado por otro dispositivo y el controlador debería esperar.
    • Si la siguiente palabra llegara antes de que la anterior hubiera sido almacenada, el controlador la tendría que almacenar en alguna parte.

Si el bloque se guarda en un buffer interno:

  • El bus no se necesita sino hasta que el DMA comienza.
  • La transferencia DMA a la memoria ya no es un aspecto crítico del tiempo.

Los controladores simples no pueden atender la E/S simultánea:

  • Mientras transfieren a la memoria, el sector que pasa debajo de la cabeza del disco se pierde; es decir que el bloque siguiente al recién leído se pierde.
  • La lectura de una pista completa se hará en dos rotaciones completas, una para los bloques pares y otra para los impares.
  • Si el tiempo necesario para una transferencia de un bloque del controlador a la memoria por medio del bus es mayor que el tiempo necesario para leer un bloque del disco:
    • Sería necesario leer un bloque y luego saltar dos o más bloques.
    • El salto de bloques:
      • Se ejecuta para darle tiempo al controlador para la transferencia de los datos a la memoria.
      • Se llama separación.
      • Al formatear el disco, los bloques se numeran tomando en cuenta el factor de separación.
      • Esto permite al S. O.:
        • Leer los bloques con numeración consecutiva.
        • Conservar la máxima velocidad posible del hardware.