lunes, 26 de octubre de 2015

3.1 Política y filosofia

Filosofía
La memoria principal puede ser considerada como un arreglo lineal de localidades de almacenamiento de un byte de tamaño. Cada localidad de almacenamiento tiene asignada una dirección que la identifica.
Una de las funciones básicas que debe implementar un SO es la Administración de la Memoria para tener un control sobre los lugares donde están almacenados los datos y procesos que actualmente se están utilizando.
Sea cual sea el esquema de organización del almacenamiento que se adopte para un sistema específico es necesario decidir que estrategias se deben utilizar para obtener un rendimiento óptimo.

 Políticas
FIFO: Los procesos se despachan de acuerdo a su tiempo de llega a la cola de procesos listos, si un proceso llega al procesador sale hasta que termine. La política FIFO actualmente no se usa como el esquema principal de un sistema, pero si por ejemplo cuando se usa una política de prioridades y hay procesos con la misma prioridad, a estos se les podría aplicar FIFO. 



Round Robín: Los procesos se despachan en la forma que lo hace el FIFO, pero se les asigna una cantidad limitada de tiempo (CUANTUM) en el procesador, si no termina en ese lapso se manda al final de la lista de procesos listos.



SJF (Shortest job first - Prioridad del trabajo más corto): Se ejecuta primero el proceso en espera que tiene el menor tiempo estimado. SJF favorece a los procesos cortos, ya que los largos podrían llegar a rezagarse mucho tiempo e incluso nunca ejecutarse.



SRT (Sortest remaining time scheduling ? Tiempo restante más cortó. En SJF una vez que un proceso comienza su ejecución continúa hasta terminar. En SRT, un proceso en ejecución puede ser desposeído por uno nuevo de menor tiempo de ejecución.

HRN: (highest response ratio next ? Prioridad de la tasa de respuesta más alta): Política no apropiativa que corrige el retraso excesivo de procesos grandes que produce el SJF, para así no caer en un favoritismo excesivo por los procesos cortos, lo logra usando una formula basada en el tiempo de espera y el tiempo de servicio, con lo cual la prioridad de cada trabajo no solo está en función del tiempo de servicio sino también del tiempo que ha esperado para ser atendido. 


3. Administración de memoria

La memoria principal puede ser considerada como un arreglo lineal de localidades de almacenamiento de un byte de tamaño. Cada localidad de almacenamiento tiene asignada una dirección que la identifica.
       La memoria principal es el lugar donde el CPU lee las instrucciones a ejecutar, así como algunos datos a emplear.


domingo, 25 de octubre de 2015

2.6 Técnicas de administración del planificador

Planificación del CPU

Ciclo de ráfaga del CPU y de E/S.
El éxito de la planificación del CPU depende de la siguiente prioridad observada de los procesos: la ejecución de un proceso consiste en un ciclo de ejecución del CPU y de E/S, y los procesos se alternan entre estos dos estados. La ejecución del proceso se hace alternando una ráfaga de CPU y una ráfaga de E/S. La última ráfaga de CPU terminará con una solicitud al sistema para que concluya la ejecución.

Planificador del CPU.
Siempre que el CPU queda inactivo, el sistema operativo debe seleccionar para su ejecución uno de sus procesos de la lista de listos. La selección es revisada por el planificador a corto plazo,  Estructura de planificación.
Las decisiones de planificación del CPU pueden efectuarse cuando un proceso cambia:
  • De ejecución a bloqueado
  • De ejecución a listo  
  • De bloqueado a listo 
  • Cuando termina.

Algoritmos de planificación
Los procesos que se asignan al cpu son tomados de la lista de listos. Esta lista se alimenta de 2 puntos: 
  •  Cuando un usuario inicia la ejecución de un programa, el planificador a largo plazo recibe la orden de ejecución, crea el proceso y lo pasa al planificador a corto plazo.
  •            Cuando un proceso deja de estar en ejecución y no hay causas de bloqueo, o deja de estar bloqueado. 


Políticas de planificación:
  •            Apropiativas.- Producen un cambio de proceso con cada cambio de contexto; el proceso que usa el cpu puede ser suspendido y permitir el acceso al cpu a otro proceso. (Tiempo compartido y tiempo real) 
  •  No apropiativas.- Un proceso no abandona nunca el procesador desde su comienzo hasta su fin. (Por lotes).


Para las diferentes políticas hay diversos algoritmos (ninguno perfecto), para su estudio nos basaremos en los siguientes procesos: 

2.5 Niveles, objetivos y criterios de planificación

Niveles de planificación

  •      Planificación de largo plazo: Planificación de trabajos), determina a qué trabajos se es permite entrar al sistema, cuál es el próximo trabajo que se va a ejecutar. Existe en los sistemas por lotes donde la decisión se basa en las necesidades de recursos y su disponibilidad. En los sistemas de tiempo compartido tiene como misión cargar los programas que se desea ejecutar en memoria, es por tanto el encargado de crear los procesos.
  •             Planificación de mediano plazo.- (Planificación de Swapping), determina a qué proceso se le permite competir por el  CPU. Suspende y/o  activa temporalmente procesos para mantener una operación uniforme en el sistema y ayuda a realizar  algunas funciones para optimizar el rendimiento del sistema.
  •           Planificación de corto plazo.- (Planificación de CPU), determina a qué proceso deberá asignarse el CPU (despachar). Esta operación se realiza muchas veces por segundo, por lo que el despachador  debe estar permanente en memoria.

