Sistemas operativos modernos
Esto almacena el valor de un apuntador en la posición de almacenamiento creada antes por la llamada a crear_global. Para leer una variable global, la llamada podría ser apuntbuf = leer_global("apuntbur): Esto devuelve la dirección almacenada en la variable global, para tener acceso a sus datos. El siguiente problema que enfrentamos al convertir un programa de un solo subproceso en uno de múltiples subprocesos es que muchos procedimientos de biblioteca no son reentrantes; es decir, su diseño no permite efectuar una segunda llamada a cualquier procedimiento dado antes de que termine una llamada anterior. Por ejemplo, el envío de un mensaje por una red bien podría programarse de modo que dicho mensaje se arme en un búfer fijo dentro de la bi blioteca y luego se salte al kernel para enviarlo. ¿Qué sucede si un subproceso ya armó su men saje en el búfer y luego una interrupción de reloj cambia a un segundo subproceso, que sobrescribe de inmediato su propio mensaje en el búfer? De forma similar, los procedimientos de asignación de memoria, como malloc en UNIX, mantienen tablas cruciales acerca del uso de la memoria; por ejemplo, una lista enlazada de las partes de la memoria que están disponibles. Mientras malloc está ocupado actualizando es tas listas, podrían estar de manera temporal en un estado inconsistente, con apuntadores que no apuntan a ningún lado. Si se efectúa una conmutación de subproceso mientras las tablas es tán inconsistentes y llega una llamada nueva de un subproceso distinto, podría utilizarse un apuntador no válido, lo cual haría que el programa se congelara. Para corregir en forma debi da todos estos problemas, sería preciso rescribir toda la biblioteca. Una solución distinta sería proporcionar a cada subproceso una funda que establezca un bit para indicar que la biblioteca se está usando. Esto bloqueará cualquier intento de otro subproceso de usar un procedimiento de biblioteca antes de que una llamada anterior haya terminado. Aunque es posible hacer que este enfoque funcione, elimina en buena parte el paralelismo potencial. Ahora consideremos las señales. Algunas son lógicamente específicas para un subproceso, pero otras no. Por ejemplo, si un subproceso invoca a alarm, tiene sentido que la señal produci da se envíe al subproceso que emitió la llamada. Sin embargo, cuando los subprocesos se imple mentan por completo en espacio de usuario, el kemel ni siquiera sabe que existen subprocesos y difícilmente podrá enviar la señal al subproceso correcto. Existe una complicación adicional si un proceso sólo puede tener una alarma pendiente a la vez y varios subprocesos invocan a alarm de manera independiente. Otras señales, como una interrupción de teclado, no son específicas para un subproceso. ¿Quién deberá atraparlas? ¿Un subproceso designado? ¿Todos los subprocesos? ¿Uno emergen te recién creado? Además, ¿qué sucede si un subproceso modifica los manejadores de señales sin avisar a los demás subprocesos? ¿Y qué sucede si un subproceso quiere atrapar una señal específica (por ejemplo, la que se produce cuando el usuario oprime CTRL+C) y otro quiere que esta señal termine el proceso? Esta situación puede presentarse si uno o más subprocesos ejecutan procedimientos de bibliotecas estándar y otros son escritos por los usuarios. Es obvio que sus deseos son incompatibles. En general, las señales ya son de por sí difíciles de manejar en un entorno de un solo subproceso. El cambio a un entorno de múltiples subprocesos de nin guna manera facilita las cosas.
RkJQdWJsaXNoZXIy MjI4NDcx