Sistemas operativos modernos

trucción del lenguaje de programación, así que el compilador sabe que son especiales y pue­ de manejar las llamadas a los procedimientos de monitor, de manera distinta de como mane­ ja otras llamadas a procedimientos. Por lo regular, cuando un proceso llama a un procedimiento de monitor, las primeras instrucciones de éste verifican si algún otro proceso está activo dentro del monitor. Si es así, el proceso invocador se suspenderá hasta que el otro proceso haya salido del monitor. Si ningún otro proceso lo está usando, el proceso invocador puede entrar. El compilador debe implementar la exclusión mutua en los ingresos a un monitor, pero es posible utilizar un mutex o un semáforo binario. Puesto que es ei compilador, no el progra­ mador, quien “tramita” !a exclusión mutua, es mucho menos probable que algo salga mal. En todo caso, quien escribe el monitor no tiene que saber la manera en que el compilador mane­ ja la exclusión mutua. Basta con saber que convirtiendo todas las regiones críticas en proce­ dimientos de monitor, dos procesos nunca podrán ejecutar sus regiones críticas al mismo tiempo. Aunque los monitores facilitan la exclusión mutua, como acabamos de ver, no es suficiente. También necesitamos que los procesos puedan bloquearse cuando les sea imposible continuar. En el problema del productor-consumidor no es muy difícil colocar en procedimientos de monitor todas las pruebas para determinar si el búfer está lleno o vacío, pero ¿cómo debe bloquearse el productor si se encuentra con que el búfer está lleno? La solución radica en la introducción de variables de condición, junto con dos operacio­ nes que las manipulan: wait y signal. Cuando un procedimiento de monitor descubre que no puede confinuar (por ejemplo, el productor ve que el búfer está lleno), ejecuta wait con algu­ na variable de condición, digamos lleno. Esta acción hace que el proceso invocador se blo­ quee, y también permite la entrada de otro proceso al que antes se le había impedido entrar en el monitor. Este otro proceso, que podría ser el consumidor, puede activar a su compañero inactivo eje­ cutando signal con la variable de condición que su compañero está esperando. Para evitar que haya dos procesos activos en el monitor al mismo dempo, necesitamos una regla que nos diga qué sucede después de signal. Hoare propone dejar que el proceso recién activado se ejecute, suspendiendo el otro. Brinch Hansen propuso solucionar el problema exigiendo que un proce­ so que ejecute signal salga del monitor de inmediato. Dicho de otro modo, una instrucción sig­ nal sólo puede aparecer como instrucción final en un procedimiento de monitor. Adoptaremos la propuesta de Brinch Hansen porque es más sencilla en lo conceptual y también más fácil de implementar. Si se ejecuta signal con una variable de condición que varios procesos están es­ perando, sólo uno de ellos, a elección del calendarizador del sistema, será revivido. Por cierto, existe una tercera solución que no propusieron ni Hoare ni Brinch Hansen: de­ jar que quien emite la señal se siga ejecutando y permitir que el proceso en espera comience a ejecutarse sólo después de que el emisor de la señal haya salido del monitor. Las variables de condición no son contadores; no acumulan señales para usarlas después como hacen los semáforos. Por lo tanto, si una variable de condición recibe una señal y nadie está esperando esa variable, la señal se perderá sin remedio. Dicho de otro modo, wait debe ve­ nir antes de signal. Esta regla simplifica mucho la implementación. En la práctica no hay pro­ blema porque es fácil mantenerse al tanto del estado de cada proceso con variables, si es

RkJQdWJsaXNoZXIy MjI4NDcx