Objetivos de la planificación 
Justicia.-  Sin favorecer o perjudicar procesos
Máxima capacidad de ejecución.- Realizar los trabajos lo más rápido posible. Minimizar los cambios de procesos
Máximo número de usuarios interactivos.- Simultáneos
Predecibilidad.-  Saber en todo momento cómo será la ejecución.
Mínima sobrecarga.- A menor sobrecarga mayor velocidad. Minimizar los cambios de contexto
Equilibrio en el uso de recursos.- Que estén ocupados equitativamente el mayor tiempo posible
Seguridad de las prioridades.- Ejecutar más pronto los de más alta prioridad
Muchos de estos objetivos están en conflicto unos con otros, esto hace que la planificación sea un problema complejo.

Criterios de planificación.
        Tiempo de respuesta.- Velocidad con que la computadora responde a una petición, depende mucho de la velocidad de los dispositivos E/S.
        Tiempo de servicio.- Tiempo que tarda en ejecutarse un proceso, desde su carga en memoria, espera en la lista de listos, ejecución en CPU y operaciones e/s.
        Tiempo de ejecución.- Tiempo de servicio menos la espera en la lista de listos, o sea, el tiempo teórico que necesitaría el proceso para ejecutarse si fuera el único.
Tiempo de CPU.- Tiempo que un proceso usa el CPU sin contar el tiempo de bloqueado.
Tiempo de espera.- Tiempo en que el proceso está activo pero sin ser ejecutado (listas)
Eficiencia.- Que el cpu siempre esté ocupado para lograr un buen rendimiento.
Rendimiento.- Número de procesos realizados por unidad de tiempo, mientras mayor, mejor.


Medidas
t.- Tiempo que un proceso P necesita estar en ejecución para hacer su tarea. ti.- Instante en que el usuario da la orden de ejecución del proceso tf.- Instante en que el proceso termina la ejecución
Tiempo de servicio (T): T=tf-ti Tiempo de espera (E): E=T-t t=20 ti=1 tf=30 T=30-1=29 E=29-20=9
Índice de servicio.- relación para evaluar la actuación de la política establecida. Representa la relación de tiempo de ejecución y tiempo de vida
I=t/T I=20/29=0.68
Si es un solo proceso, cuando I tiende a 1 el proceso está limitado por cpu, si tiende a 0 está limitado por e/s. Si son varios procesos deben sacarse valores promedio:
Tiempo medio de servicio, de espera y eficiencia (índice medio de servicio)
Tiempo del núcleo.- Tiempo consumido por el kernel para tomar decisiones del planificador de procesos, incluido el tiempo de cambio de contexto y proceso

Tiempo de inactividad (Idle).- Tiempo consumido cuando la lista de listos está vacía. 

2.4.3 Interbloqueo (DeadLock). Análisis

En un conjunto de procesos, cada uno está esperando un evento que sólo otro proceso del conjunto puede causar. Puesto que todos los procesos están esperando, ninguno de ellos puede causar ninguno de los eventos que podrían despertar a cualquiera de los demás miembros del conjunto, y todos los procesos continúan esperando indefinidamente.

Ejemplo: Una carretera en 2 direcciones tiene un puente que sólo deja pasar vehículos en un sentido, con las siguientes situaciones:

Un auto llega al puente y en sentido contrario no hay nadie y puede cruzar
Si el paso es controlado por un semáforo en cada lado y 100 m antes de cada uno hay detectores de autos para encender el semáforo opuesto en rojo, pude pasar que 2 autos lleguen al mismo tiempo en ambos sentidos y ambos estén detenidos por el semáforo (interbloqueo)

Si no hay semáforos, un conductor cede el paso, pero antes de que termine el otro, aparece un 3º y así sucesivamente, puede hacer que el conductor educado no cruce mientras haya carros en sentido contrario (postergación indefinida)

RECURSOS.- elemento que un programa o proceso puede usar en la computadora donde se ejecuta, y puede ser usado por un solo proceso en un momento dado.

Tipos

Reutilizables.- El que puede ser usado con seguridad por un proceso y no se agota con el uso, son liberados para que otros los reusen: CPU, canales de E/S, memoria y estructuras de datos archivos, bases de datos y semáforos. 
Consumibles.- El que puede ser creado (producido) y destruido (consumido). No hay límite en la cantidad.
Un proceso productor que no está bloqueado puede liberar cualquier número de recursos consumibles.
Cuando un proceso adquiere un recurso, éste deja de existir: señales, mensajes, e información en buffers.  Operaciones
  • Solicitud
  • Uso
  • Liberación

