SISTEMI OPERATIVI E LABORATORIO (Indirizzo Sistemi e Reti) 6 luglio 2006 Cognome: Nome: Matricola: Scelgo di svolgere: [ ] la parte relativa alla teoria. [ ] la parte relativa al laboratorio UNIX Ricordate che non potete usare calcolatrici o appunti. Siate sintetici nelle vostre risposte, anche quando è richiesto di motivarle, sono sufficienti poche righe per rispondere correttamente. ESERCIZI RELATIVI ALLA PARTE DI TEORIA DEL CORSO ESERCIZIO 1 (9 punti) a) riportate lo pseudocodice che descrive l implementazione dell operazione di wait su un semaforo, e indicate (ad esmpio racchiudendolo in un riquadro) quale porzione del codice deve essere eseguita in mutua esclusione. wait(semaphore S) : S.value--; if S.value < 0 then aggiungi questo processo a S.waiting block(); end; b) Come è fatto un generico semaforo (o variabile semaforica )? Descrivete la funzione di ciascuna variabile/struttura di cui è composto. Che rapporto vi è tra gli elementi di un semaforo? Un semaforo è costituito da due campi: valore e coda di attesa type semaphore = record end; value: integer waiting: list of process; Il campo value contiene il valore corrente del semaforo. Se value è positivo, la coda vaiting è certamente vuota. In genere, se value è negativo waiting contiene dei processi in attesa (non è però necessariamente così, ad esempio se value è stato inizializzato ad un valore negativo) c) Che effetto ha la system call usata nello pseudocodice? 1
toglie la CPU al processo che la invoca e manda in esecuzione uno dei processi in Ready Queue. Il processo che ha chiamato block non viene rimesso nella Ready Queue d) Perche i semafori sono preferibili ad una soluzione come l algoritmo di dekker, o l algoritmo del fornaio, o gli algoritmi che usano speciali istruzioni hardware? Perché evitano il busy-waiting e) Riportate un semplice esempio di due processi concorrenti che possono andare in deadlock (ma che non necessariamente vanno in deadlock) a causa di un uso scorretto dei semafori. Indicate anche un possibile valore iniziale dei semafori usati Q = 1; S = 1 P 0 P 1 wait(s); wait(q); wait(q); wait(s);..... signal(s); signal(q); signal(q); signal(s); ESERCIZIO 2 (9 punti) (attenzione: nel seguito tutti i numeri si intendono in esadecimale motivate sempre le vostre risposte.) In un sistema le pagine hanno una dimensione di 400 byte, e la RAM è suddivisa in 100 frame. Nelle page table del sistema, un numero di pagina è scritto su 2 byte, e la page table più grossa ammessa dal sistema occupa completamente un frame della RAM (per semplicità, non consideriamo la presenza del bit di validità e del dirty bit.) a) Il sistema usa un algoritmo di rimpiazzamento delle pagine? Si. Infatti una page table contiene al massimo il numero di 400/2 = 200 (esadecimale, ossia 512 decimale) pagine, mentre la RAM è suddivisa in 256 (decimale) frame. b) Qual è la lunghezza in bit di un indirizzo fisico? 18 bit (2 10 2 8 = 2 18 ) c) Qual è, espresso come potenza di due, la dimensione massima di un processo eseguibile nel sistema? Non è altro che lo spazio di indirizzamento logico, pari a 2 10 2 9 = 2 19 byte d) Se in un generico sistema operativo lo spazio di indirizzamento fisico è più grande dello spazio di indirizzamento logico, il sistema può soffrire del problema del trashing (motivate la vostra risposta)? Si. Può succedere se a) il sistema implementa la memoria vistuale e b) la dimensione globale dei processi attivi nel sistema eccede lo spazio di indirizzamento fisico (nel caso più banale, se eccede la dimensione della RAM) e) Descrivete brevemente il meccanismo di traduzione di un indirizzo logico in un indirizzo fisico in un sistema paginato (date per scontati i concetti di pagina, frame, page table. Usate un disegno se lo ritenete utile). 2
Ogni indirizzo logico di un processo è suddiviso in due parti: Numero-Pagina, Offset. Il Numero-Pagina viene usato come indice all interno della Page Table del processo per estrarre il Numero-Frame della Ram in cui è contenuta la corrispondente pagina. L indirizzo fisico viene formato come Numer-Frame, Offset. f) Di un sistema paginato (assumiamo che il sistema non abbia memoria virtuale) si dice che la traduzione degli indirizzi da logici a fisici mostra un hit ratio del 90%. Che cosa vuol dire? Il sistema usa un TLB per contenere una porzione della Page Table del processo in esecuzione. Nel 90% dei casi, il numero della pagina dell indirizzo logico generato si trova nel TLB, e non è necessario cercare il numero del frame corrispondente in RAM. ESERCIZIO 3 (9 punti) Per le risposte alle domande a) e d) vedere i lucidi del capitolo 12 a) Elencate sinteticamente i vantaggi e gli svantaggi dell allocazione concatenata dei file su disco. b) Il disco di un sistema ha una capacità di memorizzazione di 128K byte, e i blocchi del disco sono grandi 512 byte. Un file X è lungo 10240 byte. Per le allocazioni concatenata (no FAT) e indicizzata indicate: quanti blocchi devono essere usati per memorizzare il file (inclusi i blocchi usati per implementare il metodo di allocazione usato), e qual è la quantità di memoria (in byte) non utilizzata su disco sprecata a causa della memorizzazione del file. Motivate le vostre risposte. : il disco contiene in tutto 256 blocchi. E quindi sufficiente un byte per memorizzare il numero di un blocco. Allocazione concatenata: Ogni blocco contiene un puntatore da un byte al blocco successivo, e memorizza quindi 511 byte di dati del file. Sono quindi necessari 21 blocchi per memorizzare l intero file. L ultimo blocco contiene solo 20 byte di dati, mentre l ultimo byte è usato per contenere il marker di fine file, per cui 512 21 byte vengono sprecati. (se si contano come sprecati anche i byte che memorizzano il numero del blocco successivo nei blocchi precedenti, vanno aggiunti altri 20 byte sprecati). Allocazione indicizzata. Sono necessari 21 blocchi per memorizzare il file, di cui 1 è il blocco indice. Il blocco indice contiene 20 puntatori, per un totale di 20 byte, e i restanti 512 20 byte vengono sprecati. c) Nel caso di allocazione indicizzata, è possibile che nel disco di questo sistema si debba fare ricorso alla allocazione indicizzata a schema concatenato o a più livelli (motivate la vostra risposta)? No. Infatti, un blocco indice può contenere 512 numeri di blocco, ma l intero disco è formato di soli 256 blocchi. d) Date un esempio della variante dell allocazione concatenata normalmente usata nei sistemi windows, usando un ipotetico hard disk da 16 blocchi contenente un unico file distribuito nei blocchi 9, 4, 2, 14 (in quest ordine).. e) Un disco contiene un file che occupa molti blocchi, e che deve essere letto in maniera sequenziale. Quale delle tre forme di allocazione dello spazio su disco garantirebbe la maggior velocità di accesso al file (indipendentemente da qualsiasi altra considerazione su vantaggi e svantaggi delle tre forme di base di allocazione --- motivate la vostra risposta)?. 3
L allocazione contigua. Infatti, una volta posizionata la testina sul primo blocco del file, tutti gli altri blocchi possono essere letti senza ulteriori spostamenti del braccio della testina fra i vari cilindri del disco (cosa che invece avverrebbe se il file non fosse allocato in modo contiguo). f) Dove sono memorizzati, da un punto di vista logico (ovviamente, fisicamente gli attributi sono in memorizzati in modo permanente in qualche blocco del disco), gli attributi di un file su disco? Nella directory che contiene il file, oppure in una struttura interna del sistema puntata da un puntatore contenuto della directory che contiene il file. ESERCIZI RELATIVI ALLA PARTE DI UNIX ESERCIZIO 1 (3 punti) Scrivere l'output a monitor del seguente programma (decidete voi quale stringa venga digitata dall'utente e letta tramite scanf): #define N 40 typedef struct n { char dato[n]; int cnt; } dato; dato d; main(int argc, char **argv) { char n[24]; int p; printf( \n inserire un dato: ); scanf( %s, n); } p = fork(); if (p) { strcpy(d.dato, n); d.cnt = strlen(n); } else { strcat(d.dato, ok ); d.cnt += 3; } printf( \n %s %d, d.dato, d.cnt); 4
: Supponendo che l'utente digiti la stringa Alessandria, l'output a monitor (esclusa la prima printf) è: ok - 3 Alessandria - 11 (le scritte possono comparire in ordine inverso a seconda dello scheduling della CPU) ESERCIZIO 2 (3 punti) la seguente invocazione di msgsnd è corretta? Motivare la risposta: typedef struct m { int len; long type; char dato[n]; } msg; msg tosend; strcpy(tosend.dato, dato ); tosend.len = strlen(tosend.dato); tosend.type = 1; msgsnd(id, &tosend, sizeof(msg), 0); dove id è il corretto identificatore della coda di messaggi da utilizzare. No. Il puntatore passato come secondo parametro deve fare riferimento type della struttura corrispondente al messaggio da inviare. ESERCIZIO 3 (4 punti) è possibile settare i diritti di accesso di una directory M e di un file F in modo tale che un utente, proprietario sia di F che di M, possa creare F all'interno di M ma non possa modificare F, una volta creato? Se sì illustrare la soluzione, se no motivare la risposta. Si. r w x...... M r - -...... F ESERCIZIO 4 (3 punti) sia dato il seguente makefile p1: prog1.c gcc o prog1 prog1.c p2: prog2.c gcc o prog2 prog2.c in quale caso lanciando make p1 la regola di compilazione associata a tale target non scatta? In quale caso invece scatta? scatta sempre. 5
ESERCIZIO 5 (3 punti) spiegare il funzionamento del seguente script per bash: #!/bin/bash shopt s extglob for nyf in!($1.*) do echo $nyf done il programma setta la variabile extglob ed attiva in questo modo alcune capacità di pattern matching della shell. Il ciclo for scorre l'elenco di tutti i file, contenuti nella directory corrente e che non corrispondono al pattern indicato fra parentesi (estensione qualsiasi e nome corrispondente alla stringa passata come parametro allo script). I nomi di tali file vengono visualizzati a monitor. ESERCIZIO 6 (3 punti) Supponiamo che venga lanciata l'esecuzione del programma prog (utilizzando il nome del programma privo di alcun path innazi ad esso) in background, da linea di comando. Prog deve necessariamente essere contenuto nella directory di lavoro? Motivare la risposta. No. La shell cerca prog all'interno di una lista di directory contenuta in una sua variabile di ambiente (di solito chiamata PATH). ESERCIZIO 7 (3 punti) Nella programmazione con i thread POSIX la funzione di libreria pthread_cond_wait viene utilizzata da un thread per sospendersi su una certa condizione logica definita da una variabile di tipo pthread_cont_t, per esempio: pthread_cond_wait(&cond,&m); usualmente l'esecuzione di tale chiamata è condizionata dal verificarsi o meno di alcuni vincoli su qualche variabile del programma, se ad esempio la macro VINCOLI_NON_SODDISFATTI è un'espressione Booleana che stabilisce se tali vincoli sono soddisfatti allora la chiamata della wait dovrebbe essere condizionata come segue: while( VINCOLI_NON_SODDISFATTI==TRUE ) pthread_cond_wait(&cond,&m); spiegare perché quando più thread possono modificare il soddisfacimento dei vincoli è necessario racchiudere la pthread_cond_wait(&cond,&m) in un while invece che usare semplicemente un'istruzione di branching del tipo if( VINCOLI_NON_SODDISFATTI==TRUE ) 6
la risposta a questa domanda è documentata nella pagina del manuale online di linux (man pthread_cond_wait) ed è riassunta nel commento del programma C sui thread fornito sul sito di i-learn ESERCIZIO 8 (5 punti) Dire se le funzioni di una libreria, utilizzabili da processi single-thread, possono sempre essere utilizzate anche da processi multi-thread. Ad esempio, durante le esercitazioni pratiche in laboratorio sono state utilizzate le funzioni che manipolano le stringhe come la 'strcpy', 'strcat' e simili. Queste sono funzioni di libreria. Sicuramente potete utilizzarle in un programma composto da un processo con un singolo thread. La questione è: "queste funzioni si possono utilizzare senza ulteriori precisazioni (direttamente) in processi composti da più thread?" oppure è necessario assicurarsi che l'autore della libreria abbia adottato accorgimenti particolari? Motivare le risposte anche con argomentazioni pratiche e possibili soluzioni. (per aiutarvi nella risposta provate ad immaginare di scrivere voi una libreria, cioè un insieme di funzioni C da richiamare in altri moduli sorgenti, e provate ad immaginare cosa dovreste fare o cosa potrebbe succedere se più thread chiamassero tali funzioni. Spiegare quindi quando la libreria può essere sicuramente usata da più thread). la risposta è no - questa soluzione non è documentabile in quanto richiede lo sforzo intellettuale dello studente, una spiegazione può essere trovata a http://en.wikipedia.org/wiki/thread_safe Riguardo il viceversa la risposta è si. 7