Sunteți pe pagina 1din 3

Variable de cerradura(CERROJO)

Analicemos una solución mediante software. Consiste en tener una variable de


cerradura compartida por los procesos. Antes de que un proceso entre en su sección
crítica comprueba el valor de la cerradura. Si ésta vale 0, el proceso cambia el
valor a 1 y entra en la sección crítica. Si ésta ya vale 1, el proceso espera hasta que
la variable valga 0. Por lo tanto, un 0 indica que ningún proceso se encuentra en
una sección crítica y un 1 indica que algún proceso está en una sección crítica. A
continuación se presenta el fragmento del código (en lenguaje C) de un proceso
que quiere entrar en una sección crítica. A las instrucciones, relativas a
proporcionar la exclusión mutua, que se ejecutan antes de entrar en la sección
crítica, se les llama protocolo de entrada; a las que se ejecutan después de
ejecutar el código de la sección crítica se les llama protocolo de salida. En este
caso el protocolo de entrada lo constituyen la conjunción de las
instrucciones while y ‘cerrado = 1'. El protocolo de salida lo conforma la
instrucción ‘cerrado = 0'.

Esta solución no funciona. Suponga que un proceso lee la cerradura y comprueba


que tiene un valor 0. Antes de que pueda ponerla a 1 se planifica otro proceso. Éste
comprueba el valor de cerrado, al ser 0 entra en su sección crítica. Si antes de que
este proceso termine la sección crítica se vuelve a planificar al primer proceso no
se habrá logrado la exclusión mutua. El problema proviene de que el protocolo de
entrada es una sección crítica más, pues se dedica a modificar una variable
compartida (la variable cerrado). Obsérvese que si el protocolo de entrada se
pudiera ejecutar sin cambios de proceso la solución sería efectiva.
Ejemplo de implementación
El siguiente código sería un posible ejemplo del uso de control de concurrencia mediante cerrojos:

int cerrojo = 0; /* Inicializamos la variable cerrojo. Esto sería sólo válido para
hilos, ya que los procesos no comparten espacio de memoria. La
variable se inicializa FUERA de los hilos.
Del while en adelante, ya es código perteneciente a los hilos
en ejecución. */

while(cerrojo == 1); // Protocolo de


cerrojo = 1; // entrada

... // Sección crítica

cerrojo = 0; // Protocolo de salida

Sin embargo, esto es problemático: Supongamos que tenemos únicamente un proceso con dos
hilos (Hx y Hy) y el planificador retira el hilo Hx justo antes de ejecutarse la instrucción cerrojo =
1;. El hilo Hy ejecuta su código, entra en la sección crítica (Esto puede ocurrir ya que cerrojo
sigue a 0) y el planificador le retira el uso del procesador dentro de ésta. A continuación, se le
vuelve a asignar el procesador a Hx.
De esta forma, tenemos a dos hilos ejecutando código de la sección crítica. Para evitar este
problema, debemos implementar los protocolos de entrada y salida de forma que se ejecuten en
una sola instrucción, con lo cual o el planificador retira el uso del procesador antes de esta
instrucción, o sino lo retira después de haberla ejecutado.
Este algoritmo utiliza un flag.

Al entrar a la sección crítica se fija si es uno o cero si es cero lo pone en uno y entra a
la sección crítica; si es uno espera hasta que valga cero. Antes de salir de la sección
crítica iguala el flag a cero.

Repeat
If (flag = 0) then {
Flag:=1
Seccion crítica
Flag:=0
Seccion no crítica}
Until 0 = 1

Este algoritmo si embargo no resuelve el problema de la sección crítica


porque si hubiera una interrupción justo después de comprobar el estado del flag y se
accediera a la memoria compartida antes de cambiar el flag, otro proceso podría
acceder a la memoria compartida, cambiar el flag a uno y habrían dos procesos
accesando la memoria compartida.

S-ar putea să vă placă și