Condiciones para que se dé un interbloqueo (deben estar todas)
1.                   Condición de exclusión mutua. Cada recurso está asignado únicamente a un solo proceso o está disponible.
2.                   Condición de retener        y esperar.             Los procesos        que
actualmente tienen             recursos que         les           fueron otorgados previamente pueden         solicitar nuevos recursos. 3. Condición de no expropiación. No               es            posible
quitarle por la fuerza a un proceso los recursos que le fueron otorgados previamente. El proceso que los tiene debe liberarlos 
4. Condición de espera circular. Debe haber una cadena circular de dos o más procesos, cada uno de los cuales está esperando un recurso retenido por el siguiente miembro de la cadena.
Además:
Número finito de recursos y procesos.

Un proceso puede pedir tantos recursos como necesite siempre que no exceda los existentes 

2.4.2.2 Mecanismos de monitoreo

Aunque los semaforos proporcionan un mecanismo adecuado y efectivo para el proceso de sin-cronizacion, un uso incorrecto de los mismos puede dar lugar a errores de temporizacion que son dificiles de detectar, dado que estos errores solo ocurren si tienen lugar algunas secuencias de eje-cucion concretas y estas secuencias no siempre se producen.

Hemos visto un ejemplo de dichos errores en el uso de contadores en la solucion del problema productor-consumidor (Seccion 6.1). En ese ejemplo, el problema de temporizacion se producia raras veces, e incluso entonces el valor del contador parecia ser razonable: lo que pasaba es que diferia en 1 del valor correcto. Pero aunque el valor pareciera correcto, no era aceptable y es por esta razon que se introdujeron los semaforos.

Lamentablemente, estos errores de temporizacion pueden producirse tambien cuando se emplean semaforos. Para ilustrar como, revisemos la solucion con semaforos para el problema de la seccion critica. Todos los procesos comparten una variable de semaforo mutex, que se iniciali-za con el valor 1. Cada proceso debe ejecutar una operacion wait (mutex) antes de entrar en la seccion critica y una operacion signal (mutex) despues de la misma. Si esta secuencia no se lleva a cabo, dos procesos podrian estar dentro de sus secciones criticas al mismo tiempo. Examinemos los problemas a los que esto da lugar. Observe que estos problemas surgiran inclu-so aunque solo sea un unico proceso el que no se comporte de la forma adecuada; dicha situacion puede deberse a un error de programacion no intencionado o a que un cierto programador no tenga muchas ganas de cooperar.

Suponga que un proceso intercambia el ordenen el que se ejecutan las operaciones wait() y signal (), dando lugar a la siguiente secuencia de ejecucion:

signal(mutex);
seccion critica
wait(mutex);
En esta situacion, varios procesos pueden estar ejecutando sus secciones criticas simultane-amente, violando el requisito de exclusion mutua. Observe que este error solo puede des-cubrirse si varios procesos estan activos simultaneamente en sus secciones criticas y que esta situacion no siempre se produce.
???? Suponga que un proceso reemplaza signal(mutex) por wait(mutex). Es decir, ejecuta
wait(mutex);

seccion critica wait(mutex);
En este caso, se producira un interbloqueo.

    Suponga que un proceso omite la operacion wait( mutex ), la operacion signal (mutex) , o ambas. En este caso, se violara la exclusion mutua o se producira un interbloqueo.
Estos ejemplos ilustran los distintos tipos de error que se pueden generar facilmente cuando los programadores emplean incorrectamente los semaforos para solucionar el problema de la seccion critica..

Para abordar tales errores, los investigadores han desarrollado estructuras de lenguaje de alto nivel. En esta seccion, vamos a describir una estructura fundamental de sincronizacion de alto nivel, el tipo monitor.

Utilización:

Un tipo, o un tipo abstracto de datos, agrupa una serie de datos privados con un conjunto de metodos publicos que se utilizan para operar sobre dichos datos. Un tipo monitor tiene un con-junto de operaciones definidas por el programador que gozan de la caracteristica de exclusion mutua dentro del monitor. El tipo monitor tambien contiene la declaracion de una serie de variables cuyos valores definen el estado de una instancia de dicho tipo, junto con los cuerpos de los procedimientos o funciones que operan sobre dichas variables. En la Figura 6.16 se muestra la sin-taxis de un monitor. La representacion de un tipo monitor no puede ser utilizada directamente por los diversos procesos. Asi, un procedimiento definido dentro de un monitor solo puede acceder a las variables declaradas localmente dentro del monitor y a sus parametros formales. De forma similar, a las variables locales de un monitor solo pueden acceder los procedimientos locales.

