Sartomiki.net

  • Aumenta dimensione caratteri
  • Dimensione caratteri predefinita
  • Diminuisci dimensione caratteri
Home Cronologia Sistemi operativi Domande riassuntive

Domande riassuntive

E-mail Stampa PDF
Valutazione attuale: / 16
ScarsoOttimo 

1. Le system  call  sleep  e  alarm a cosa   servono,   come   si   usano,   sono   intercambiabili,   si possono usare  insieme nello stesso processo?  Come si  annulla un  time reimpostato? Un processo in attesa su una pipe riceve un segnale SIGALRM?

-unsigned int sleep(unsigned int seconds): 
Sospende l'esecuzione del processo per il numero di secondi specificato. 
-unsigned int alarm(unsigned int seconds): 
Invia al processo corrente il segnale SIGALRM dopo che siano trascorsi il numero di secondi specificato. Una successiva chiamata ad alarm() reimposta il tempo di invio del segnale SIGALRM. Se il numero di secondi è zero, non viene attivato nessun allarme e viene disabilitato l'eventuale allarme precedentemente impostato.  

-sleep() può essere basata sull'arrivo del segnale SIGALRM, pertanto è da evitare un uso contemporaneo di sleep() e della system call alarm().
Il processo in pipe riceve i segnali a lui inviati come un processo qualsiasi e reagisce con il comportamento definito per quel dato segnale.

2. Dettagliare le differenze essenziali tra processi, user thread e kernel thread.

Un thread è parte di un processo: i processi possono essere costituiti da uno o più  threads. I thread di uno stesso task hanno in comune sezione di codice, sezione di dati e risorse di sistema, mentre è difficile tenere qualcosa in comune tra processi.
Gli user thread sono suppoortati mediante un insieme di chiamate a livello utente o di librerie di sistema e quindi non vi è l'intervento del kernel. Viceversa nel kernel thread gli stessi thread vengono generati chiamando la system call del sistema e quindi con l'interazione del kernel stesso.
I vantaggi del primo sono :
-un context swith veloce tra thread di uno stesso task
-poter implementare sopra un kernel qualsiasi
Gli svantaggi che comporta sono invece
-solo un thread running per task, anche in un sistema multiprocessore
-se un thread effettua una system call bloccante sono bloccati tutti i thread dello stesso task
I vantaggi del secondo sono:
-i thread ready possono essere schedulati anche se appartengono allo stesso task di un thread che ha chiamato una system call bloccante.
-In un sistema multiprocessore si possono eseguire thread multipli per task
I relativi svantaggi però sono:
-il context swith è più costoso perchè richiede il passaggio al modo kernel
-limitazione nel numero massimo di thread per task

2.b Come si fanno finire tutti i thread attivi di un processo? Il thread padre può  terminare senza che tutti i thread della sua famiglia terminino? Giustificare la risposta. Quale system call consente ad un thread di sincronizzarsi con la terminazione di un suo thread figlio?

Per finire tutti i thread attivi di un processo si utililizza la system call void exit(int status)che termina tutto il task perchè i thread sono allo stesso livello; il padre può terminare anche se i figli non hanno ancora terminato e in questo caso essi, diventati orfani, vengono “adottati” dall'init.
La system call che consente la sincronizzazione tra padre e figlio è la wait() che rappresenta l'unica forma di comunicazione tra figlio e padre.

3. Illustrare la sintassi e la funzione delle System call wait e exit. Cosa succede se un processo padre non chiama wait?

