2. En un sistema multiprogramado con un
único procesador, los procesos se intercalan
en el tiempo para dar la apariencia de
ejecución simultánea.
Como no se consigue un procesamiento
paralelo real y aunque se produce una
cierta sobrecarga en los intercambios de
procesos de un sitio a otro, la ejecución
intercalada produce beneficios importantes
en la eficiencia del procesamiento y en la
estructuración de los programas.
El problema principal se da por la
velocidad relativa de ejecución de los
procesos, la cual no puede predecirse y
dependen de las actividades de otros
procesos, de la forma en que el SSOO trata
las políticas de planificación.
3. Lectura / Escritura
Lectura / Escritura
Compartir recursos globales está lleno de
riesgos. ¿ Por que ?
El orden en que se ejecuten las lecturas y
escrituras, es critico. ¿ Por que ? :P
Que pasa si un Proceso A solicita uso y
obtiene control sobre un canal de E/S y se
suspende (el proceso A) antes de hacer uso
del canal?
5. Veamos el siguiente ejemplo:
void echo(){
ent=getchar();
sal=ent;
putchar(sal);
}
Cualquier programa puede llamar a este
procedimiento repetidas veces para recibir
la entrada de un usuario y mostrarla en
pantalla.
Considérese un sistema multiprogramado
con un único usuario, el cual puede pasar
de una aplicación a otra y cada aplicación
utiliza el mismo teclado para la entrada y la
misma salida por pantalla……
6. ……… Como cada aplicación utiliza el
procedimiento echo(), tiene sentido que
éste sea un procedimiento compartido que
se cargue en una parte de la memoria para
todas las aplicaciones; así se usa una copia
del procedimiento y se ahorra espacio.
Esto es útil, estamos de acuerdo, ya que
nos permite una interacción cercana y
eficiente entre los procesos. Sin embargo,
compartir puede dar lugar a problemas.
Proceso A
Proceso B
1.- Llama al procedimiento
echo y es interrumpido
inmediatamente, después de
terminar la función de
entrada. En este punto, el
último carácter leído, X,
estará almacenado en la
variable ent.
2.- Se activa el proceso B y
llama al procedimiento
echo, que se ejecuta hasta
el final y muestra un
caracter Y en la pantalla.
3.- Se reanuda el proceso A,
Ahora el valor de X ha sido
sobrescrito en la variable
ent con Y; Por lo tanto, lo
original para A se perdió.
7. ¿Que pasa si decimos ahora que solo un
proceso a la vez puede utilizar la función
echo()?
El S.O. debe ser capaz de seguir la pista a
los distintos procesos (Lo cual hace
mediante los PCB)
El S.O. debe proteger los datos y los
recursos físicos de cada proceso contra
injerencias no intencionadas de otros
procesos. Esto supone emplear técnicas
relativas a la memoria, archivos y E/S.
Los resultados de un proceso debe ser
independientes de la velocidad relativa a
la que se realiza la ejecución de otros
procesos concurrentes.
8.
9. La manera en que interactúan los procesos
se puede clasificar en función del nivel de
conocimiento que cada proceso tiene de la
existencia de los demás.
Procesos no tienen conocimiento de
los demás. Estos son llamados procesos
independientes que no están pensados
para operar juntos. Nótese que aunque los
procesos no trabajen juntos, el S.O. tiene
que encargarse de la competencia por los
recursos.
Procesos tienen conocimiento
indirecto de otros. No conocen
necesariamente a los otros por sus PID,
pero comparten el acceso de algunos
objetos, como un Buffer de E/S. Estos
procesos muestran Cooperación
indirecta.
10. Procesos tienen un conocimiento
directo de los otros. Estos son capaces
de comunicarse con los demás por el PID y
están diseñados para trabajar
conjuntamente en alguna actividad. Estos
procesos muestran , al igual que los
anteriores, cooperación.
Obviamente, las condiciones no estarán
siempre tan claramente diferenciadas.
11.
12. “Dos o más procesos necesitan acceder a
un recurso durante el curso de su
ejecución; ningún proceso es consciente de
la existencia de los otros y no se ve
afectado por su ejecución”
Por ende, cada proceso debe dejar tal y
como esté el estado de cualquier recurso
que utilice, como E/S, Memoria, CPU o
Reloj.
En el caso de que existan procesos en
competencia, se deben solucionar tres
problemas de control……
13. Esto se da cuando dos o mas procesos
quieren acceder a un único recurso no
compartible, como una impresora.
Estos recursos serán llamados, Recursos
Críticos y la parte del programa que los
accede se conoce como Sección Critica
del programa.
Recurso Crítico
Proceso A
Proceso B
Pide recurso en
00:00:12:15
Pide recurso en
00:00:12:16
14. Imaginemos que tenemos a P1 y P2 con
dos recursos R1 y R2. Ahora supongamos
que cada proceso necesita acceder a ambo
recursos para llevar a cabo una parte de su
función.
Proceso A Proceso B
R1 R2
Ambos necesitan
acceder a R1 y R2
¿Cual es el problema
aquí?!
15. Esto es cuando un proceso no puede
acceder a un recurso por un tiempo
ilimitado.
16.
17.
18. El recurso sigue existiendo después de que
un proceso lo use (recurso reutilizable) o
desaparece una vez utilizado.
Los procesos pueden compartir el uso de
un recurso o lo deben usar en modo
exclusivo o dedicado.
Hay un único ejemplar de cada recurso o
existen múltiples unidades de cada uno.
Es factible expropiar el recurso al proceso
que lo está utilizando.
19. Proceso P1
Solicita (C)
Solicita (I)
Uso de los recursos
Libera (I)
Libera (C)
Proceso P2
Solicita (I)
Solicita (C)
Uso de los recursos
Libera (C)
Libera (I)
1.- P1 : solicita (C)
2.- P2 : solicita (I)
3.- P2 : solicita (C)
4.- P1 : solicita (I)
23. G={ {N} , {A} }
N se descompone de dos subconjuntos
disjuntos que se corresponden con los
procesos P y los recursos R. Cada recurso
Ri tiene asociado un valor que representa
cuántas unidades del recurso existen.
El conjunto de aristas A se descompone de
similar manera. Las Aristas de asignación
que relacionan R con P indican que el
proceso tiene asignada una unidad de dicho
recurso. Las aristas de solicitud que
relacionan P con R indican que el proceso
está esperando la concesión de una unidad
de dicho recurso.
24. Tomando en cuenta que tenemos un sistema con 3
recursos, R1 con 2 unidades, R2 con 3 unidades y
R3 con 2 unidades. A su vez, tenemos tres procesos
que realizan la siguiente traza de peticiones:
1.- P1 : solicita (R1[2])
2.- P2 : solicita (R2[1])
3.- P2 : solicita (R1[1])
4.- P3 : solicita (R2[1])
N = { P1,P2,P3,R1(2),R2(3),R3(2) }
A = { R1P1, R1P1, R2P2, P2 R1, R2P3 }
28. Tomando en cuenta que tenemos un sistema con 3
recursos, cada uno de ellos con una sola unidad y 4
procesos que realizan las siguiente traza de
peticiones:
1.- P1 : solicita (R1[1])
2.- P2 : solicita (R2[1])
3.- P2 : solicita (R1[1])
4.- P3 : solicita (R2[1])
5.- P4 : solicita (R3[1])
6.- P1 : solicita (R2[1])
N = ???
A = ???
29. R1 R2 R3
P3
P2
P1
N = { P1,P2,P3,P4,R1(1),R2(1),R3(1) }
A = {R1P1, R2P2,P2R1,P3R2,R3P4,P1R2}
P4
30.
31. Veremos el método de Dekker, el cual tiene
la ventaja de ilustrar la mayoría de los
errores habituales que se producen en la
construcción de programas concurrentes.
Primer Intento de Dekker
/* Proceso A*/
While(turno !=0)
/*hacer nada*/
/*Sección Critica*/
Turno=1;
/* Proceso B*/
While(turno !=1)
/*hacer nada*/
/*Sección Critica*/
Turno=0;
32. Segundo Intento de Dekker
/* Proceso A*/
While(señal[1])
/*hacer nada*/
Señal[0]=true;
/*Sección Critica*/
Señal[0]=false;
/*Resto Código*/
/* Proceso B*/
While(señal[0])
/*hacer nada*/
Señal[1]=true;
/*Sección Critica*/
Señal[1]=false;
/*Resto Código*/
33. Tercer Intento de Dekker
/* Proceso A*/
Señal[0]=true;
While(señal[1])
/*hacer nada*/
/*Sección Critica*/
Señal[0]=false;
/* Proceso B*/
Señal[1]=true;
While(señal[0])
/*hacer nada*/
/*Sección Critica*/
Señal[1]=false;
34. Cuarto Intento de Dekker
/* Proceso A*/
Señal[0]=true;
While(señal[1])
/*hacer nada*/
Señal[0]=false;
/*Sección Critica*/
Señal[0]=true;
/* Proceso B*/
Señal[1]=true;
While(señal[0])
/*hacer nada*/
Señal[1]=false;
/*Sección Critica*/
Señal[1]=true;
35. Dos o mas procesos pueden cooperar por
medio de señales simples de forma que se
pueda obligar a detener un proceso en una
posición determinada hasta que reciba una
señal especifica.
Para esta señalización se usan unas
variables especificas llamadas semáforos.
Para transmitir una señal por el semáforo X
los procesos ejecutan la primitiva Signal(X).
Para recibir una señal de los procesos se
ejecuta la primitiva Wait(X)
36. Los Semáforos son variables que tienen un
valor entero sobre el que se pueden definir
las tres operaciones siguientes:
Un semáforo puede iniciarse con un valor
no negativo.
Wait disminuye el valor del semáforo. Si el
valor se hace negativo, el proceso que
ejecuta wait se bloquea.
Signal incrementa el valor del semáforo. Si
el valor no es positivo, se desbloquea un
proceso bloqueado por wait.
37. struct semaforo{
int contador;
tipoCola cola;
}
void wait(semaforo s){
s.contador--;
if(s.contador <0){
poner este proceso en s.cola;
bloquear este proceso;
}
}
void signal(semaforo s){
s.contador++;
if(s.contador <=0){
quita un proceso de s.cola;
Poner proceso P en la cola de
listos;
}
}