La estructura del monitor asegura que solo un proceso este activo cada vez dentro del monitor. En consecuencia, el programador no tiene que codificar explicitamente esta restriccion de sincronizacion. Sin embargo, la estructura de monitor, como se ha definido hasta ahora, no es lo suficientemente potente como para modelar algunos esquemas de sincronizacion. Para ello, necesitamos definir mecanismos de sincronizacion adicionales. Estos mecanismos los proporciona la estructura condition. Un programador que necesite escribir un esquema de sincronizacion a medida puede definir una o mas variables de tipo condition:

    condition x, y;
Las unicas operaciones que se pueden invocar en una variable de condicion son wait () y signal () . La operacion
x.wait();
indica que el proceso que invoca esta operacion queda suspendido hasta que otro proceso invo-que la operacion
x.signal();

La operacion x.signal() hace que se reanude exactamente uno de los procesos suspendidos. Si no habia ningun proceso suspendido, entonces la operacion signal () no tiene efecto, es decir, el estado de x sera el mismo que si la operacion nunca se hubiera ejecutado Compare esta operacion con la operacion signal () asociada con los semaforos, que siempre afectaba al estado del semaforo.

Suponga ahora que, cuando un proceso invoca la operacion x. signal(), hay un proceso en estado suspendido asociado con la condicion x. Evidentemente, si se permite al proceso sus-pendido Q reanudar su ejecucion, el proceso P que ha efectuado la senalizacion debera esperar; en caso contrario, P y Q se activarian simultaneamente dentro del monitor. Sin embargo, observe que conceptualmente ambos procesos pueden continuar con su ejecucion. Existen dos posibilidades:
1. Senalizar y esperar. P espera hasta que Q salga del monitor o espere a que se produzca otra condicion.
2. Senalizar y continuar. Q espera hasta que P salga del monitor o espere a que se produzca otra condicion.
Hay argumentos razonables en favor de adoptar cualquiera de estas opciones. Por un lado, puesto que P ya estaba ejecutandose en el monitor, el metodo de senalizar y continuar parece el mas razonable. Por otro lado, si permitimos que la hebra P continue, para cuando se reanude la ejecu-cion de Q, es posible que ya no se cumpla la condicion logica por la que Q estaba esperando. En el lenguaje Pascal Concurrente se adopto un compromiso entre estas dos opciones: cuando la hebra P ejecuta la operacion signal, sale inmediatamente del monitor. Por tanto, la ejecucion de Q se reanuda de forma inmediata.

monitor nombre del monitor {
// declaraciones de variables compartidas procedimiento P1 ( . . . )?????????????????????????????????????????????????????????? {

}
procedimiento P2 (??????????????? . . )???????? {

}
procedimiento Pn ( .????????????????????? )????? {

}
codigo de inicializacion ( .???? )?????????? {
}

}

2.4.2.1 Mecanismo de semáforo

Las diversas soluciones hardware al problema de la seccion critica, basadas en las instrucciones TestAndSet () y Swap (), son complicadas de utilizar por los programadores de aplicaciones. Para superar esta dificultad, podemos usar una herramienta de sincronizacion denominada semaforo.
Un semaforo S es una variable entera a la que, dejando aparte la inicializacion, solo se accede mediante dos operaciones atomicas estandar: wait () y signal (). Originalmente, la operacion wait () se denominaba P (del termino holandes proberen, probar); mientras que signal( ) denominaba originalmente V (verhogen, incrementar). La definicion de wait () es la que sigue:

wait (S) {
while S <= 0
;??? // no-op
S--;
}
La definicion de signal () es:
signal(S) {
S++;
}

Todas las modificaciones del valor entero del semaforo en las operaciones wait () y signal () deben ejecutarse de forma indivisible. Es decir, cuando un proceso modifica el valor del semaforo, ningun otro proceso puede modificar simultaneamente el valor de dicho semaforo. Ademas, en el caso de wait(), la prueba del valor entero de S (S <- 0), y su posible modificacion (S - -) tambien se deben ejecutar sin interrupcion.

Utilizacion

Los sistemas operativos diferencian a menudo entre semaforos contadores y semaforos binarios. El valor de un semaforo contador puede variar en un dominio no restringido, mientras que el valor de un semaforo binario solo puede ser 0 01. En algunos sistemas, los semaforos binarios se conocen como cerrojos mutex, ya que son cerrojos que proporcionan exclusion mutua.
Podemos usar semaforos binarios para abordar el problema de la seccion critica en el caso de multiples procesos. Los n procesos comparten un semaforo, mutex, inicializado con el valor 1. Cada proceso P; se organiza como se muestra en la Figura 6.9.
Los semaforos contadores se pueden usar para controlar el acceso a un determinado recurso formado por un numero finito de instancias. El semaforo se inicializa con el numero de recursos disponibles. Cada proceso que desee usar un recurso ejecuta una operacion wait () en el semaforo (decrementando la cuenta). Cuando un proceso libera un recurso, ejecuta una operacion signal()(incrementando la cuenta). Cuando la cuenta del semaforo llega a 0, todos los recursos estaran en uso. Despues, los procesos que deseen usar un recurso se bloquearan hasta que la cuenta sea mayor que 0.
Tambien podemos usar los semaforos para resolver diversos problemas de sincronizacion. Por ejemplo, considere dos procesos que se esten ejecutando de forma concurrente: P1 con una instruccion S1 y P2 con una instruccion S2. Suponga que necesitamos que S2 se ejecute solo despues de que Sl se haya completado. Podemos implementar este esquema dejando que P1 Y P2 compartan un semaforo comun synch, inicializado con el valor 0, e insertando las instrucciones:

