Septiembre 2008 (con Soluciones)

Anuncio
Ingeniería Informática. Curso 3º
Sistemas Operativos
Examen Final. PROBLEMAS.
5 de Septiembre de 2008
1.
Es necesario modelar el comportamiento de un ascensor que presta servicio a un edificio de 20
pisos. Dicho ascensor es utilizado por robots para subir a su planta destino. El ascensor se encuentra
inicialmente en la planta baja. Los robots afluyen continuamente y van accediendo al ascensor en la
planta baja. Cuando hay 5 robots en el ascensor, éste cierra sus puertas; los demás robots tendrán que
esperar. Cada robot que consigue acceder al ascensor solicita un piso de destino (por simplicidad
consideraremos que cada robot subido al ascensor va un piso diferente).
Una vez ocupado el ascensor al completo, éste se pone en marcha y sube, accediendo a los pisos
solicitados en orden de recorrido. El robot que haya llegado a su destino se baja y acaba su operación.
Vaciado el ascensor, éste regresa inmediatamente a la planta baja para cargar 5 nuevos robots.
El comportamiento de ambos procesos los podemos esquematizar así:
robot(int piso_destino)
- Esperar a que haya sitio en el ascensor, y entrar
cuando sea posible;
- Pulsar piso de destino;
- Notificar al ascensor si ya hay 5 robots
- Esperar a que el ascensor alcanza el piso destino;
- Bajar
ascensor()
Ir a planta baja(); // función dada. No implementar
while (true) {
esperar a que entren 5 robots;
for (i=0; i<5; i++) {
- determinar siguiente piso destino
- avisar al robot adecuado;
}
Ir a planta baja()
}
(a) (2 puntos) Codificar los procesos robot() y ascensor() empleando cerrojos y variables
condicionales con los siguientes significados:
A: variable de condición para la espera de los robots a la entrada del ascensor.
B: variable de condición para la espera del ascensor en la planta baja.
C: variable de condición para notificar la bajada de un robot en su planta destino.
PISOS[20]: array de variables de condición para la espera de un robot dentro del ascensor hasta
llegar a su destino.
La pulsación del piso de destino se simula mediante la puesta a TRUE de la entrada
correspondiente de un array PISOS_pulsados[20], inicializado a FALSE.
(b) (3 puntos) Codificar el mismo problema utilizando ahora el mecanismos de sincronización de
semáforos generales para que tengan el siguiente comportamiento. Determina en primer lugar las
variables y semáforo que consideres necesarios, indicando claramente el valor inicial de cada uno.
2. Dado el código que se presenta a continuación, y asumiendo que el directorio data existe y contiene
inicialmente un fichero llamado result, responde a las siguientes preguntas:
a.
b.
c.
(1 punto) Dibujar el estado de las tablas de descriptores de ficheros (tdda), intermedia (TIN) y de
nodos-v (I-nodos) justo antes de la finalización del proceso hijo. Asuma que el proceso padre es
más prioritario que el hijo.
(2 puntos) Si el sistema de ficheros es tipo FAT, indica un posible estado final del sistema,
incluyendo tanto las entradas de la FAT como los bloques de datos relevantes (incluyendo los
directorios data y doc). Los bloques de datos son de 1KB (1024 bytes).
(2 puntos). Asumir ahora que el sistema de ficheros usado es una simplificación del modelo de
Unix: nodos-i con 4 punteros directos y uno indirecto. Indica el contenido de los nodos-i y de
los bloques de datos relevantes (incluyendo los directorios data y doc). Los bloques de datos
son de 1KB (1024 bytes).
int fd1;
int fd2;
char buf1[2000]=”aaaa...a”;
char buf2[1500]=”bbbb...b”;
void hijo( ) {
fd2=open(”data/result”,O_RDWR);
write(fd1,buf1,2000);
lseek(fd1,2500,SEEK_CUR);
write(fd1,buf1,500);
write(fd2,buf2,1500);
close(fd2);
}
main() {
mkdir(”data/doc”); //Creación de dir doc
fd1=open(“data/doc/examen”,O_CREATE…);
if (fork() == 0) {
hijo();
exit(0);
}
else {
//Escribimos 1500 c’s en buf2
memcpy(buf2,”cccc...c”,1500);
fd2=open(”data/result”,O_RDWR);
wait(NULL);
lseek(fd1,1500,SEEK_CUR);
write(fd1,buf2,500);
write(fd2,buf2,500);
}
}
Ingeniería Informática. Curso 3º.
Sistemas Operativos
Examen Final. TEORIA.
5 de Septiembre de 2008
1. [PROCESOS]
a) Considerar el siguiente grafo de precedencia de procesos/procedimientos:
C
E
G
A
B
D
F
Proponer el código del esquema de ejecución de este grafo (1)usando fork() y wait().
b) Indicar al menos 5 causas por las que el kernel de un sistema operativo se vea obligado a hacer entrar
en operación al planificador de procesos, si este utiliza una política de planificación expropiativa por
prioridades similar a la de Linux.
2. [SINCRONIZACION Y COMUNICACIÓN]
a) La existencia de una instrucción test-and-set en el repertorio de instrucciones del procesador permite
incorporar al kernel del sistema operativo funciones básicas de sincronización lock y unlock del tipo
llamado con “espera activa”. Dos posibles implementaciones alternativas a la estudiada de la operación
lock() son las siguientes
VERSION 1
while (test-and-set(cerrojo))
yield(); // ceder uso de CPU
VERSION 2
while (TRUE) {
if (!test-and-set(cerrojo) break;
while (cerrojo == 1)
;
}
¿Qué ventajas respecto a la implementación básica original aportan cada una de las dos versiones?
Recuerda la implementación básica:
while (test-and-set(cerrojo)) { }
b) Considerar los siguientes mecanismos de sincronización: mutex, variables condicionales, semáforos
anónimos, semáforos con nombre. Y los siguientes mecanismos de comunicación: memoria compartida,
pipes anónimos, pipes con nombre, paso de mensajes. Indicar cuáles serán los mecanismos
preferiblemente aplicables y por qué para cada uno de los siguientes escenarios: (1) coordinación entre
threads, (2) coordinación entre procesos emparentados (por ejemplo, entre padre e hijo) o (3)
coordinación entre procesos no emparentados.
3. [MEMORIA]
a) ¿Qué relación hay entre un fichero ejecutable y el mapa de memoria de un proceso? ¿Cómo contribuye
al mapa de memoria de proceso una biblioteca estática? ¿Y una biblioteca dinámica?
b) Describir la operación de tratamiento de un fallo de página en caso de gestión de memoria virtual
paginada por demanda con política de reemplazamiento por buffering.
c) El espacio virtual de memoria de un proceso es la suma de los espacios virtuales de los hilos que lo
integran. ¿Cierto o falso? Razonar.
4. [ENTRADA/SALIDA]
a) En relación al dispositivo reloj, indicar qué afirmaciones son ciertas. Justifica tu respuesta- Siempre que se produce una oscilación del reloj se produce una interrupción del mismo.
- El tiempo entre dos interrupciones de reloj es configurable por el sistema operativo.
- Una de las funciones típicas gestionadas por el reloj es la planificación de procesos
b) Señala, de entre las siguientes, las ventajas que aporta la utilización de los buffers del sistema operativo
en dispositivos de bloques. Justifica tu respuesta.
- Mejora del rendimiento en grandes accesos secuenciales.
- Mejora el rendimiento al no tener que acudir siempre al dispositivo para realizar la operación
requerida
- Permite el uso simultáneo de dispositivos de uso exclusivo.
c) Comparar las modalidades RAID4 y RAID5, indicando cuál es la usada habitualmente y por qué. Si
disponemos de un RAID5 con cuatro discos, ¿cuántos discos se leen/modifican por una escritura de un
bloque?
5. [SISTEMA DE FICHEROS]
a) Enumera los distintos tipos de ficheros que admite típicamente un sistema de ficheros UNIX e indica
si la llamada lseek() le es aplicable o no. ¿Qué explicación tiene en cada caso la situación EOF – Fin de
Fichero?
b) ¿Qué beneficio y/o perjuicio tendría que la primer parte (por ejemplo, los primeros 512 bytes) de un
fichero UNIX se almacenase en el mismo bloque de disco que su i-nodo?. En caso de ser así, ¿cuántas
operaciones de disco se necesitarían como mínimo para obtener el i-nodo del fichero
/home/pepe/practica2/prog.c suponiendo que en memoria ya se encuentra el i-nodo del directorio raíz,
pero ninguna otra cosa de las necesarias para recorrer la ruta?
SOLUCIONES DEL EXAMEN DE SSOO.
SEPTIEMBRE 2008.
PROBLEMA 1
Solución con variables condicionales
Declaraciones iniciales
condvar A; espera de robots para subir al ascensor
condvar B; espera de ascensor a que suban 5 robots en planta baja
int ocupados=0; contador de robots dentro del ascensor
condvar PISOSA[20]; array de 20 condiciones una por cada piso
boolean PISOSB[20]; array de 20 booleanos con el estado de piso-solicitado – inicial a FALSE
condvar C=0; notificación de bajada de robot del ascensor
mutex mutex;
Proceso robot(int destino)
Proceso ascensor()
lock(mutex);
while (ocupados >=5)
waitc(A,mutex);
ocupados++;
PISOSB[destino] = TRUE;
if (ocupados==5) signalc(B);
waitc(PISOSA[destino], mutex);
ocupados--;
PISOSB[destino] = FALSE;
signalc(C);
unlock(mutex);
while (TRUE) {
lock(mutex);
while (ocupados < 5)
waitc(B, mutex);
p=0;
for (i==0; i<5; i++) {
while(PISOSB[p]==FALSE) p++;
signalc(PISOSA[p]);
waitc(C, mutex);
}
unlock(mutex);
Ir_a_planta_baja;
broadacast(A);
}
Solución con semáforos
Declaraciones iniciales
Semáforo A=5; espera de robots para subir al ascensor
Semáforo B=0; espera de ascensor a que suban 5 robots en planta baja
int ocupados=0; contador de robots dentro del ascensor
semáforo PISOSA[20]; array de 20 semáforos uno por cada piso, iniciados a 0
boolean PISOSB[20]; array de 20 booleanos con el estado de piso-solicitado – inicial a FALSE
Semáforo C=0; notificación de bajada de robot del ascensor
Semáforo mutex;
Proceso robot(int destino)
Proceso ascensor()
wait(A);
wait(mutex);
ocupados++;
if (ocupados==5) signal(B);
PISOSB[destino] = TRUE;
signal(mutex);
wait(PISOSA[destino]);
wait(mutex);
ocupados--;
PISOSB[destino] = FALSE;
signal(mutex);
signal(C);
while (TRUE) {
wait(B);
p=0;
for (i==0; i<5; i++) {
wait(mutex);
while(PISOSB[p]==FALSE) p++;
signal(mutex);
signal(PISOSA[p]);
wait(C);
}
Ir_a_planta_baja;
for (i==0; i<5; i++)
signal(A);
}
PROBLEMA 2.
Estado de las tablas justo ANTES de la llamada close(fd2) del proceso hijo:
Tdaa Padre
Entrada estándar
Salida estándar
Salida error
(fd1) ->id1 de TIN
(fd2) -> id2 de TIN
Tdaa hijo
Entrada estándar
Salida estándar
Salida error
(fd1) -> id1 de TIN
(fd2) -> id3 de TIN
TIN (tabla global)
Entrada
Id1:
Id2:
Id3:
N punteros
2
1
1
Contador
5000
0
1500
Permisos
R,W
R,W
R,W
Puntero a nod-v
Visión LÓGICA del estado final de cada fichero:
Examen -> 2000 ‘a’ (BL 0 -1) – blancos hasta 4500 (BL 1,2,3y4) – 500 ‘a’ (BL
4) – blancos hasta 6500 (BL 4, 5 y 6) – 500 ‘c’ (BL6). Total 7 bloques lógicos
Result -> 500 ‘c’ (BL 0) – 1000 ‘b’ (BL 0 y 1). Total 2 bloques lógicos
b) Sistema FAT.
Posible FAT:
0
eof
1
eof
2
3
3
eof
4
5
5
6
6
7
7
8
8
9
9
10
10
eof
11
free
12
free
El bloque FÍSICO 0 contendrá las entradas del directorio “data”:
Nombre fichero
Doc
Result
Tipo
D
R
Tamaño Fecha Permisos….. Primer bloque Físico
--………
1
1500
…………………
2
El bloque FÍSICO 1 contendrá las entradas del directorio “data” :
Nombre fichero
examen
Tipo
R
Tamaño Fecha Permisos…..
7000
…………………
4
El fichero “result” se almacenará en los bloques físicos 2 y 3. El fichero
“examen” ocupará los ficheros físicos 4,5,6,7,8,9 y 10 (si bien, los bloques 6, 7
y 9 contendrán únicamente espacios en blanco).
c) Sistema tipo Unix
Necesitaremos 4 nodos-i:
Nodo-i 3 (relativo al directorio /data)
Tipo: D
P. Dir 0: 33
P. Dir 1: NULL
P. Dir 2: NULL
P. Dir 3: NULL
P. Ind. : NULL
Nodo-i 8 (relativo al fichero /data/result)
Tipo: R ….
P. Dir 0: 15
P. Dir 1: 16
P. Dir 2: NULL
P. Dir 3: NULL
P. Ind. : NULL
Nodo-i 7 (relativo al directorio /data/doc)
Tipo: D
P. Dir 0: 12
P. Dir 1: NULL
P. Dir 2: NULL
P. Dir 3: NULL
P. Ind. : NULL
Nodo-i 12 (relativo al fich. /data/doc/examen)
Tipo: R
P. Dir 0: 40
P. Dir 1: 41
P. Dir 2: NULL
P. Dir 3: NULL
P. Ind. : 42
Bloques (físicos) de datos ocupados:
Bloque 33 (entradas de /data)
.
3
..
?
doc
7
result 8
Bloque 12 (entradas de …/doc)
.
7
..
3
examen 12
Bloques físicos 15 y 16: contenido de /data/results
Bloques físicos 40 y 41: contenido de los bloques lógicos 0 y 1 de /data/doc/examen
Bloque físico 42 (bloque físico dedicado a albergar punteros a otros bloques físicos)
43
NULL
47
NULL
NULL
…….
Bloque físico 43: contenido del bloque lógico 4 de …/examen
Bloque físico 47: contenido del bloque lógico 6 de …/examen
TEORIA
Cuestión1
a)
Con fork() y wait()
pidA = Fork(); exec(“A);
wait(pidA);
pidB = fork(); exec(“B”);
pidC = fork(); exec(“C”);
wait(pidC);
pidE = fork(); exec(“E”);
wait(pidB);
pidD = fork() ; exec(“D”) ;
wait(pidE);
wait(pidD);
pidF = fork() ; exec(“F”);
wait(pidF);
pidG = fork(); exec(“G”);
wait(pidG);
b) Puntos de activación del planificador
1. Acaba el proceso en ejecución P
2. P realiza una llamada bloqueante (p.ej, pause())
3. P causa una excepción que lo bloquea (p.ej., fallo de página mayor)
4. P desbloquea un proceso más prioritario (p.ej., signal(sem) o msgsend(q,m))
5. Una interrupción desbloquea un proceso más prioritario que P. (p.ej., fin de
temporizador, o de operación de disco o de operación de Terminal)
6. Una interrupción de reloj marca el fin del quanto de P
7. P cede el uso de la CPU: yield();
8. P hace una llamada que rebaja su prioridad y como consecuencia otro proceso
resulta más prioritario (p.ej., nice(10))
9. P crea un hilo más prioritario (p.ej. pthread_create())
Cuestión 2.
a) Ventaja VERSION 1: reduce la espera activa al permitir que otros procesos
preparados para ejecutarse tengan la posibilidad de ser planificados mientras dure la
espera activa por el cerrojo
Ventaja VERSION 2: la operación test-and-set supone un doble acceso indivisible a la
dirección de memoria del “cerrojo” – una para leer su contenido y otra para escribir (un
1) en él. Con esta versión, mientras la espera activa detecte que el valor del cerrojo es 1
solo realizará operaciones de lectura de memoria, ahorrando así los ciclos de escritura.
b)
Sincronización
Comunicación
Threads
Procesos
emparentados
Procesos no
emparentados
Mutex, varcond
Memoria_compartida
Semáforos_anónimos
Pipes anónimos,
Memoria compartida
Semáforos con nombre
Pipes con nombre
Memoria compartida
Paso de mensajes
Cuestión 3.
a) El fichero ejecutable tiene una estructura fija en la que se incluyen secciones
(código, datos con valor inicial) que se convertirán en regiones de memoria.
En el fichero existe una Tabla de Secciones que marca el comienzo y tamaño
de cada sección dentro del fichero.
Una biblioteca estática ya está incluída en el fichero ejecutable, por tanto no
modifica el mapa de memoria durante la ejecución del proceso (formará
parte de la región de código y de la región de datos)
Sin embargo, en el caso de una biblioteca dinámica, el código necesario se
incluirá en el mapa de memoria del proceso cuando éste haga uso de una
función de la biblioteca o durante la carga del programa (creándose nuevas
regiones de forma dinámica).
b) Fallo de página -> excepción
-> (asumiendo dirección de usuario) el S.O. comprueba la dirección
virtual para saber si está en una región válida del mapa del proceso (podría
ser una expansión de pila)
-> Buscar en la(s) listas asociadas al buffering si el contenido aún reside
en memoria (fallo menor). Si es así, no hay que buscar marco libre. Sólo
modificar la TP del proceso para que la página apunte a ese marco y
ponerla como válida.
-> Si no está en memoria, habría que traerla a memoria desde el
dispositivo de respaldo. Como se usa buffering, tenemos un marco libre
seguro.
-> No es necesario emplear ninguna política de reemplazamiento de
página. Ese proceso está desacoplado del tratamiento del fallo gracias al
buffering.
c) Falso. Los hilos comparten el mismo espacio virtual. De hecho, comparten
prácticamente todas las regiones (excepto la pila, pero todas las pilas residen en el
mismo espacio virtual).
Cuestión 4.
a.
i. Reloj del sistema, funciona con una batería y mantiene la fecha y hora con el
sistema apagado. El reloj temporizador produce interrupciones
periódicamente, que se utilizarán para distintos propósitos (temporizadores,
estadísticas, planificación)
ii. Ninguno de los dos, aunque su programación se realiza escribiendo en
registros de E/S y usa interrupciones para notificar sus eventos. Pero no tiene
sentido pensar en un acceso aleatorio (de tamaño fijo) o secuencial al
dispositivo.
iii. Sí. Es un contador que, al llegar a 0, produce una interrupción.
iv. Sí (para planificaciones tipo round-robin)
b.
i. Falso. En esos casos es contraproducente
ii. Cierto.
c. Se usa RAID5 por la distribución de bloques de paridad entre discos. Para una
escritura, leeremos el bloque del disco destino, lo modificaremos (escritura);
leeremos el disco que contenga el bloque de paridad correspodiente, recalcularemos
la paridad y escribiremos de nuevo el bloque (otra escritura).
Cuestión 5.
a. Fichero regular -> lseek aplicable. EOF: final de fichero
Directorio -> lseek: no. EOF: final de la lista de entradas
Tubería -> lseek: no. EOF: se devuelve en una lectura si no hay escritores en
el extremo de escritura
Enlace simbólico -> lseek: no (no sobre el enlace; sí si el fichero enlazado es
regular). EOF: depende del fichero apuntado
Dispositivo (bloques o caracteres) -> lseek: no. EOF: Depende del
dispositivo
b. La lectura de un i-nodo de disco incluiría parte de la información del fichero.
Para directorios, puede incluir la lista de muchos de sus ficheros, evitando una
segunda lectura. La desventaja es que traemos más datos potencialmente inútiles por
cada lectura de nodo-i. Además, si el fichero está vacío, desperdiciaremos esos 512
bytes.
En el caso mejor para el tratamiento de la ruta propuesta bastaría con 3
lecturas (los nodos-i de home, pepe y practica2) para conocer el número de nodo-i
de “prog.c” (con otra lectura, tendríamos el nodo-i de prog.c)
Descargar