Soluciones del examen de diciembre, año 2000
Pregunta 1. Cuestiones breves.
Las respuestas las pueden hallar en cualquier libro de Sistemas Operativos, excepto estas cuestiones:
d) Suponga que, para el sistema operativo de su ordenador personal, debe usted renunciar a todos estos servicios, excepto uno: multiprogramación; memoria virtual; protección de memoria; capacidad de multiusuario. ¿Con cuál se quedaría y por qué?
Esta es una pregunta en la que interviene la opinión personal y se trata de aportar argumentaciones consistentes a la respuestas escogida. En cualquier caso, se pueden hacer algunas afirmaciones generales: la capacidad de multiusuario no parece ser un aspecto esencial en un ordenador personal; la protección de memoria sólo se vuelve realmente esencial cuando tenemos multiprogramación; la memoria virtual, sin multiprogramación puede ser útil, pero sólo si nuestro único programa en ejecución necesita más memoria que la que tiene la memoria principal; etc. Es decir, realmente hay muchas razones más o menos poderosas para quedarse con la multiprogramación, que por otra parte provoca un inmediato aumento de productividad en nuestro ordenador (posibilidad de ejecutar varias aplicaciones a la misma vez).
e) ¿Se puede considerar que la interfaz gráfica de usuario forma parte del sistema operativo? Aporte razones a favor y en contra.
Esta pregunta sí que no tiene respuesta: es sólo una excusa para que desarrollen su capacidad de argumentar con los conocimientos de los que disponen.
Pregunta 2: resolver un problema de concurrencia
La opción (a) consiste en resolver el primer problema de los lectores/escritores, pero con la limitación añadida de un máximo de veinte lectores concurrentes.
Esta es una posible implementación con cerrojos y variables condición, con dos variables globales inicializadas a cero y dos variables condición, una para lectores y otra para escritores. Esta solución funciona tanto con semántica Mesa como Hoare.
LECTOR |
ESCRITOR |
Mutex.acquire() While Lectores>20 do Espera++ Puedo_leer.wait() Espera-- End while Lectores++ Mutex.release() ... LEER ... Mutex.acquire() Lectores-- If lectores=0 y espera=0 Puedo_escribir.signal() Else Puedo_leer.signal() End if Mutex.release() |
Mutex.acquire() While Lectores>0 do Puedo_escribir.wait() ... ESCRIBIR ... Mutex.release() |
La opción (b) pide escribir una solución al problema de los filósofos libre de interbloqueos. En el capítulo del Silberschatz correspondiente a interbloqueo pueden encontrar distintas formas de construir dicha solución.
Pregunta 3. Comprobar estado de asignación de recursos
Partimos de esta situación:
Recursos. A=9; B=3; C=6.
Proceso |
Necesidades máximas |
Asignado |
||||
A |
B |
C |
A |
B |
C |
|
P1 |
3 |
2 |
2 |
1 |
0 |
0 |
P2 |
6 |
1 |
3 |
5 |
1 |
1 |
P3 |
3 |
1 |
4 |
2 |
1 |
1 |
P4 |
4 |
2 |
1 |
0 |
0 |
1 |
Para ello, debemos buscar una secuencia segura.
Los recursos disponibles son A=1; B=1; C=3. Con estas existencias, podemos atender cualquier petición que realicen P2 y P3. Si cualquiera de ellos termina, se puede también atender a P1 en el peor caso. Y con todos estos recursos liberados, puede terminar P4. Por tanto, existen múltiples secuencias seguras para este estado, así que es un estado seguro.
Como se trabaja con el algoritmo del banquero, el sistema puede reaccionar concediendo la petición o denegándola en caso de que se pasara a un estado inseguro. El nuevo estado, si concediéramos la petición, sería:
Disponible:
A=0; B=1; C=2.
Proceso |
Necesidades máximas |
Asignado |
||||
A |
B |
C |
A |
B |
C |
|
P1 |
3 |
2 |
2 |
2 |
0 |
1 |
P2 |
6 |
1 |
3 |
5 |
1 |
1 |
P3 |
3 |
1 |
4 |
2 |
1 |
1 |
P4 |
4 |
2 |
1 |
0 |
0 |
1 |
Busquemos una secuencia segura. En esta situación, ningún proceso puede finalizar en el peor caso, porque todos y cada uno de ellos pueden pedir un recurso de tipo A, del cual no quedan existencias. Por tanto no existe secuencia segura y el estado es inseguro.
Así pues, el sistema tendrá que denegar la petición y dejar al proceso bloqueado.
Pregunta 4. Máquina con memoria segmentada.
Son 10 bits de segmento más 22 bits de desplazamiento = 32 bits.
Por tanto pueden existir 232 direcciones = 4 Gigabytes.
Como hay 22 bits disponibles para desplazamiento, serán 222 bytes por segmento = 4 Megabytes.
Podría ser algo así:
segmento |
Dir. base |
Longitud (bytes) |
0 |
300000 |
10240 |
1 |
200000 |
25600 |
2 |
700000 |
2048 |
3 |
0 |
131072 |
Base[2]+desplazamiento = 700000 + 1000 = 701000
Si observamos el reparto de la memoria física, vemos que sólo hay un hueco que tiene más de 400Kb, y es el espacio que queda a continuación de la dirección física 702048. Por tanto, el hueco será concedido en esa dirección, o bien justo al final de la memoria física (que también dejaría un único hueco compacto).