s1;
signal(synch);
en el proceso P1, y las instrucciones
wait(synch); S2;
en el proceso P2. Dado que synch se inicializa con el valor 0, P2 ejecutara S2 solo despues de que P1 haya invocado signal ( synch), instruccion que sigue a la ejecucion de S1.

do
waiting(mutex);

???????????? // seccion critica
signal(mutex);

??????????? // seccion restante
}while (TRUE);

??? Implementacion
La principal desventaja de la definicion de semaforo dada aqui es que requiere una espera activa. Mientras un proceso esta en su seccion critica, cualquier otro proceso que intente entrar en su seccion critica debe ejecutar continuamente un bucle en el codigo de entrada. Este bucle continuo plantea claramente un problema en un sistema real de multiprogramacion, donde una sola CPU se comparte entre muchos procesos.

La espera activa desperdicia ciclos de CPU que algunos otros procesos podrian usar de forma productiva. Este tipo de semaforo tambien se denomina cerrojo mediante bucle sin fin (spinlock), ya que el proceso "permanece en un bucle sin fin" en espera de adquirir el cerrojo. (Los cerrojos mediante bucle sin fin tienen una ventaja y es que no requieren ningun cambio de contexto cuando un proceso tiene que esperar para adquirir un cerrojo.

Los cambios de contexto pueden llevar un tiempo considerable. Por tanto, cuando se espera que lo-s cerrojos se mantengan durante un periodo de tiempo corto, los cerrojos mediante bucle sin fin pueden resultar utiles; por eso se emplean a menudo en los sistemas multiprocesador, donde una hebra puede "ejecutar un bucle" sobre un procesador mientras otra hebra ejecuta su seccion critica en otro procesador).
Para salvar la necesidad de la espera activa, podemos modificar la definicion de las operaciones de semaforo wa i t () y s i gna 1(). Cuando un proceso ejecuta la operacion wa i t () y determina que el valor del semaforo no es positivo, tiene que esperar. Sin embargo, en lugar de entrar en una espera activa, el proceso puede bloquearse a si mismo. La operacion de bloqueo coloca al proceso en una cola de espera asociada con el semaforo y el estado del proceso pasa al estado de espera. A continuacion, el control se transfiere al planificador de la CPU, que selecciona otro proceso para su ejecucion.
Un proceso bloqueado, que esta esperando en un semaforo S, debe reiniciarse cuando algun otro proceso ejecuta una operacion signal (). El proceso se reinicia mediante una operacion wakeup () , que cambia al proceso del estado de espera al estado de preparado. El proceso se coloca en la cola de procesos preparados. (La CPU puede o no conmutar del proceso en ejecucion al proceso que se acaba de pasar al estado de preparado, dependiendo del algoritmo de planifigacion de la CPU.)
Para implementar semaforos usando esta definicion, definimos un semaforo como una estructura "C":

typedef struct {
int value;
struct process *list;
}semaphore;

Cada semaforo tiene un valor (value) entero y una lista de procesos list. Cuando un proce
so tiene que esperar en un semaforo, se anade a la lista de procesos. Una operacion signa1 () elimina un proceso de la lista de procesos en espera y lo despierta.
La operacion de semaforo wait () ahora se puede definir del siguiente modo:

wait(semaphore *S) {
S->value--;
if (S->value < 0) {
anadir este proceso a S->list;
block();
}
}

    La operacion de semaforo signal () ahora puede definirse asi:

signal(semaphore *S) {
S->value++;}
if (S->value <= 0) {
eliminar un proceso P de S->list;
wakeup(P);
}
}