wait() - attende il termine di un processo - pid_t wait (int *status);  
La chiamata di sistema wait() fa si che un processo genitore si blocchi in attesa della terminazione di uno qualunque dei suoi figli, restituendo poi al genitore il PID del processo figlio ed il suo stato di uscita, informandolo sul modo in cui è terminato (regolare oppure anomalo). La wait() provoca inoltre il recupero di tutte le aree di memoria di sistema (descrittori di processo) dedicate al figlio. La funzione wait() sospende il processo corrente finchè un figlio (child) termina o finchè il processo corrente riceve un segnale di terminazione o un segnale che sia gestito da una funzione. Quando un child termina la propria esecuzione senza che il parent abbia atteso la sua terminazione attraverso la chiamata a system call wait(), assume lo stato di "zombie", ossia di processo "defunto".  
Se il processo corrente (padre/parent) esegue la system call wait() mentre uno o più child si trovano in stato di zombie, allora wait() ritorna immediatamente e ciascuna risorsa dei child viene liberata.  
exit() - termina normalmente il programma - void exit(int status);  
La funzione exit() effettua il termine normale del programma, ritornando il valore di status al parent. Essa esegue in sequenza le seguenti operazioni: chiude tutti i file aperti, rilascia la memoria che stava usando, e così via. In particolare sono chiusi i file descriptor, viene memorizzato lo stato di terminazione del processo, i processi figli sono ereditati da init (nella process structure di ogni figlio al pid del processo padre viene assegnato il valore del pid di init (normalmente =1), viene inviato il segnale SIGCHLD al processo padre.
-Tutte le funzioni registrate con le funzioni atexit() e on_exit() sono chiamate nell'ordine inverso alla loro registrazione.
-Tutti gli stream aperti vengono scaricati tramite la funzione della libreria standard fflush().
-Tutti gli stream aperti (compresi stdin, stdout e stderr) vengono chiusi impiegando le funzioni della libreria standard.
-Viene chiamata la funzione _exit().
La funzione exit() non ritorna. Termina l'esecuzione del processo.

3.b Cosa succede se un processo non chiama exit?

La exit() è chiamata comunque in corrispondenza dell'ultima parentesi } incontrata nel codice (non se ne richiede la chiamata esplicita). Può accadere che un processo termini prematuramente (morte del processo) prima di poterla chiamare regolarmente.

3.c Che cosa usa il kernel per indicare al padre che il figlio ha terminato?  


Usa il sistema di segnali caratteristico dei sistemi UNIX: il figlio invia il segnale SIGCHLD al padre.

3.d Si può controllare questo meccanismo? 


Tale meccanismo può essere controllato mediante la gestione (da parte del processo ricevente/padre) del segnale inviato; è necessaria in tal caso una routine di gestione dei segnali (signal handler).

4. Considerare tutte le combinazioni possibili di ordine di chiamata, di assenza di chiamata, e di morte del padre o del figlio.

PADRE CHIAMA WAIT()
La terminazione dei processi figli viene attesa dal parent, per cui quando essi terminano la loro esecuzione vengono liberate tutte le risorse ad essi associate.
PADRE NON CHIAMA WAIT()
La terminazione dei figli NON è attesa dal parent, per cui alla loro terminazione essi diventano zombie (processi defunti, che continuano ad occupare le risorse ad essi assegnate).
FIGLIO TERMINA PRIMA CHE IL PADRE CHIAMI LA WAIT()
Uguale al caso precedente.
MORTE (PREMATURA) DEL PADRE
Terminazione anomala del parent, con exit status !=0. Il padre muore prima di poter eseguire WAIT() (o mentre attende su WAIT()), per cui tutti i suoi processi figli divengono orfani e, per tal motivo, ereditati dal processo init.

5. A che cosa servono le system call: pthread_detach (pthread_self ()) e pthread_mutex_trylock (&mutex)?

int pthread_detach(pthread_self()) è usato per indicare che le risorse di sistema di pthread_self() (che restituisce l'ID del thread chiamante) dovrebbero essere reclamate quando il thread termina. se il thread ha già finito le risorse sono rilasciate immediatamente. Se il thread non è ancora terminato, questa routine non causa la fine del thread. Dopo pthread_detach non è più possibile chiamare pthread_join() sullo stesso thread (infatti entrambe le system call servono a liberare la memoria del thread).
int pthread_mutex_lock(&mutex): Questa funzione imposta lo stato locked del mutex puntato dall'argomento passato. Se lo stato del mutex era unlocked allora viene mutato ma non solo, viene anche fatto si che solo il thread che ne ha settato lo stato come locked possa riportarlo in unlocked.  
Qualora il mutex fosse già stato settato come locked da un altro thread la stessa richiesta, da parte di un secondo thread, viene messa in coda in attesa che il mutex torni ad assumere lo statounlocked. Int pthread_mutex_trylock(&mutex) -> simile alla precedente, permette di evitare il deadlock e di effettuare eventualmente rollback. Questa funzione cerca di entrare nella mutex specificata senza bloccare il thread chiamante. Se il mutex è attualmente bloccato da un altro thread, la chiamata alla pthread_mutex_trylock() restituisce come errore EBUSY.
int pthread_join(pthread_t thread, void **value_ptr): la funzione pthread_join() sospende l’esecuzione del processo chiamante fino alla terminazione del thread thread, a meno che thread non sia già terminato. Se la pthread_join() ha successo e ritorna un ptr non nullo, il valore passato a pthread_exit() dal thread che sta terminando dovrebbe essere disponibile nella locazione referenziata da ptr. Se una pthread_join() ritorna con successo vuol dire che il relative thread è terminato.

5.b Descrivere dettagliatamente che cosa succede, al processore, al processo e al suo stack, al kernel e al suo stack, quando un processo effettua una system call.

La system call è il metodo usato da un processo per richiedere un'azione da parte del kernel. Prima di tutto avviene il salvataggio dello stato del programma utente (PC, registri, bit di modo,IR, segmento di codice del programma utente…, salvati nello stack ). Normalmente la system call è realizzata mediante una trap a un indirizzo specifico nell’interrupt vector. Quindi il controllo passa, attraverso l'interrupt vector, ad una routine di servizio del kernel e il bit mode è settato a monitor mode. Il monitor verifica che i parametri (che vengono passati nei registri, sullo stack o in memoria, i puntatori alle locazioni di memoria vengono passati nei registri) associati siano corretti e legali, esegue la richiesta e restituisce il controllo all'istruzione successiva alla system call.
Si usano tre metodi per il passaggio dei parametri tra un processo e il SO.
-Passaggio di parametri in registri
-attraverso una tabella in memoria per cui l'indirizzo è passato come parametro in un registro
-Push dei parametri in uno stack da parte del programma e pop dello stack da parte del kernel

6. Scrivere  la  soluzione  del  problema  dei  Readers  & Writers  con precedenza ai  Readers mediante  Regioni  Critiche  Condizionali.  Commentare  le  istruzioni  chiave  e  cosa  succede quando un  Writer  termina e ci  sono sia  Readers  che  Writers  accodati  per   l'uso della risorsa comune.

Class RW_precedenza_ai_Readers{
Private
int nr,nw;
char busy;
public:
void start_read(void);
void start_write(viud);
void end_read(void);
void end_write(void);
void(init(void));
}; 

void start_read(void){
nr++;
await(nw==0);
}
void start_write(void){
await(!busy&&nr==0);
nw++;
busy=TRUE;
}
void end_read(void){
nr--;
}
void end_write(void){
busy=FALSE;
nw--;
}
void init(void){
busy=FALSE;
nr=nw=0;}
Visto che la precedenza è data ai Readers se un Writer finisce di scrivere si controlla il contatore nr. Fino a che non è pari a zero un altro Writer non può scrivere di nuovo.

7. In quale condizioni si può avere deadlock a run-time utilizzando le primitive semaforiche per implementare la mutua esclusione. Quale Pthread system call permette di evitare il deadlock e di effettuare eventualmente un rollback?

Sono dovuti agli error time-dependent ossia quando i processi condividono in modo arbitrario delle variabili. Essi possono essere riscontrati solo a run-time dal momento che il compilatore non è in grado di individuarli. Consideriamo la seguente situazione, nella quale a causa di un errore di battitura, la signal(S) del processo P1 sia stata sostituita da una wait(s):
INIT(ME)=1;

(P1)
begin
WAIT(ME)
RC1
WAIT(ME)
End

(P2)
begin
WAIT(ME)
RC2
SIGNAL(ME)
end

Ove RC1 ed RC2 sono le regioni critiche del processo 1 e 2.
In questo schema tutti i processi condividono un semaforo ME inizializzato ad 1. ogni processo prima di accedere alla proprio sezione critica deve effettuare una wait(ME) e dopo esserne uscito una signal(ME). se tale sequenza non è rigidamente rispettata può accadere che due o più processi possano trovarsi contemporaneamente nella sezione critica generando il time-depender error.
Se per esempio P2 giunge per primo alla sezione critica, esso la può  eseguire senza che si presenti alcun problema. Tuttavia il sistema entra in deadlock quando P1, dopo aver eseguito la propria sezione critica effettua la seconda wait(ME); (si blocca perché l semaforo diventa negativo!)
il deadlock si manifesta immediatamente se invece è P1 ad essere eseguito per primo. Quando P2 giunge alla proprio sezione critica non può  far altro che bloccarsi sulla wait(S).
La pthread system call che permette di evitare il deadlock ed eventualmente tornare in uno stato di rollback è la pthread_mutex_trylock(). Questa funzione cerca di entrare nella mutex specificata senza bloccare il thread chiamante. Se il mutex è attualmente bloccato da un altro thread, la chiamata alla pthread_mutex_trylock() restituisce come errore EBUSY.

8. Elencare tutte le situazioni in cui può avvenire un context-switching in un sistema operativo Unix.

Il context-switching può  avvenire perchè arriva un interrupt, perché  è finito il quanto di tempo a disposizione del processo o perché è richiesta un’operazione di I/O(ossia una trap fatta da un supervisor call);

9. Spiegare la differenza tra chiamata a funzione e chiamata a System call. Qual è la funzione delle System call fork, wait e exit? Dettagliare.

La system call è il metodo usato da un processo per richiede un’azione da parte del kernel. fornisce l’interfaccia tra un programma in esecuzione e il SO.. E’ generalmente disponibili come istruzione assembler. Quindi a differenza della CHIAMATA A FUNZIONE dove il processo rimane in user mode, nella SYSTEM CALL il kernel prende il controllo. La fork() crea una copia identica del processo che l’ha invocata(padre) facendo sì che questo abbia esattamente la stessa immagine in memoria, inclusi i descrittore di file, lo stack , i dati, ecc. Dopo la fork() il processo padre ed il processo figlio possono intraprendere due percorsi di esecuzione completamente indipendenti, senza che i cambiamenti delle variabili dell’uno si ripercuotano su quelle dell’altro. La fork() restituisce il valore 0 al figlio ed il process identifier(pid) del figlio al processo padre facendo sì che i due processi possano riconoscere sé stessi. La chiamata di sistema wait() fa si che un processo genitori si blocchi in attesa della terminazione di uno qualunque dei suoi figli, restituendo poi al genitore il pid del processo figlio ed il suo stato di uscita informandolo sul modo in cui è terminato. Esso provoca inoltre il recupero di tutte le aree di memoria di sistema dedicate al processo figlio. Il processo figlio termina la proprio esecuzione mediante la chiamata di sistema exit() che svolge due compiti molto importanti: rilascia tutte le risorse di sistema che il processo deteneva(memoria,file); restituisce il pid e lo stato di uscita del figlio al genitore, che questi catturerà  attraverso la chiamata di sistema wait. Exit fa terminare il processo perché causa una transizione prima nello stato running in modo kernel e poi in zombie.

10. Come si realizza della mutua esclusione su sistemi multiprocessore? E in quelli monoprocessore?

Nel caso di sistema monoprocessore viene realizzato sfruttando il meccanismo di interrupt: mentre si è nella regione critica gli interrupt vengono disabilitati. In questo modo lo schedulatore del sistema non può intervenire e quindi nessun processo può essere attivato. Nei sistemi multiprocessore con memoria comune non è possibile disabilitare gli interrupt su tutti gli altri processori. L’istruzione Test & Set in un unico ciclo macchina, quindi senza la possibilità di essere interrotta, permette di testare il valore di un bit e successivamente di settarlo a 1. Per cui è ora possibile creare una primitiva atomica con la quale proteggere una sezione critica. Le operazioni sono: valutazione del valore del bit di lock S, test sul valore originale di S: se è 1 si torna al primo passo, se è 0 si prosegue.


blog comments powered by Disqus
 

http://sartomiki.net/modules/mod_fuofb/assets/it/find-us-on-facebook-1.png

Follow me

Amici

Chi è online

 5 visitatori online

Siti amici

Banner

Notizie flash

Il mese di maggio 2010 abbiamo segnato il nuovo record di visite mensili: 3000!

Grazie a tutti! Continuate a visitare sartomiki.net

PUBBLICITA'