Sistemas operativos modernos
bloqueo una y otra vez (espera activa). En algún momento llegará una interrupción de reloj y se calendarizará otro proceso para ejecutarse. Tarde o temprano, el proceso que tiene el blo queo podrá ejecutarse y lo liberará. En el caso de los subprocesos la situación es diferente, porque no hay un reloj que deten ga a los que se han ejecutado durante demasiado tiempo. Por lo tanto, un subproceso que trate de adquirir un bloqueo mediante espera activa dará vueltas en forma indefinida y nunca lo ten drá porque nunca permitirá que otro subproceso se ejecute y suelte el bloqueo. Es aquí donde se encuentra la diferencia entre entrar_region y mutexjock. Cuando este úl timo fracasa en su intento por adquirir un bloqueo, invoca a thread_yield para ceder la CPU a otro subproceso. Por lo tanto, no hay espera activa. La siguiente vez que se ejecute el subpro ceso, volverá a probar el bloqueo. Puesto que thread_yield no es más que una llamada al calendarizador de subprocesos en espacio de usuario, es muy rápido. Por ello, ni mutexjock ni mutexjunlock requieren llamadas al kernel. Con estos procedimientos que sólo requieren un puñado de instrucciones, los sub procesos en el nivel de usuario pueden sincronizarse cabalmente en espacio de usuario. El sistema de mutexes que acabamos de describir no es más que un conjunto de llamadas. En todo software siempre se exigen más funciones, y las primitivas de sincronización no son la ex cepción. Por ejemplo, hay sistemas de subprocesos que ofrecen una llamada mutexjtrylock que ad quiere el bloqueo, o bien, devuelve un código de fracaso, pero no se bloquea. Esta llamada permite al subproceso decidir qué hará a continuación, si es que existen alternativas a la simple espera. Hasta aquí hemos pasado por alto un aspecto que vale la pena analizar. En un sistema de subprocesos en espacio de usuario no hay problema si varios subprocesos tienen acceso al mis mo mutex porque todos operan en el mismo espacio de direcciones. Sin embargo, en casi to das las soluciones anteriores, como en el algoritmo de Peterson y los semáforos, existe la suposición de que múltiples procesos tienen acceso a, por lo menos, cierta memoria comparti da, que podría ser una sola palabra, o más. Si los procesos tienen espacios de direcciones dis tintos por completo, como hemos dicho siempre, ¿cómo pueden compartir la variable turno en el algoritmo de Peterson, o los semáforos, o un búfer común? Hay dos respuestas. Primera, algunas de las estructuras de datos compartidas, como los se máforos, pueden almacenarse en el kemel y el acceso a ellas puede ser exclusivamente median te llamadas al sistema. Este enfoque elimina el problema. Segunda, casi todos los sistemas operativos modernos (incluidos UNIX y Windows) ofrecen un mecanismo para que los proce sos compartan una parte de su espacio de direcciones con otros procesos. De esta forma, pue den compartirse los búferes y otras estructuras de datos. En el peor de los casos, si no existe otra posibilidad, puede utilizarse un archivo compartido. Si dos o más procesos comparten la mayor parte de su espacio de direcciones, o todo, la distinción entre procesos y subprocesos se borra un poco, aunque no deja de existir. Dos pro cesos que comparten un espacio de direcciones siguen teniendo archivos abiertos, temporiza dores de alarma y otras propiedades de proceso distintas, mientras que los subprocesos de un mismo proceso los comparten. Además, cuando varios procesos comparten un mismo espacio de direcciones nunca son tan eficientes como los subprocesos en el nivel de usuario, pues el kemel participa intensamente en su administración.
RkJQdWJsaXNoZXIy MjI4NDcx