La operacion block () suspende al proceso que la ha invocado. La operacion wakeup () reanuda la ejecucion de un proceso bloqueado P. Estas dos operaciones las proporciona el sistema operativo como llamadas al sistema basicas.
Observe que, aunque bajo la definicion clasica de semaforos con espera activa, el valor del semaforo nunca es negativo, esta implementacion si que puede tener valores negativos de semaforo. Si el valor del semaforo es negativo, su modulo es el numero de procesos en espera en dicho semaforo. Este hecho resulta de conmutar el orden de las operaciones de decremento y de prueba en la implementacion de la operacion wait ().
 La lista de procesos en espera puede implementarse facilmente mediante un campo de enlace en cada bloque de control de proceso (PCB). Cada semaforo contiene un valor entero y un puntero a la lista de bloques PCB. Una forma de anadir y eliminar procesos de la lista de manera que se garantice un tiempo de espera limitado consiste en usar una cola FIFO, donde el semaforo contenga punteros a ambos extremos de la cola. Sin embargo, en general, la lista puede utilizar cualquier estrategia de gestion de la cola. El uso correcto de los semaforos no depende de la estrategia concreta de gestion de la cola que se emplee para las listas de los semaforos.
 El aspecto critico de los semaforos es que se deben ejecutar atomicamente: tenemos que garantizar que dos procesos no puedan ejecutar al mismo tiempo sendas operaciones waitO y signal () sobre el mismo semaforo. Se trata de un problema de seccion critica. En un entorno de un solo procesador (es decir, en el que solo exista una CPU), podemos solucionar el problema de forma sencilla inhibiendo las interrupciones durante el tiempo en que se ejecutan las operaciones wait () y signal (). Este esquema funciona adecuadamente en un entorno de un solo procesador porque, una vez que se inhiben las interrupciones, las instrucciones de los diferentes procesos no pueden intercalarse: solo se ejecuta el proceso actual hasta que se reactivan las interrupciones y el planificador puede tomar de nuevo el control.
En un entorno multiprocesador, hay que deshabilitar las interrupciones en cada procesador; si no se hace asi, las instrucciones de los diferentes procesos (que esten ejecutandose sobre diferentes procesadores) pueden intercalarse de forma arbitraria. Deshabilitar las interrupciones en todos los procesadores puede ser una tarea compleja y, ademas, puede disminuir seriamente el rendimiento. Por tanto, los sistemas SMP deben proporcionar tecnicas alternativas de bloqueo, como por ejemplo cerrojos mediante bucle sin fin, para asegurar que las operaciones wait () y signa l () se ejecuten atomicamente.
 Es importante recalcar que no hemos eliminado por completo la espera activa con esta definicion de las operaciones wait () y signal (); en lugar de ello, hemos eliminado la espera activa de la seccion de entrada y la hemos llevado a las secciones criticas de los programas de aplicacion. Ademas, hemos limitado la espera activa a las secciones criticas de las operaciones wait() y signal (), y estas secciones son cortas (si se codifican apropiadamente, no deberian tener mas de unas diez instrucciones). Por tanto, la seccion critica casi nunca esta ocupada y raras veces se produce este tipo de espera; y, si se produce, solo dura un tiempo corto. En los programas de aplicacion, la situacion es completamente diferente, porque sus secciones criticas pueden ser largas (minutos o incluso horas) o pueden estar casi siempre ocupadas. En tales casos, la espera activa resulta extremadamente ineficiente.

Interbloqueos e inanicion

La implementacion de un semaforo con una cola de espera puede dar lugar a una situacion en la que dos o mas procesos esten esperando indefinidamente a que se produzca un suceso que solo puede producirse como consecuencia de las operaciones efectuadas por otro de los procesos en espera. El suceso en cuestion es la ejecucion de una operacion signal (). Cuando se llega a un estado asi, se dice que estos procesos se han interbloqueado.
Para ilustrar el concepto, consideremos un sistema que consta de dos procesos, Po y Pl, con acceso cada uno de ellos a dos semaforos, S y Q, configurados con el valor 1:

Po ??????????????????     Pi
wait (S)?????????? ?wait (Q);
wait (Q)??????????  wait (S);
signal (S)??????  signal (Q);
signal (Q)??????  signal (S);

Suponga que Po ejecuta wait(S) y luego P1 ejecuta wait(Q). Cuando Po ejecuta wait(Q), debe esperar hasta que P1 ejecute signal (Q). De forma similar, cuando P1 ejecuta wait (S), tiene que esperar hasta que Po ejecute signal(S). Dado que estas operaciones signal() no pueden ejecutarse, Po y Pl se interbloquean.
Decimos que un conjunto de procesos esta en un estado de interbloqueo cuando todos los procesos del conjunto estan esperando un suceso que solo puede producirse como consecuencia de las acciones de otro proceso del conjunto. Los sucesos que mas nos interesan aqui son los de adquisicion y liberacion de recursos, pero tambien hay otros tipos de sucesos que pueden dar lugar a interbloqueos, como veremos en el Capitulo 7. En ese capitulo describiremos varios mecanismos para tratar los problemas de interbloqueo.


Otro problema relacionado con los interbloqueos es el del bloqueo indefinido o muerte por inanicion, una situacion en la que algunos procesos esperan de forma indefinida dentro del semaforo. El bloqueo indefinido puede producirse si anadimos y eliminamos los procesos a la lista asociada con el semaforo utilizando un esquema LIFO (last-in, first-out).

2.4.2 Sincronización de procesos

