Sistemas operativos modernos
Por Otra parte, muchas veces es conveniente que el kemel mismo inhabilite las interrupcio nes durante unas cuantas instrucciones, mientras actualiza variables o listas. Por ejemplo, si ocurriera una interrupción en un momento en que la lista de procesos listos se encuentra en un estado inconsistente, podrían presentarse condiciones de competencia. La conclusión es: inha bilitar las interrupciones a menudo es una técnica útil dentro del sistema operativo mismo, pe ro no es apropiada como mecanismo general de exclusión mutua para procesos de usuario. Variables de bloqueo Como segundo intento, examinemos una solución en software. Consideremos el uso de una sola variable compartida (de bloqueo) que inicialmente es 0. Cuando un proceso quiere entrar en su región crítica, primero prueba el bloqueo. Si éste es O, el proceso lo establece a 1 y entra en la re gión crítica. Si el bloqueo ya es 1, el proceso espera hasta que cambie a 0. Por lo tanto, un Oin dica que ningún proceso está en su región crítica, y un 1 indica que algún proceso está en su región crítica. Por desgracia, esta idea contiene exactamente el mismo defecto que vimos en el directorio de spooler. Supongamos que un proceso lee el bloqueo y ve que es 0. Antes de que pueda establecerlo a 1, se calendariza otro proceso, el cual se ejecuta y establece a 1 el bloqueo. Cuan do el primer proceso vuelve a ejecutarse, también establecerá a 1 el bloqueo, y dos procesos estarán en su región crítica al mismo tiempo. Usted podría pensar que este problema puede resolverse si primero se lee el valor del blo queo y luego vuelve a verificarse, inmediatamente antes de almacenarlo, pero eso de nada sir ve. La competencia se presenta ahora si el segundo proceso modifica el bloqueo justo después de que el primero termina su segunda verificación. Alternancia estricta Un tercer enfoque para atacar el problema de la exclusión mutua se muestra en la figura 2-20. Este fragmento de programa, al igual que casi todos los que se presentan en el libro, está escri to en C. Escogimos este lenguaje porque casi todos los sistemas operativos reales están escritos en él (o a veces en C-i-f-), pero casi nunca en lenguajes como Java, Modula 3 o Pascal. C es po tente, eficiente y predecible, características cruciales para escribir sistemas operativos. Java, por ejemplo, no es predecible porque podría quedarse sin memoria en un punto crítico y tener que invocar al recolector de basura en un momento muy inoportuno. Esto no puede suceder en C porque ahí no hay recolección de basura. En Prechelt (2000) se hace una comparación cuantita tiva de C, C++, Java y otros cuatro lenguajes. En la figura 2-20 la variable entera tumo, que al principio es O, indica a quién le corres ponde entrar en la región crítíca y examinar o actualizar la memoria compartida. Al principio, el proceso Oexamina tumo, ve que es Oy, por lo tanto, entra en su región crítica. El proceso l también ve que es Oy, por lo tanto, da vueltas en un ciclo corto, probando en forma continua tumo para detectar cuando cambie a L La prueba continua de una variable hasta que adquiere algún valor se denomina espera activa, y en general debe evitarse porque desperdicia tiempo de CPU. Sólo se usa cuando es razonable suponer que la espera será corta. Un bloqueo que uti liza espera activa se denomina bloqueo giratorio.
RkJQdWJsaXNoZXIy MjI4NDcx