1. Administración de Procesos

Anuncio
Gabriel Astudillo Muñoz
Gabriel Astudillo Muñoz
1. Administración de Procesos
1.2.2. Métodos para lograr la exclusión mutua.
1.1. Comunicación entre procesos (IPC).
1.2.2.1. Alternancia estricta
•
Al existir más de un proceso “ejecutándose” (en estado Ready,
Running o Blocked), se da el problema de concurrencia de procesos.
•
Cada proceso pide recursos del sistema computacional, como por
ejemplo memoria o un archivo en especial y es deber del kernel
permitir la comunicación entre ellos para sincronizar los recursos
compartidos.
1.2. Condiciones de competencia.
•
Dos o más procesos leen o escriben en ciertas zonas compartidas.
•
El resultado final depende de lo que cada proceso ejecutó y cuándo
lo ejecutó ! existe la necesidad de eliminar estas condiciones.
•
Exclusión Mutua: concepto que garantiza que si un proceso utiliza un
recurso compartido, los demás no pueden utilizarlo.
•
Sección Crítica: Parte del programa en la que tiene acceso al
recurso compartido.
Proceso 1
While (1) {
while(turn != 0)
espera();
}
seccion_critica();
turn = 1;
seccion_nocritica();
}
While (1) {
while(turn != 1)
espera();
}
seccion_critica();
turn = 0;
seccion_nocritica();
}
Se definen los siguientes tiempos de ejecución:
o Seccion_critica() : 3 [seg] en ambos procesos.
o Seccion_nocritica(): 3[seg] en Proceso 0 y 60[seg] en Proceso 1.
• ! Para evitar que existan condiciones de competencia, se debe
evitar que dos o más procesos accedan al mismo tiempo a la
Sección Crítica.
1.2.1. Solución
•
Proceso 0
Condiciones necesarias y suficientes para obtener una buena
solución:
1. Dos procesos no deben encontrarse al mismo tiempo dentro
de sus secciones críticas.
2. No se deben hacer hipótesis sobre la velocidad o el número
de CPU.
3. Ningún proceso que esté en ejecución fuera de su sección
crítica puede bloquear a otros procesos.
4. Ningún proceso debe esperar eternamente para entrar a su
sección crítica.
1
Además, en t=1, turn=0.
Tiempo
1
2
3
4
5
6
7
8
9
10
11
12
13
...
turn
0
0
0
1
1
1
0
0
0
1
1
1
1
Estado Proceso 0
seccion_critica()
seccion_critica()
seccion_critica()
seccion_nocritica()
seccion_nocritica()
seccion_nocritica()
seccion_critica()
seccion_critica()
seccion_critica()
seccion_nocritica()
seccion_nocritica()
seccion_nocritica()
espera()
Estado Proceso 1
espera()
espera()
espera()
seccion_critica ()
seccion_critica ()
seccion_critica ()
seccion_nocritica()
seccion_nocritica()
seccion_nocritica()
seccion_nocritica()
seccion_nocritica()
seccion_nocritica()
seccion_nocritica()
Problema: El proceso 0 está bloqueado a causa del proceso 1, ya
que no ha actualizado la variable turn, ya que todavía no sale de su sección
crítica. ! esta no es una buena solución (contradice condición 3) . Además,
un mismo proceso no puede ingresar a su sección critica dos veces
seguidas. Posee espera ocupada.
2
Gabriel Astudillo Muñoz
Gabriel Astudillo Muñoz
1.2.2.2. Solución de Peterson.
Esta solución fue propuesto por Peterson en 1981. Cada proceso, antes de
utilizar las variables compartidas, llama a una función (entra_region) con su
propio número de proceso (0 ó 1 como ejemplo). Esta llamada, provoca una
espera del proceso hasta que puede entrar a la región crítica.
#define FALSE 1==2
#define TRUE 1==1
#define TOTAL_PROC 2
int turno;
int interesados[TOTAL_PROC];
void entra_region(int proceso){
int otro_proceso;
otro_proceso = 1 – proceso;
interesados[proceso] = TRUE;
turno = proceso;
while(turno == proceso &&
interesados[otro_proceso] == TRUE){
espera(); //No puedo entrar a la region critica!!
}
}
void sale_region(int proceso){
interesados[proceso] = FALSE;
}
Esta es una buena solución al problema de competencia, pero se basa en
una espera ocupada.
Suponiendo que tenemos los mismos procesos que en el ejemplo anterior,
se puede realizar la siguiente tabla temporal (Los estados de las variables turno e
interesados se dejan como inquietud):
3
Proceso 0
main{
...
entra_region(0);
seccion_critica();
sale_region(0)
seccion_nocritica();
entra_region(0);
seccion_critica();
sale_region(0)
}
Tiempo
1 (*)
2
3
4
5
6
7
8
9
10
11
...
Proceso 1
main{
...
entra_region(1);
seccion_critica();
sale_region(1)
seccion_nocritica();
entra_region(1);
seccion_critica();
sale_region(1)
}
Estado Proceso 0
entra_region(0)
espera()
espera()
seccion_critica()
seccion_critica()
seccion_critica()
sale_region(1)
seccion_nocritica()
seccion_nocritica()
seccion_nocritica()
entra_region(0)
seccion_critica()
...
Estado Proceso 1
entra_region(1)
seccion_critica()
seccion_critica()
sale_region(1)
seccion_nocritica()
seccion_nocritica()
seccion_nocritica()
seccion_nocritica()
seccion_nocritica()
seccion_nocritica()
seccion_nocritica()
seccion_nocritica()
...
Nota: En t=1, se produce una condición de competencia, ya que
ambos procesos llaman al mismo tiempo a la función
entra_region(). Esto se traduce a que ambos procesos
almacenan su número en la variable turn, pero sólo cuenta la
última operación. Se supone que el proceso que ganó fue el
proceso 1.
4
Gabriel Astudillo Muñoz
1.2.2.3. Instrucción TSL (Test and Set Lock)
•
Lee el contenido de una palabra de memoria en un registro para
después almacenar un valor distinto de cero en esa dirección
•
Las operaciones de lectura y almacenamiento de la palabra tienen la
garantía de ser indivisibles
•
Se emplea una variable compartida, flag. Ésta coordina el acceso al
recurso compartido.
•
Cuando flag==0, cualquier proceso puede darle el valor 1 mediante
la instrucción TSL y después leer o escribir en el recurso compartido.
Al terminar, el proceso vuelve a hacer flag=0.
enter_region:
tsl register,flag // copia flag al registro y hace flag=1
cmp register,#0
// ¿flag = 0?
jnz enter_region // si era distinto de cero, la cerradura
// estaba establecida por lo que hay
// que hacer un ciclo
ret
// retorno a quien hizo la llamada;
leave_region:
mov flag,#0
ret
// almacena un 0 en flag
// regresa a quien hizo la llamada
Gabriel Astudillo Muñoz
1.2.2.4. Semáforos.
• Método desarrollado por Dijkstra.
•
Un semáforo es una variable entera (positiva), cuyo valor sólo
puede ser accesado mediante las operaciones wait y signal además
de su inicialización, cuya definición es: (en algunos textos, wait =
down y signal=up)
WAIT: if (s<=0)
s--;
SIGNAL: s++;
• WAIT: verifica si el valor de un semáforo es mayor que cero y en
este caso decrementa dicho valor y el proceso continúa. Si es
cero, el proceso se va a dormir.
• SIGNAL: incrementa el valor del semáforo respectivo. Si uno o más
procesos dormían y no podían completar una operación
DOWN anterior, el SO elige alguno de ellos y se le permite
terminar la operación WAIT. ! después de un SIGNAL en
un semáforo con procesos durmiendo, dicho semáforo
seguirá con valor 0, pero habrá un menor número de
procesos durmiendo.
• Las modificaciones al valor del semáforo sólo se ejecutan en
forma indivisible, es decir, si un proceso está modificando un
semáforo ningún otro proceso puede esta modificando el
mismo valor
• Ejemplo:
/*Semáforo mutex compartido por N procesos e
inicializado en 1*/
/*Estructura del proceso Pi */
while (TRUE) {
wait(mutex);
/*Sección Critica*/
signal(mutex);
/*Sección No Crítica*/
}
5
6
Gabriel Astudillo Muñoz
1.2.3. Bloqueo Mutuo y Aplazamiento Indefinido.
•
Cuando un proceso de un sistema multiprogramado espera un
evento que nunca va a ocurrir, dicho proceso se encuentra en un
estado de bloqueo
•
En un bloqueo de sistema pueden intervenir uno o mas procesos
(bloqueo mutuo).
•
El aplazamiento indefinido (starvation, inanición) está íntimamente
relacionado con el bloque mutuo.
•
Un proceso que no esté bloqueado, puede estar esperando un
evento que, por ejemplo, dado la política de asignación de
recursos, nunca va a ocurrir.
•
Un conjunto de procesos está en deadlock cuando cada
proceso en el conjunto está esperando por un evento que solo
puede ser causado por otro proceso en el conjunto.
•
Ejemplo:
Proceso A
Proceso B
wait(s);
wait(q);
/* SC */
signal(q);
signal(s);
wait(q);
wait(s);
/* SC */
signal(s);
signal(q);
¿Dónde y cuándo se produce el bloqueo mutuo?
7
Descargar