En muchos casos, los procesos se reúnen para realizar tareas en conjunto, a este tipo de relación se le llama procesos cooperativos. Para lograr la comunicación, los procesos deben sincronizarse, de no ser así pueden ocurrir problemas no deseados. La sincronizacion es la transmisión y recepción de señales que tiene por objeto llevar a cabo el trabajo de un grupo de procesos cooperativos.
Es la coordinación y cooperación de un conjunto de procesos para asegurar la comparación de recursos de computo. La sincronizacion entre procesos es necesaria para prevenir y/o corregir errores de sincronizacion debidos al acceso concurrente a recursos compartidos, tales como estructuras de datos o dispositivos de E/S, de procesos contendientes. La sincronizacion entre procesos también permite intercambiar señales de tiempo (ARRANQUE/PARADA) entre procesos cooperantes para garantizar las relaciones especificas de precedencia impuestas por el problema que se resuelve.
Sin una sincronizacion adecuada entre procesos, la actualización de variables compartidas puede inducir a errores de tiempo relacionados con la concurrencia que son con frecuencia difíciles de depurar. Una de las causas principales de este problema es que procesos concurrentes puedan observar valores temporalmente inconsistentes de una variable compartida mientras se actualizan. una aproximacion para resolver este problema es realizar actualizaciones de variables compartidas de manera mutuamente exclusiva. Se pueden mejorar permitiendo que a lo mas un proceso entre a la vez en la seccion critica de codigo en la que se actualiza una variable compartida o estructura de datos en particular.
Para que los procesos puedan sincronizarse es necesario disponer de servicios que permitan bloquear o suspender bajo determinadas circunstancias la ejecución de un proceso. Los principales mecanismos de sincronizacion que ofrecen los sistemas operativos son:
  • Señales
  • Tuberías
  • Semáforos
  • Mutex y variables condicionales
  • Paso de mensajes

2.4.1 Exclusión mutua de secciones criticas

Regiones críticas 

Parte de un programa, en la cual se intenta el acceso a recursos compartidos
Tipos de procesos

  Los procesos no conocen a los demás, son independientes, no trabajan juntos.
  Los procesos conocen indirectamente  a otros: no los conocen necesariamente, pero comparten algunos recursos.
  Los procesos conocen a otros: se comunican y trabajan conjuntamente en una misma actividad. 

Competencia de procesos por los recursos

Hay conflicto cuando los procesos compiten por el mismo recurso al mismo tiempo y el sistema operativo asignará el recurso a uno y el resto tendrá que esperar, el que quede esperando se retrasará, se bloqueará y en el peor de los casos nunca terminará bien
Ejemplo: Un Sistema Operativo debe asignar un identificador de proceso (PID) a dos procesos en un sistema multiprocesador. Si se realiza esta acción en dos procesadores a la vez sin control,  se puede asignar el mismo PID a dos procesos distintos. Este problema se debe a que la asignación de PID es una sección crítica que debe ejecutarse en forma atómica, de forma completa e indivisible y ningún otro proceso podrá ejecutar dicho código mientras el primero no haya acabado su sección. 
Debe haber sincronización que permita a los procesos cooperar entre ellos sin problemas protegiendo el código de la región crítica:

  Cada proceso debe solicitar permiso para entrar en la sección crítica mediante código. 
  Cuando un proceso sale de la sección crítica debe indicarlo mediante código. Esto permitirá que otros procesos entren a ejecutar la sección crítica.
Requisitos:
  Exclusión mutua: Si un proceso está ejecutando código de la sección crítica, ningún otro proceso lo podrá hacer. 
  Progreso: Si ningún proceso está ejecutando dentro de la sección crítica, se elegirá alguno de los que desean entrar. 
  Espera acotada: Debe haber un límite en el número de veces que se permite que los demás procesos entren a ejecutar código de la sección crítica después de que un proceso haya efectuado una solicitud de entrada y antes de que se conceda la suya.

Exclusión mutua  

Operación de control que permite la coordinación de procesos concurrentes, prohibiendo a otros procesos realizar una acción cuando un proceso haya obtenido el permiso.
Involucra al sistema operativo (quien asigna recursos), y a procesos, que deben  expresar los requisitos de exclusión mutua, como puede ser bloqueando los recursos antes de usarlos.

Problemas:
                     Interbloqueo. Se tienen dos procesos 1 y 2 y dos recursos críticos, R1 y R2. Cada proceso necesita acceder a ambos recursos para llevar a cabo una parte de su función, es posible que: el sistema operativo asigna R1 a 1 y R2 a 2. Cada proceso está esperando uno de los dos recursos. Ninguno liberará el recurso que ya tiene hasta que adquiera el otro y ejecute su sección crítica. Ambos procesos están interbloqueados.
                     Inanición. Tres procesos, 1, 2 y 3, necesitan acceder periódicamente al recurso R. 1 tiene el recurso, 2 y 3 espera. Cuando 1 deja su sección crítica, 2 y 3 pueden acceder a R. Se concede acceso a 3 y antes que termine su sección crítica, 1 solicita acceso de nuevo. Se concede el acceso a 1 después de que 3 termine y si 1 y 3 se conceden el acceso repetidamente el uno al otro, se puede negar indefinidamente a 2 el acceso. 

