vuoi
o PayPal
tutte le volte che vuoi
SEGMENTAZIONE: prende i processi e li divide in unità funzionali.
sono molto differenti tra di loro;
se ogni programma dovesse gestire esattamente le istruzioni di input e output di
ognuna delle periferiche uscirebbero programmi lunghissimi e non è fattibile, allora
si creano i drivers che “mascherano” quello che c’è dall’altra parte delle
periferiche mettendo a disposizione dei programmi del sistema operativo che
sono standardizzati, rendendo le periferiche tutte uguali.
Con questi 3 avremmo un sistema operativo fatto e finito.
= come metto/ strutturo i file all’interno dell’hard disk e di che tipo sono
Vengono inclusi in directory (= cartelle), sono organizzati ad albero
Gerarchia: user, windows, programmi, …
Se si corrompe è un problema perché non sappiamo più dove sono i file
Definisce anche il livello di protezione delle cartelle, chi può accedervi per
modificarle o leggere.
permette all’utente di interagire con il pc;
possono aere interfaccia testuale (server) o grafica (pc);
permette di eseguire comandi, fare operazioni con periferiche, configurare il
sistema operativo e interagire col file system.
Sistema operativo multi-programmato, esegue più processi
contemporaneamente;
Un processo non è un programma, ma vengono generati durante l’esecuzione di
un programma;
è composto da: istruzioni (codice eseguibile), dati dell’esecuzione del programma
e informazioni sullo stato del processo;
processo entità dinamica
→
programma entità statica
→
se abbiamo tanti processi abbiamo bisogno di specularli (round-Robin)
i processi posso essere eseguiti in 2 modalità:
Kernel mode: decide quale istruzione eseguire, ha controllo completo delle
- periferiche e della memoria (di solito è uno)
User mode: alcune cose posso farle, altre devo aspettare l’ok o la fine di altri
- processi già in corso
Il so viene eseguito in modalità privilegiata così da avere processi per controllare
altri processi in modalità user,
i processi utente devono invocare il supervisor del sistema operativo tramite la
system call per eseguire operazioni privilegiate come accesso ai file (ci accedo
solo io), accesso alle periferiche, operazioni di input e output.
Lo stato del processo può essere:
interno: proprio di ognuno dei processi, a che punto sono arrivato nel
- programma, tutti i dati delle variabili e dei registri utilizzati
esterno: come il processo viene letto dal sistema operativo, informazioni
- generiche, cosa sta facendo ora il processo perché può essere:
1) in esecuzione
2) pronto (in attesa di accedere alla cpu appena si libera)
3) in attesa (il programma non può andare avanti perché ha bisogno di
qualcosa per proseguire)
quando un processo è in esecuzione possono succedere 3
cose: se gli serve un input esterno durante l’esecuzione
- andrà in stato di attesa
se il sistema operativo blocca il processo per
- eseguirne altri, non eseguirà più istruzioni e andrà in
stato di pronto
se finisce le istruzioni da eseguire, terminerà il
- programma
quando un processo è pronto può succedere solo che il sistema operativo
acconsente all’eseguimento delle istruzioni e quindi andrà in esecuzione.
quando un processo è in attesa, appena ottiene l’input andrà in stato di pronto
non in esecuzione perché nel frattempo sta andando già un altro programma.
“first in, first out” = primo che arriva è il primo a essere servito
Metto in ordine i processi, appena arrivano li metto in coda e inizio a eseguire il
primo, alcuni processi possono essere veloci ma siccome sono arrivati dopo
devono aspettare gli altri davanti che magari sono più lunghi→ non molto
efficiente
Va bene solo nel calcolo scientifico perché i processi hanno tutti lo stesso tempo
di esecuzione
sarebbe meglio ordinarli per durata così riesco a minimizzare i tempi di attesa
possibili, ma a priori non so quanto duri l’esecuzione di ogni programma e quindi
organizzo lo scheduling con il Round-Robin.
Round-Robin = suddivido il programma in quanti di tempo, quando eseguo faccio
prima un programma per un quanto di tempo, poi mi sposto su un altro
programma e finché non li ho eseguiti tutti almeno una volta non torno al
programma inziale.
In questo modo il problema dei tempi di attesa si riduce, non lo risolvo
completamente.
Se un processo termina, continuo l’esecuzione sui processi che rimangono.
Ho p1 e p2, il kernel esegue p1 per 1 quanto di tempo e poi va in stato di attesa
perché si verifica un’interruzione interna, posso quindi eseguire p2 fin quando non
termina 1 quanto di tempo e torna in stato di pronto.
Non appena p1 esce dallo stato di attesa, torna anche lui in pronto e si ricomincia
il Round-Robin finché i processi non terminano o ci sono altre interruzioni interne.
Se il quanto di tempo fosse infinitamente piccolo, non avrei tempo abbastanza tra
un processo e l’altro per salvare i dati,
Context switch = spostare il processo dall’esecuzione perché è finito il quanto di
tempo (preemption) richiede tempo per salvare lo stato interno del processo
quindi ne devo tenere conto quando decido la lunghezza del quanto.
Il Round-Robin è un metodo
standard semplice, in Linux c’è
anche una priorità (come al
pronto soccorso) e quindi può
essere diverso a seconda del
sistema operativo.
è un modello lineare, è una sequenza di celle numerate identificate da un
indirizzo, se ci fosse un solo processo, questo può usare tutta la memoria, mentre se
ci sono più processi in corso, va suddivisa.
Abbiamo bisogno di almeno un indirizzo per ogni cella quindi non posso cerare
una memoria troppo grande (se gli indirizzi sono lunghi N bit, lo spazio di
indirizzamento è M = celle) tutte le celle devono essere indirizzabili
→
2 Normalmente ci riferiamo a celle o altre istruzioni andando
a prendere in considerazione un indirizzo di quella cella o
di quell’ istruzione che però è puntato rispetto all’ inizio del
programma;
Se ci sono altri programmi, può essere che il nostro
processo non sia all’inizio, abbiamo bisogno di un mapping
tra la cella definita all’interno del processo e quello che
farà realmente il processore;
quando il programma viene eseguito, viene caricato nella
memoria fisica.
Dobbiamo tenerci da parte le info di dove abbiamo messo
il nostro programma (= registro base) così da riuscire a
leggere esattamente l’informazione che mi serve.
È possibile che la memoria fisica si frammenti perché i processi non vengono
eseguiti nello stesso arco di tempo e quindi restano nella memoria per durate
differenti, non sarà molto ordinata.
Per evitarlo (rilocazione non va bene), divido un processo in tante pagine (= pezzi
di istruzioni lunghi uguali)
Ho un riferimento tra il programma in parti e la loro posizione, non so dove inizia
l’intero programma ma dove solo collocate le pagine nella memoria.
Ottengo 2 tipi di memoria:
memoria virtuale: è costituita dall’insieme delle pagine virtuali di lunghezza
- fissa che dividono un singolo programma
memoria fisica: è sempre la main memory divisa in pagine fisiche della
- stessa dimensione
se due programmi hanno delle pagine esattamente uguali, le metto in memoria
una volta ma specifico che appartengono a entrambi.
La memory management unit (mmU) gestisce le associazioni tra pagine virtuali e
pagine fisiche, traduce le richieste di celle di acceso alla memoria prima di
passare alla main memory, è una memoria associativa particolarmente veloce.
Pagine della stessa lunghezza è grande vantaggio, devo far coincidere inizio
pagina virtuale con inizio pagina fisica e le metto alla stessa “altezza”,
indirizzo virtuale/fisico diviso in:
numero di pagina virtuale/fisica (npv/npf)
- spiazzamento (offset) = valore che una cella ha
- all’interno della pagina assume stessi valori in
→
entrambe le pagine perché hanno la stessa
dimensione
come faccio a tradurre un indirizzo virtuale in un
indirizzo fisico?
So la posizione di ognuna delle pagine virtuali, ogni volta che trovo la pagina
virtuale corrispondente nella memoria fisica, posso spostarmi esattamente
dell’offset.
La paginazione è il meccanismo più semplice tradurre da virtuale a fisico, è
comodo fare una tabella che indica la corrispondenza tra le due pagine
inserendo anche solo quelle che uso di più
Come faccio se ho la memoria fisica piena ma voglio eseguire altri programmi?
Il sistema operativo va a vedere le pagine all’interno della memoria meno
utilizzate, le salva da un’altra parte e libera lo spazio, continuando il ciclo di switch,
Questo processo rallenta molto il pc perché deve leggere l’hard disk.
Le pagine che ci sono sulla memoria si chiamano pagine residenti, se un processo
ha bisogno di una pagina che non c’è nella ram ho un errore di page-fault.
la ram costa di più dell’hard disk perché ci mette di meno a prelevare informazioni
gerarchia della memoria: utilizzo diversi livelli di memoria, con tecnologie diverse in
modo da ottenere un buon compromesso costo/prestazioni
in ordine:
località temporale: più uso un dato, più lo tengo in alto, più è facilmente e
- velocemente reperibile
località spaziale: più uso un dato, quelli che ci sono attorno verranno
- sicuramente usati e allora li tengo in alto, una volta usati li sostituisco
il processore se trova qualcosa all’interno di un certo livello lo usa e continua a
utilizzarlo, se in quel caso non ci fosse, va a un altro livello della gerarchia
rallentando tutto, e una volta trovato lo porta in alto
se faccio le gerarchie di memoria in alto troppo piccole, il processore andrà più
spesso a guardare gli altri blocchi e non mi conviene, se lo allargo sarà tutto più
veloce il pc costa ovviamente di più
→
tempo medio di accesso ai dati:
hit rate (tasso di successo) = probabilità che il dato ci sia realmente nel
- livello più alto
hit time (tempo di successo) = tempo effettivo che impiegherei per
- accedere al dato nel livello più alto
se il dato è nel livello più alto, ci impiego hit rate
se il dato non è nel livello più alto, ci impiego più tempo
non avvengono con la stessa probabilità ma dipende dalla grandezza della
memoria veloce (tradotto poi in hit rate).
Miss penalty (te