Requisitos para la exclusión mutua.
1.  Solo un proceso, de los que tienen regiones críticas por el mismo recurso, debe tener permiso para entrar en ella en un instante dado. 
2.  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.
3.  Cuando ningún proceso está en su sección crítica, cualquier proceso que solicite entrar en la suya debe poder hacerlo sin dilación. 
4.  Un proceso permanece en su sección crítica solo por un tiempo finito.
 

2 situaciones:

Sin sincronización.- Puede ser que Escribir esté actualizando un registro y sin terminar le sorprenda el cambio de proceso, terminará
en el siguiente turno de CPU. Con el cambio le tocará turno a Leer, que leerá el registro obteniendo datos inconsistentes

Con sincronización.- Mediante un mecanismo que impida la lectura de un registro (bloqueo) a un proceso mientras Escribir realice operaciones. Leer al usar el CPU y solicitar lectura sobre el registro lo encontrará bloqueado y quedará en espera de que Escribir termine para hacer su lectura 

2.4 Concurrencia y secuencialidad

La concurrencia comprende un gran número de cuestiones de diseño, incluyendo la comunicación entre procesos, competencia por los recursos, sincronización de la ejecución de varios procesos y asignación del tiempo de procesador a los procesos y es fundamental para que existan diseños como Multiprogramación,
Multiproceso y Proceso distribuido 
Los procesos son concurrentes si existen simultáneamente 2 o más y llegan al mismo tiempo a ejecutarse.

La concurrencia puede presentarse en tres contextos diferentes: 

  Varias aplicaciones: (multiprogramación) para permitir que el cpu sea compartido entre varios trabajos • Aplicaciones estructuradas: Como ampliación del diseño modular y la programación estructurada, algunas aplicaciones pueden implementarse eficazmente como un conjunto de procesos concurrentes. 
  Estructura del sistema operativo: Las mismas ventajas de estructuración son aplicables a los sistemas operativos que están implementados como un conjunto de procesos. 

Tipos de computadora en los que puede haber concurrencia: 

  Multiprogramación con un CPU. El sistema operativo se encarga de repartir el CPU entre los procesos, intercalando su ejecución  para dar una apariencia de ejecución simultánea. 
  Multiprocesador. Máquina formada por más de un CPU que comparten memoria principal. Los procesos no sólo intercalan su ejecución sino también la superponer.
  Multicomputadora. Es una máquina de memoria distribuida formada por una serie de computadoras, es posible la ejecución simultánea de los procesos en los diferentes CPU’s.
La concurrencia será aparente siempre que el número de procesos sea mayor que el de procesadores disponibles y será real cuando haya un proceso por procesador (Paralelismo). 

Pros: 
  Facilita la programación de aplicaciones: permite que se estructuren como un conjunto de procesos que cooperan entre sí para alcanzar un objetivo común.  •Acelera los cálculos: Dividiendo una tarea en varios procesos, ejecutándolos en “paralelo”. 
  Posibilita            el             uso         interactivo            a             múltiples               usuarios                que         trabajan                de              forma    simultánea. • Permite un mejor aprovechamiento de los recursos, en especial del CPU, ya que pueden aprovechar las fases de entrada-salida de unos procesos para realizar las fases de procesamiento de otros. 

Contras: 
  Inanición e interrupción de procesos
  Ocurrencia de bloqueos
  Que 2 o más procesos requieran el mismo recurso 

Tipos de procesos concurrentes:

Proceso independiente: El que se ejecuta sin cooperación de otros. Ejemplo: varias ventanas de una misma aplicación de forma simultánea.
Procesos cooperantes: Los que están diseñados para trabajar conjuntamente, deben  comunicarse e interactuar. (Aplicaciones en red) Tipos de interacción: 
  Motivada porque los procesos comparten o compiten por el acceso a recursos. Ejemplo: dos procesos independientes compiten por el acceso a disco o para modificar una base de datos.  • Motivada porque los procesos se comunican y sincronizan entre sí para alcanzar un objetivo común. Ejemplo: compilador con varios procesos que trabajan conjuntamente para obtener un solo archivo de salida. 

Aspectos de un sistema operativo para  gestionar la concurrencia.
1.        Debe                             seguir     la            pista       de           los           distintos                procesos                activos, por          medio        de           PBC’s
2.        Debe asignar y quitar recursos a cada proceso activo: 
  Tiempo de procesador. 
  Memoria: (virtual, swapping) • Archivos
  E/S: 
3. Debe proteger datos y recursos de cada proceso contra injerencias no intencionadas de otros procesos.