sistema operativo v2014 -...

50
Il sistema operativo

Transcript of sistema operativo v2014 -...

Page 1: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Il sistema operativo

Page 2: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Il sistema operativo

Pag. 1- 50

Indice Classificazione dal punto di vista dell'utente ..............................................................................................................................................3

Sistemi dedicati.......................................................................................................................................................................................................................3 Sistemi batch...........................................................................................................................................................................................................................4 Sistemi interattivi multiutente .............................................................................................................................................................................................7 Sistemi transazionali ..............................................................................................................................................................................................................8 Sistemi real time .....................................................................................................................................................................................................................8

Classificazione dei sistemi operativi monoprogrammati e multiprogrammati .................................................................................. 10 Sistemi multiprogrammati - interattivi ...................................................................................................................................................... 14

I processi .............................................................................................................................................................................................................................. 14 I processi rientranti ......................................................................................................................................................................................................................... 15

Le interruzioni ..................................................................................................................................................................................................................... 16 Il modello a macchine virtuali .................................................................................................................................................................... 19

Moduli e primitive .............................................................................................................................................................................................................. 20 I device driver...................................................................................................................................................................................................................... 22 Sistemi operativi aperti vs sistemi operativi proprietari .............................................................................................................................................. 24 Il nucleo................................................................................................................................................................................................................................ 25

Lo schedulatore dei lavori .............................................................................................................................................................................................................. 25 Politiche di schedulazione dei lavori ............................................................................................................................................................................................. 26 Schedulatore dei processi ............................................................................................................................................................................................................... 26 Politiche di schedulazione dei processi ......................................................................................................................................................................................... 26 Il controllore del traffico ................................................................................................................................................................................................................ 28 La sincronizzazione tra i processi.................................................................................................................................................................................................. 28 Interferenza e cooperazione tra i processi.................................................................................................................................................................................... 29 I semafori binari e la primitiva TEST AND SET ....................................................................................................................................................................... 29 Le primitive WAIT e SIGNAL ..................................................................................................................................................................................................... 30 I semafori a contatore e le primitive P e V................................................................................................................................................................................... 30 Il problema del produttore del consumatore ............................................................................................................................................................................... 31 Sincronizzazione attraverso i messaggi ......................................................................................................................................................................................... 32 Lo stallo ............................................................................................................................................................................................................................................ 32

La gestione della memoria .......................................................................................................................................................................... 33 Gestione della memoria a partizioni fisse ...................................................................................................................................................................... 33 Gestione della memoria a partizioni variabili................................................................................................................................................................ 34 Tecniche di overlay: paginazione e segmentazione...................................................................................................................................................... 35

Paginazione ...................................................................................................................................................................................................................................... 36 Segmentazione................................................................................................................................................................................................................................. 37 Segmentazione con paginazione dinamica ................................................................................................................................................................................... 39

Le periferiche ................................................................................................................................................................................................ 39 Dispositivi hardware .......................................................................................................................................................................................................... 39 Il gestore delle periferiche................................................................................................................................................................................................. 41 Come ottimizzare la gestione delle periferiche ............................................................................................................................................................. 42

Periferiche indipendenti.................................................................................................................................................................................................................. 43 Periferiche bufferizzate................................................................................................................................................................................................................... 43 Tecniche di allocazione a periferiche virtuali ............................................................................................................................................................................... 43

Il file system................................................................................................................................................................................................... 44 L'interprete di comandi ............................................................................................................................................................................... 47 Processi padre e processi figlio .................................................................................................................................................................. 48 I software di sistema .................................................................................................................................................................................... 49

Bibliografia • I sistemi operativi reti e internet il sistema informativo aziendale - A.Lorenzi e aa.vv. - Atlas • Complementi di informatica – A.Garavaglia – F.Petracchi – Parte II - Masson • Introduzione all’Informatica – P.Tosoratti – Casa Editrice Ambrosiana • Elaboratori e loro applicazioni – Volume 3 – F.Cesarini – F.Pippolini – G-Soda – Edizioni Cremonese • Corso di Informatica – Volume 3 – R.P.Dameri – G.Foresti – Editrice Jackson • www.wikipedia.it

Page 3: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Il sistema operativo

Pag. 2- 50

Introduzione Se si sfogliano vecchie annate di riviste di informatica, viene da sorridere pensando alle risorse disponibili sul mercato commerciale solo dieci anni fa.

In effetti lo sviluppo tecnologico ha compiuto in tempi brevissimi passi tali da consentire miglioramenti enormi nella produzione dei dispositivi elettronici.

Questo sviluppo ha richiesto e richiede grandi investimenti, ampiamente ripagati dal successo commerciale che premia chi riesce a produrre per primo un processore più potente, un disco più grande o dei chip di memoria più veloci. Nuovi dispositivi sono comparsi sul mercato e altri ne sono scomparsi.

Un effetto ben visibile è che oggi è possibile per molti utenti privati e piccole aziende avere accesso a grandi capacità di calcolo, impensabili fino a pochi anni fa, a costi molto ridotti.

Aumenta così in misura sempre maggiore il numero di persone che usano un computer per i motivi più disparati, per lavoro e per svago, con finalità artistiche o di profitto.

Il mercato del computer si è popolato di molti clienti, e potenziali clienti, privi di conoscenze tecniche approfondite, che richiedono programmi user friendly, cioè facili da usare.

Per l'utenza privata questa è una necessità che i produttori non possono trascurare, perché il cliente che adopera il computer a casa desidera poterlo fare senza dover ricorrere a consulenze per ogni problema che gli si possa presentare.

Per l'utenza aziendale, la facilità d'uso è comunque una qualità dei programmi molto desiderabile, che consente di diminuire il costo dell'addestramento dei dipendenti.

Di conseguenza, i produttori di software investono in ricerche sociologiche e psicologiche per sapere come confezionare i propri programmi e come rendere disponibili le risorse all'utente

finale, in modo da garantirsi un vantaggio competitivo sui concorrenti.

Per comprendere come sia importante poter accedere in modo semplice alle risorse informatiche, si pensi che la rete delle reti, Internet1, esiste da molti anni, ma il suo uso è stato a lungo confinato ad un ristretto numero di specialisti in grado di usare programmi con pochissime funzioni, mentre il suo successo commerciale è iniziato quando si sono diffusi i primi Web browser, strumenti grafici che permettono di reperire in modo facile le informazioni sulla rete, fatte di immagini e documenti multimediali, filmati e audio. Navigare su Internet è un'attività svolta con profitto da molte persone, anche grazie alla trasformazione degli strumenti a disposizione per la consultazione.

Si è quindi assistito ad un veloce incremento delle prestazioni dei dispositivi con contenimento o addirittura diminuzione dei costi: tanto i produttori di microprocessori che quelli di unità periferiche hanno migliorato, e continuano a migliorare, la tecnologia usata, rendendo disponibili, a prezzi accettabili, più velocità di elaborazione e più spazio dove immagazzinare dati.

L'aumento di prestazioni permette di dedicare molte risorse ai programmi che sovrintendono al funzionamento dei sistemi di calcolo, contribuendo a renderli più versatili. La potenza di calcolo disponibile viene in parte adoperata per gestire automaticamente le attività di manutenzione del sistema o per eseguire i programmi che non richiedono l'intervento dell'utente.

1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Page 4: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 3 - 50

Se il sistema è sufficientemente potente, l'utente non si accorgerà neppure di quante attività il computer svolga contemporaneamente, molte delle quali in modo del tutto invisibile.

Per esempio mentre si scrive un testo usando un programma che corregge automaticamente gli errori di battitura nel momento in cui si verificano, sullo stesso computer, attraverso Internet, si possono memorizzare dati e programmi, e sempre nello stesso tempo dal lettore di CD proviene musica e un orologio digitale scandisce i secondi.

In altre parole, dove non è richiesto di sfruttare la piena potenza dell'elaboratore, parte della capacità di calcolo viene impiegata per rendere le attività più gradevoli e facili per l'utente.

Le prestazioni migliorate delle nuove macchine consentono naturalmente di potenziare i vecchi programmi, aggiungendo nuove routine che: • ne permettano un uso più semplice, per esempio fornendo strumenti visivi che eseguono automaticamente

procedure complesse; • ne estendano l'applicabilità, permettendo di usare lo stesso programma per intervenire su diverse fonti di

dati; • forniscano nuovi strumenti di manipolazione dei dati.

A proposito di quest'ultimo punto, lavorando con programmi di manipolazione delle immagini oggi si possono eseguire algoritmi complessi (calcolo delle ombre, distribuzione della luminosità) in tempi ragionevoli. Gli stessi algoritmi, nel recente passato, venivano sviluppati su macchine quasi costruite appositamente.

Migliorare i vecchi programmi costa tanto meno quanto più questi sono predisposti ad accogliere le modifiche: in particolare, quanto più rigorosamente sono scritti usando i concetti e le regole della programmazione strutturata.

In un programma ben strutturato, infatti, i punti da modificare sono più facilmente localizzabili, così come le posizioni dove si devono inserire le chiamate delle nuove procedure o funzioni.

Queste considerazioni permettono di inquadrare correttamente la trattazione che riguarda i sistemi operativi. Il sistema operativo (in inglese operating system) è un programma, o meglio, un insieme di programmi, scritto allo scopo di rendere disponibili all'uso le risorse di calcolo e i dispositivi collegati al computer.

Si può pensare a questi programmi come all'insieme degli impiegati di un'azienda, ciascuno dei quali ha compiti specifici da svolgere, e tutti insieme lavorano per raggiungere gli obiettivi aziendali specificati dalla direzione e propagati attraverso i vari livelli dell'organizzazione. Nello stesso modo, quando un utente interagisce col computer, vengono emanate richieste di risorse che raggiungono l'hardware dopo essere state interpretate da vari programmi organizzati in modo gerarchico.

Il sistema operativo racchiude alcuni di questi livelli di organizzazione, e rende disponibile il computer per l'esecuzione di azioni complesse.

Classificazione dal punto di vista dell'utente

Le tre configurazioni fondamentali con le quali un sistema viene offerto agli utenti sono: sistema dedicato, sistema batch (a lotti), sistema interattivo multiutente. Classificazioni più specifiche comprendono di solito anche i sistemi transazionali e i sistemi real time.

Sistemi dedicati

I sistemi dedicati sono i sistemi che prevedono l'utilizzo da parte di un solo utente per volta. In questa categoria rientrano i personal computer e le workstation usate nel progetto architettonico o ingegneristico e nell'ambito della ricerca scientifica.

I sistemi dedicati attuali supportano il multitasking che è un tipo particolare di multiprogrammazione nella quale più applicazioni (task) vengono eseguite contemporaneamente sulla stessa macchina scambiando tra loro dati e risultati. Questi elaboratori funzionano tipicamente con i sistemi operativi Windows, Linux e Mac OS.

Esistono poi i sistemi operativi che utilizzano il meccanismo di multithreading, che rispetto al multitasking usano meccanismi di protezione tra i programmi, più evoluti e sicuri, tipici dei sistemi di livello superiore: un processo, un lavoro, una transazione o un task possono essere scomposti in parti più piccole parallelizzabili, chiamate thread, che procedono indipendentemente, condividendo lo spazio di indirizzamento in memoria centrale e sincronizzandosi solo quando occorre.

Page 5: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 4 - 50

All'occorrenza, queste macchine vengono fatte funzionare in monoprogrammazione con sistemi operativi più semplici: questo può essere necessario per far funzionare programmi particolari che verrebbero appesantiti negli ambienti multitasking. Nei sistemi dedicati e multitasking spesso si fa ricorso ad ambienti grafici a finestre, nei quali le varie applicazioni possiedono un'interfaccia utente che occupa una parte delimitata dello schermo. Tali sistemi sono quindi dotati di un’interfaccia di tipo GUI (Graphical user interface).

In questo modo si possono vedere contemporaneamente diverse applicazioni in esecuzione e si può passare dall'una all'altra, secondo la necessità, usando il mouse o la tastiera. Il sistema operativo, in questi casi, dispone di librerie a collegamento dinamico (DLL, Dynamic Link Library) che contengono procedure e funzioni condivise da diverse applicazioni.

Per esempio, quando si desidera salvare un testo scritto con un word processor, si apre una finestra di dialogo che permette di scegliere dove salvare il file e con quale nome oppure anche di annullare l'operazione. La stessa finestra può essere usata da qualsiasi altra applicazione che abbia la stessa necessità di salvare un file: perciò è opportuno che il codice necessario possa essere condiviso dalle diverse applicazioni, in modo da avere un comportamento uniforme.

Questo si ottiene ponendo il codice in un modulo di sistema che viene caricato in memoria la prima volta che un programma qualsiasi lo richiede. Se un altro programma fa la stessa richiesta in un tempo successivo, il modulo è già presente in memoria e la richiesta viene soddisfatta senza bisogno di ricaricarlo (vedi processi rientranti).

I moduli costituiti dalle librerie dinamiche contengono di norma una serie di primitive omogenee per tipologia, per esempio nel caso del sistema operativo Windows si ha una libreria contenente tutte le finestre di dialogo destinate a segnalare errori o messaggi all'utente, o necessarie per eseguire procedure standard di sistema come scegliere i caratteri, stampare un documento, caricarlo da disco o salvarlo. Si ha poi una libreria per la gestione dei dispositivi multimediali e molte altre. (vedi moduli e primitive)

In un dato istante, la memoria centrale contiene perciò codice proveniente da programmi applicativi, dalle librerie dinamiche e dai moduli di livello più profondo del sistema operativo, ottenendo uno sfruttamento estremamente intenso delle risorse disponibili. È possibile per esempio eseguire attività in background (in sottofondo): un programma che visualizzi l'ora, un programma antivirus o anche un trasferimento di dati attraverso la linea del telefono, oppure copie o ricerche di file.

Sistemi batch

In un sistema tipo batch (a lotti di lavoro), l'utente non interagisce con il computer durante l'esecuzione dei programmi. Al contrario, occorre preparare prima di tutto il lavoro da svolgere, e al termine si ottiene il risultato. Il lavoro batch può quindi essere considerato l'opposto di interattività, intendendo con questo termine la possibilità di fornire i dati che servono al momento della richiesta, di ottenere risultati parziali durante l'esecuzione oppure messaggi di avvertimento o di errore.

L'impiego batch delle risorse presenta evidenti svantaggi, ma permette anche uno sfruttamento

intelligente delle risorse in quei casi in cui l'intervento dell'operatore non è strettamente necessario.

Per esempio l'estrazione e la stampa dei dati di fatturazione di un'azienda richiede l'intervento dell'impiegato solo all'inizio, quando deve impostare le condizioni ed i parametri relativi alla stampa richiesta. Assegnati tali parametri, come l'intervallo di date da analizzare e le specifiche dei clienti o degli articoli, i programmi possono lavorare fino alla produzione della stampa senza bisogno di altri interventi, quindi l'operatore umano è disponibile per svolgere altre mansioni.

Page 6: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 5 - 50

Siccome l'attività della CPU è limitata principalmente dai tempi di attesa per le operazioni di I/O, durante i quali l'unità centrale è forzatamente inattiva, una riduzione di questi tempi aumenta l'efficienza del sistema. I tempi di inattività sono dovuti sia alla lentezza dei dispositivi meccanici rispetto a quelli elettronici, sia al ritardo con cui l'utente soddisfa alle richieste di input del programma.

Per esempio nei primi computer dell'informatica moderna la metodologia batch prevedeva che l'utente preparasse in anticipo tutto il proprio lavoro su dispositivi che non facevano parte del sistema di calcolo, come nastri o schede perforate, fornendo fin dall'inizio tutti i dati ed i comandi necessari per l'elaborazione. In pratica l'utente perdeva la possibilità di interagire con la macchina durante l'esecuzione dei programmi. Il blocco di schede veniva letto da appositi dispositivi ottici o meccanici ed il suo contenuto veniva copiato sui dispositivi di memoria di massa.

Il tempo di attesa della CPU durante le operazioni di ingresso viene cosi ridotto automaticamente, in quanto tutto l'input è disponibile su dispositivi relativamente veloci quali le unità a disco. Il tempo di attesa per l'output viene analogamente diminuito eseguendo le operazioni di uscita non verso le stampanti ma ancora verso le memorie di massa. Il tempo necessario a generare l'output su tali dispositivi è più basso sia perché le operazioni di scrittura sono più veloci, sia perché i dischi non sono soggetti ad interruzioni dovute a cause meccaniche, frequenti invece sulle stampanti (fine della carta o strappi). Una volta che il lavoro richiesto dall'utente è terminato, tutto l'output sta su disco ed occorre eseguirne la stampa. Questa operazione non deve però coinvolgere in alcun modo la CPU, che può cosi dedicarsi alle successive elaborazioni. Il dispositivo che si preoccupa del trasferimento dell'output si chiama elaboratore di canale.

Gli elaboratori di canale possono essere associati a qualsiasi periferica e sono costituiti da un'area di memoria detta buffer (memoria temporanea), nella quale si accumulano i caratteri da trasferire, e da un dispositivo logico che ne controlla il flusso dalla sorgente al buffer e da questo alla destinazione, risolvendo il problema della sincronizzazione dei due dispositivi (sorgente e destinazione) che in generale sono in grado di fornire e ricevere caratteri a velocità tra loro diverse.

Se l'elaboratore di canale è associato ad un videoterminale esso può anche provvedere a generare l'eco dei tasti digitati sullo schermo.

Quindi nei sistemi batch l'utente deve impostare tutti i dati del programma in anticipo: in un sistema moderno questo può essere fatto in modo interattivo attraverso il riempimento di maschere su videoterminale che presentano tutte le richieste del programma.

Occorre perciò disporre fin dall'inizio del lavoro di tutti i dati che verranno richiesti dai diversi programmi da eseguire ed inoltre non si può contare su output parziali nel corso dell'esecuzione. Questo non rappresenta una limitazione rilevante nel calcolo di tipo scientifico, statistico o matematico, mentre è più problematico per alcune applicazioni di tipo gestionale: per esempio, una procedura di fatturazione deve fornire all'operatore una serie di informazioni durante l'immissione dei dati, in modo che eventuali anomalie possano essere risolte senza dover aspettare a lungo. Se il cliente al quale si fattura ha dei pagamenti insoluti in atto, è utile che l'operatore lo sappia prima di chiudere l'operazione, cosi da poter chiedere direttive ai propri superiori.

L'ambiente batch non è adatto e non si presta ad una serie di attività informatiche comuni nel lavoro di ufficio, come l'elaborazione di testi o alcuni tipi di analisi dei dati che meglio si effettuano usando fogli di calcolo. Queste attività vengono svolte in maniera appropriata se l'utente è in grado di interagire continuamente con i programmi e modifica le proprie scelte nel corso dell'esecuzione in modo non facilmente descrivibile a priori, come invece richiede l'elaborazione batch.

Lo stesso discorso può valere per altri tipi di applicazione, come per esempio lo sportello bancario: l'impiegato interagisce continuamente con il programma fornendo in input le richieste di servizi (pagamenti, riscossioni, aperture di conto) e ricevendo rapidamente in output le risposte (tipicamente la stampa della contabile dell'operazione o alcune informazioni a video).

Il fatto che le applicazioni interattive siano molto richieste e addirittura irrinunciabili nell'ambito dell'ufficio, spiega perché oggi sia difficile trovare un sistema che funzioni solo in modalità batch. Essa viene comunque supportata ed usata ampiamente anche nei sistemi operativi moderni laddove si vogliono eseguire lavori che non richiedono l'intervento dell'operatore, cioè lavori che devono essere eseguiti

Page 7: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 6 - 50

sempre con gli stessi comandi e sempre nello stesso ordine, spesso anche in orari prefissati, per esempio al termine della giornata lavorativa.2

Il nome tecnico con il quale viene indicata una sequenza di fasi da eseguire in modo batch è job stream (flusso del lavoro). Alternativamente, la sequenza dei comandi può essere memorizzata su un file, scritto usando un video e una tastiera.

Questo file viene già a trovarsi su disco e l'esecuzione dei comandi in esso contenuti può essere richiesta con un singolo comando, impartito ancora attraverso una tastiera. Con questo comando si può specificare: • il nome del file contenente il job stream; • il nome dell'utente al quale addebitare l'esecuzione; • la periferica di uscita verso la quale va indirizzato l'output; • eventualmente l'ora alla quale far mettere in coda il lavoro perché venga eseguito. Per esempio, alle 17 si

può richiedere che il lavoro venga svolto partendo dalle 23, perché l'uso del sistema è meno costoso, oppure le periferiche di uscita sono meno richieste.

Quando il job stream è pronto, esso viene preso in carico dall'opportuno elaboratore di canale che provvede a metterlo in linea sui dispositivi di memoria di massa e a caricarlo in una coda sotto il controllo del sistema operativo per la sua effettiva elaborazione. La gestione della coda è compito del sistema operativo, secondo le politiche che lo caratterizzano, con o senza l'uso di priorità.

Al termine dell’esecuzione del job, il sistema operativo deve riconoscere che l'output generato è stampabile, e quindi porlo in una coda di stampa, associata all'elaboratore di canale corrispondente all'unità di uscita richiesta dall'utente, aggiungendo informazioni sulle risorse impiegate e gli addebiti.

Rispetto ai sistemi operativi per elaboratori dedicati, quelli che lavorano in ambienti batch devono perciò avere in più i moduli che: • gestiscono le code di lavori in ingresso e le code di stampa; • provvedono alla protezione reciproca degli utenti; • realizzano i meccanismi di assegnazione delle risorse.

Oggi i sistemi batch non esistono più ma il termine batch viene usato in modo più esteso di quello qui presentato, per indicare un qualsiasi insieme di programmi da eseguire uno dopo l'altro mentre la modalità di lavoro è rimasta nei file batch (.bat), utili soprattutto per operazioni sempre uguali e che non richiedono l'interazione con l'utente.

Per esempio, nel sistema operativo DOS è possibile scrivere file di testo chiamati script (o file batch) contenenti sequenze di comandi e chiederne l'esecuzione. Occorre che il file abbia l'estensione BAT e l'esecuzione del job stream è ottenuta digitando il nome del file stesso. Questo è comodo quando si devono eseguire spesso sequenze di comandi sempre uguali oppure quando si vuole far eseguire un insieme complicato di comandi ad un utente non esperto.

Un esempio tipico è quello del file Autoexec.bat, che contiene la sequenza dei comandi da eseguire all'accensione del computer, come la connessione alla rete, il caricamento dei programmi che gestiscono il mouse e la tastiera e in generale tutto ciò che l'utente desidera eseguire all'accensione senza doverlo digitare tutte le volte.

Vediamo qui di seguito un semplice esempio di file Autoexec.bat: Path = c:\dos rem able DOS to check programs and external command in DOS directory Keyb US Prompt $p$g set temp = c:\temp LH c:\dos\doskey/insert

2 Nei vecchi sistemi batch le fasi del lavoro erano: preparazione dei dati, inoltro all'elaboratore e ritiro dei risultati. I diversi utenti preparavano i propri job (lavori) su dispositivi offline (non connessi all'elaboratore) il cui uso costava poco rispetto a quello della macchina: potevano essere perforatori di schede o nastri o anche micro e personal computer dotati di editore di testi o word processor. Opportune periferiche provvedevano a portare online (in linea, pronti per l'elaborazione) i job: queste potevano essere lettori di dischi o nastri perforati o unità a dischi mobili o a nastri magnetici.

Page 8: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 7 - 50

Il file autoexec.bat indica che la directory è c:\DOS, i file temporanei vengono trasferiti nella cartella c:\temp, il prompt viene mostrato nella forma drive: directory. Viene anche caricata nella parte alta della memoria l’utility doskey con l’opzione per l’inserimento.

Sistemi interattivi multiutente

Con i sistemi batch si riesce a migliorare l'efficienza con la quale vengono impiegate le risorse, sostanzialmente realizzando un parallelismo tra le operazioni dei diversi dispositivi: mentre la CPU elabora, altri dispositivi eseguono operazioni accessorie come il trasferimento dei dati.

Questo aumento di efficienza viene pagato dagli utenti con la perdita dell'interattività, cioè della possibilità di colloquiare con i programmi durante la loro esecuzione, fornendo dati in ingresso e acquisendo risultati parziali o messaggi di errore nel momento in cui vengono determinati.

È possibile recuperare questa qualità a patto di accettare nuove complicazioni nel sistema operativo e un aumento del tempo dedicato all'esecuzione delle sue routine, pur mantenendo un'ottima efficienza.

L'obiettivo da raggiungere consiste nel mettere a disposizione di ciascun operatore una periferica interattiva come il video, attraverso la quale si possano usare le risorse del sistema in modo simile a quello di un sistema dedicato.

Il mezzo che consente di raggiungere tale obiettivo è l'uso time sharing della CPU: la risorsa CPU viene dedicata a ciascun utente a turno per un tempo stabilito. Se le commutazioni tra utenti sono abbastanza frequenti, ognuno ha la sensazione di lavorare su una macchina dedicata.

La velocità della CPU costituisce un parametro critico di un sistema dove essa viene gestita in time sharing.

Per evitare i sovraccarichi, occorre eseguire in ogni time slice3 un numero sufficiente di operazioni di CPU, che deve essere comunque molto più grande del numero di istruzioni eseguite per effettuare i riassegnamenti.

Per poter eseguire un numero elevato di operazioni in un tempo piccolo come deve essere il time slice, non c'è soluzione diversa dall'essere veloce.

Il time slice deve essere piccolo per garantire che in un tempo percettibile da una persona, per esempio un secondo, si trovi un numero elevato di time slice, per poter offrire il servizio a tutti gli utenti almeno una volta.

Riassumendo: • gli utenti devono essere serviti in un tempo ragionevole, perciò in questo tempo si deve trovare almeno

un time slice dedicato a ciascuno, meglio se più di uno. • se gli utenti sono molti, occorre che i time slice siano brevi (dovendo servire 1000 utenti in un secondo

occorre avere un time slice di durata massima pari ad un millesimo di secondo). • comunque, anche se i time slice devono essere brevi, devono essere sempre molto più lunghi del tempo

di riassegnamento, altrimenti il sistema trascorre un tempo eccessivo a compiere operazioni di gestione rispetto al tempo dedicato agli utenti.

Riducendo la durata del time slice, il numero delle commutazioni tra utenti cresce troppo e di conseguenza il tempo dedicato alle routine di sistema diviene eccessivo. Si cade cioè nel system overload, situazione nella quale le attività del sistema operativo impegnano troppo la CPU.

In questa modalità di lavoro assumono ovviamente grande importanza due parametri: • velocità della CPU, cioè il numero di istruzioni che la CPU esegue in 1 secondo; questo parametro

viene spesso indicato come velocità operativa della CPU e misurato in MIPS (milioni di istruzioni per secondo);

• dimensione della memoria centrale che deve essere sufficientemente grande per contenere, oltre ai moduli del sistema operativo, i processi degli utenti e i dati su cui operare.

Per raggiungere l'obiettivo di ottenere una macchina interattiva occorre risolvere i problemi relativi alla mutua sicurezza dei programmi eseguiti ed alla corretta gestione delle risorse. Riguardo a quest'ultima le questioni non sono dissimili da quelle viste nel caso dei sistemi batch, con la difficoltà in più di dover controllare molte linee di I/O interattive.

3 Time slice (in italiano: quanto di tempo). una porzione di tempo dedicata dai sistemi operativi multiprogrammati a ciascun processo o thread, attraverso lo scheduling della CPU. L'esecuzione di più processi o thread, eseguiti in alternanza solo per uno specifico quanto di tempo (nell'ordine dei millisecondi), viene denominata tecnica di time sharing. Il time-sharing può riferirsi ai task, nel qual caso si hanno sistemi operativi multitasking, mentre nel caso di task definiti da più thread, essi sono definiti multithreading..

Page 9: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 8 - 50

Sistemi transazionali

Tra i sistemi interattivi multiutente, evidenziamo i sistemi transazionali, strutturati appositamente per gestire le transazioni, ossia le operazioni di updating (aggiornamento) di archivi e basi di dati di dimensioni rilevanti, che hanno la loro collocazione naturale in applicazioni di tipo gestionale: per esempio la rete Bancomat, la Borsa telematica e i sistemi di raccolta dati dai punti vendita dei grandi magazzini.

Bancomat Borsa telematica Punto vendita di un grande

magazzino

La peculiarità dei loro sistemi operativi consiste di funzioni e procedure sofisticate che permettono di costruire basi di dati logicamente organizzate e di consultarle ed aggiornane in modo semplice e rapido e in condizioni di sicurezza.

Questo significa garantire che un'operazione di aggiornamento che consiste nell'intervento su più di un archivio venga sempre eseguita completamente anche sotto le peggiori condizioni, oppure che venga annullata nella sua interezza. Per esempio, un movimento di vendita di merce effettuato da un registratore di cassa collegato ad un sistema informativo genera una transazione formata da un insieme di registrazioni: • il movimento sul mastro di magazzino; • la modifica della giacenza nel riepilogativo di magazzino; • le registrazioni contabili in dare ed in avere; • la scrittura del movimento sui giornali di cassa.

Se uno di questi interventi non va a buon fine per qualsiasi motivo, occorre garantire che anche gli altri vengano annullati (operazione di rollback), in modo che l'operazione possa essere ripetuta in seguito. In questo modo viene salvaguardata la mutua integrità dei dati nei diversi archivi. Se fallisse la modifica della giacenza, una verifica incrociata sul giornale, che registra tutti i movimenti, e sul riepilogativo, che invece contiene solo il totale, darebbe per risultato una quadratura errata.

Se si considera che oggi i magazzini sono fortemente automatizzati, con la generazione e l'inoltro automatico degli ordini ai fornitori quando la merce scende sotto scorta, si capisce anche che una situazione in cui i dati non sono certi al 100% sia assolutamente inaccettabile.

Sistemi real time

Comunemente si dice che un sistema lavora in real time (tempo reale) quando risponde istantaneamente agli stimoli provenienti dall'esterno.

In un sistema real time, un'elaborazione può considerarsi corretta non solo quando fornisce risultati esatti, ma soprattutto quando li fornisce in tempo; cioè un risultato che arriva in ritardo è un risultato inutilizzabile e quindi errato.

Questo non è mai realizzabile in pratica, in quanto qualsiasi sistema fisico ha un tempo di reazione non nullo necessario per generare una risposta a qualunque stimolo. Ciò è vero tanto per i sistemi di calcolo quanto per sistemi di altri tipi, come l'ambiente in cui avviene una reazione chimica o un semplice circuito elettrico al quale venga applicato un segnale o ancora un uomo al quale venga posta una domanda.

L'elaboratore è inserito in un ambiente che è caratterizzato da certi tempi di reazione che possono essere più o meno lunghi, e con questo ambiente colloquia, assumendo informazioni e fornendo risultati con tempi di reazione caratteristici propri (e del sistema operativo). • Quando il tempo di reazione dell'elaboratore non è essenziale alla corretta evoluzione dell'ambiente in cui è inserito, ma può variare in un intervallo, si dice che il sistema opera in tempo reale in senso lato. Questo è il caso tipico in cui l'elaboratore colloquia con l'utente, per esempio con un agente di viaggi che effettua prenotazioni su aerei o treni, oppure un impiegato bancario che accetta un

Page 10: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 9 - 50

versamento su un conto corrente. In questi casi non ci sono problemi ad accettare tempi di reazione di qualche secondo o addirittura di qualche decina di secondi.

• Molto diverso è il caso in cui l'elaboratore viene usato come controllore di processo, cioè per automatizzare un procedimento produttivo. Qui l'ambiente col quale l'elaboratore interagisce è quello, per esempio, di una reazione chimica: l'elaboratore rileva i valori di alcune variabili dello stato della reazione, come temperature, concentrazioni di reagenti, pressioni, attraverso un insieme di sensori e interviene continuamente su tale stato attraverso dispositivi come rubinetti che si aprono e chiudono per impedire o permettere ai flussi di reagenti di partecipare alla reazione, oppure dispositivi termici che correggono la temperatura ambientale tenendola sotto controllo.

Se il tempo di reazione dell'elaboratore è troppo elevato, può succedere che la reazione non prosegua correttamente e termini, oppure dia luogo ad effetti dannosi. Un esempio efficace è quello del controllo delle reazioni di fissione nelle centrali nucleari: se l'elaboratore risponde in tempi troppo lunghi gli effetti possono essere catastrofici.

In breve, se una reazione chimica non controllata impiega un decimo di secondo a generare una miscela detonante, un elaboratore che risponde in due decimi di secondo sicuramente non è adatto.

Il sistema di calcolo deve pertanto avere tempi di reazione minori, ed in qualche caso molto minori, di quelli caratteristici dell'ambiente in cui è inserito: si parla allora di funzionamento in tempo reale in senso stretto.

Oggi si tende a riconoscere come tempo reale solo quest'ultimo, indicando con il più generico termine di sistemi interattivi quelli funzionanti in tempo reale in senso lato4.

4 Non esiste un insieme standard di indici che misurino le prestazioni di un sistema di calcolo; di seguito vediamo due parametri di uso abbastanza comune:

• CM activity (attività della CPU) È il rapporto espresso in percentuale tra il tempo in cui la CPU opera e il tempo totale in cui il sistema funziona. Può essere divisa in due parti che descrivono l'attività al servizio dei programmi utente e quella dedicata al sistema operativo. Siano: o TempoUtente il tempo totale dedicato ai programmi degli utenti, comprese le routine di sistema la cui esecuzione è richiesta dagli utenti; o TempoSistema il tempo dedicato alle attività di sistema svolte in modo automatico, cioè senza richiesta da parte degli utenti, per esempio per

gestire il time sharing. o Tempolnattivo il tempo in cui il sistema resta in attesa del verificarsi di eventi esterni, come il reperimento di un'informazione da un disco. La somma di questi tempi dà il TempoTotale, un intervallo di tempo in cui il sistema è al servizio degli utenti. La CPU activity è allora data da: CPUACTIVITY (%) = (TempoUtente + TempoSistema) * 100 / TempoTotale e si può scomporre nei due termini TempoUtente * 100 / TempoTotale TempoSistema * 100 / TempoTotale La CPU activity può degradarsi per motivi fisiologici, per esempio perché qualche utente richiede attività onerose, oppure patologici a causa del verificarsi di circostanze anomale, come un guasto non diagnosticato oppure un cattivo dimensionamento delle risorse che costringe il sistema a svolgere del lavoro non necessario. Per esempio: se occorre gestire una base dati condivisa tra utenti, occorre disporre di sufficiente memoria centrale per poter rispondere efficacemente alle richieste. Se questa scarseggia, il sistema impiega molto più tempo per reperire le informazioni e le prestazioni decadono.

• Throughput (produttività) Questo concetto è di per sé molto generico, e indica qualsiasi parametro che misura quanto lavoro si può svolgere in una unità di tempo. Un modo di esprimere la produttività consiste nell'indicare quante istruzioni al secondo o quanta attività della CPU viene dedicata all'utente misurata su un millisecondo. Con le notazioni già usate si può scrivere: THROUGHPUT = TempoUtente / TempoTotale oppure, più genericamente THROUGHPUT = Numero istruzioni / tempo cioè il numero di istruzioni elementari eseguite nell'unità di tempo, o anche THROUGHPUT = Numero processi eseguiti /tempo cioè il numero di processi smaltiti nell'unità di tempo. La produttività differisce dalla CPU activity in quanto considera il tempo di sistema nello stesso modo del tempo inutilizzato. Perciò se troppi utenti sono connessi al sistema, la CPU activity sarà molto alta, mala produttività molto bassa, a causa della quantità esigua di risorse destinate a ciascuno. Il concetto di throughput ha un campo di applicabilità molto ampio, e si possono trova; parametri assimilabili alla produttività in tutti gli ambiti connessi alla gestione del. informazioni. Per esempio la capacità di un certo programma di svolgere certi compiti standard: per un gestore di database può essere il tempo impiegato a rintracciare un certo record in u grosso archivio, oppure il tempo necessario per ordinare lo stesso archivio; per un processore di testi un parametro adatto é il tempo necessario in media all'operatore per impostare un documento standard contenente sottolineature, grassetti, note a piè d pagina, titoli e altre particolarità. Lo stesso termine viene usato per caratterizzare la velocità delle stampanti e allora indica di solito pagine o linee al minuto o caratteri al secondo. Si capisce da quanto detto che un'applicazione o un dispositivo che ha produttività elevata in un certo contesto può essere insufficiente o sovradimensionato in un altro. È inutile usare una stampante da 1000 righe al minuto per servire un personal computer mentre è impensabile usarne una più lenta come stampante principale di un grosso sistema informatico. In altri termini occorre fare attenzione, nel confrontare le produttività degli strumenti tra i quali si desidera scegliere, che il confronto venga effettivamente eseguito tra caratteristiche simili e nel contesto giusto, possibilmente quello reale di impiego.

Page 11: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 10 - 50

Classificazione dei sistemi operativi monoprogrammati e multiprogrammati

I sistemi operativi gestiscono le risorse della macchina in modo diverso a seconda delle esigenze dell'utente: lo stesso processore può infatti essere usato in modo che un solo utente ne sfrutti le capacità, oppure in modo che diversi utenti possano a turno accedere alle stesse. Inoltre in certe applicazioni si può desiderare che certi eventi esterni vengano trattati con priorità più elevata di altri.

La scelta di un sistema operativo piuttosto che di un altro è dettata dall'analisi dei problemi che si vogliono trattare e dall'ambiente in cui il computer dovrà operare.

Una scelta importante che si deve affrontare consiste nel decidere se il computer dovrà essere o no in grado di eseguire diversi programmi contemporaneamente.

Ad un primo livello di dettaglio i sistemi operativi possono essere valutati descrivendo le due modalità di funzionamento delle macchine: monoprogrammazione e multiprogrammazione

Le risorse hardware sono tutti i dispositivi dei tipi elencati di seguito: • unità centrali di processo (CPU); • memorie centrali (MC); • unità di memoria di massa (MM); • dispositivi di ingresso e/o di uscita (I/O).

Si hanno poi alcuni dispositivi particolari ai quali si accennerà separatamente: • gli elaboratori di canale; • i dispositivi multimediali; • i coprocessori matematici e gli acceleratori grafici.

Questi ultimi sono dispositivi hardware simili nella struttura ad una CPU, dedicati allo svolgimento di particolari funzioni, come il calcolo matematico o la gestione di periferiche grafiche. Il loro impiego, sebbene diffuso, è settoriale e non costituisce un punto di interesse primario per una trattazione dei sistemi operativi.

Nello stesso modo, i dispositivi multimediali, sebbene la loro importanza nelle macchine attuali sia sempre più rilevante, non sono molto significativi nell'ambito che viene qui trattato. Le schede audio o video si possono considerare come particolari dispositivi di ingresso/uscita, al pari di tastiere e stampanti, mentre i lettori e i masterizzatori di dischi ottici, CD o DVD, possono essere assimilati a particolari dispositivi di memoria di massa. Ognuno di questi dispositivi viene commercializzato con una dotazione di propri moduli software che ne permettono l'impiego con i diversi sistemi operativi, mettendo a disposizione le primitive richieste dal sistema operativo usato.

Il generico sistema di calcolo a cui si fa riferimento è composto da una CPU, una MC ed una pluralità di dispositivi dei tipi rimanenti.

In realtà nei sistemi di grandi dimensioni e nelle workstation5 ad alte prestazioni possono essere presenti più processori (sistemi multiprocessore). In questo caso il lavoro del sistema operativo si complica per consentire la gestione corretta delle risorse da parte dei diversi processi attivi.

Un sistema operativo è composto da un insieme di programmi che, per essere eseguiti dall'unità centrale di un computer, devono essere allocati in memoria centrale, cioè risiedervi nella forma di codice macchina. La stessa macchina deve permettere ad un utente di eseguire i propri programmi, che si trovano quindi a condividere almeno due risorse (l'unità centrale di processo e la memoria centrale) con almeno un altro programma (il sistema operativo). Un sistema viene detto monoprogrammato (o uniprogrammato) quando la sua memoria centrale contiene, in un dato istante, codice utente proveniente da un unico programma. 5 La workstation o stazione di lavoro è una tipologia particolare di computer monoutente, che si contraddistingue dall'essere destinata principalmente ad un utilizzo produttivo (da cui il prefisso work), e dall'avere alte prestazioni per poter assolvere compiti altamente professionali di vario genere. Caratteristica quest'ultima che rende la workstation un computer utilizzato da professionisti in ambiti di lavoro che necessitano di grandi potenze di calcolo come ad esempio il CAD, la ricerca scientifica, la produzione audio/video. Esso è dunque sinonimo di un computer più potente rispetto ad un normale personal computer domestico.

Page 12: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 11 - 50

Il codice in oggetto viene eseguito dalla CPU che preleva le istruzioni dalla memoria nella sequenza corretta e le esegue una per volta. Il registro contatore di programma (PC, Program Counter) provvede a segnalare quale istruzione debba essere eseguita, e gli altri eventuali registri della CPU (PSW, Program Status Word) contengono le diverse informazioni che consentono al processore di eseguire i suoi compiti relativamente all'attività in corso.

L'esecuzione di un'istruzione del programma utente comporta una chiamata di sistema (system call), cioè la richiesta di qualche routine del sistema operativo, per esempio quando viene richiesto l'accesso a qualche periferica o a dispositivi di memoria di massa. Quando si scrive un programma in linguaggi evoluti come C++ o Java, è il compilatore che provvede a generare il codice appropriato per il sistema operativo usato: un'istruzione di output in C++ viene trasformata in modo diverso a seconda che il sistema operativo sia Linux piuttosto che Windows.

In ogni caso, il compilatore genera una sequenza di istruzioni in codice macchina, tra le quali ad un certo punto compare almeno una chiamata al sistema operativo.

Quando il flusso dell'esecuzione attraversa la chiamata, occorre che il programma utente sia momentaneamente sospeso in favore del sistema operativo, dopo aver salvato alcune informazioni che consentiranno al programma utente di ripartire correttamente.

Uno studente alle prese con un argomento complicato si comporta in modo analogo quando interrompe lo svolgimento per documentarsi su un passaggio che non gli è chiaro o quando si concede uno spuntino per l'intervallo: lo stato dell'esercizio rimane scritto sul quaderno o sul libro e, al termine dell'interruzione, potrà ripartire dal punto dove era arrivato.

Nel caso in esame occorre salvare da qualche parte, ossia in memoria centrale, il contenuto dei registri usati dal programma: in questo modo il programma potrà ripartire dopo aver ricopiato nei registri i dati salvati.

Occorre puntualizzare un fatto importante: il salvataggio dei registri è sufficiente a garantire che il programma possa ripartire correttamente, alla condizione che l'area di memoria che contiene le istruzioni e i dati del programma non venga intaccata dalla routine di sistema. Lo scenario, nel caso in cui questo non accada, è il seguente: quando i registri vengono ricaricati dalla memoria, il contatore di programma (PC) indica di riprendere l'esecuzione leggendo dalla memoria un'istruzione in un punto particolare, dove però non si trova più l'istruzione originale, ma qualcosa d'altro. Succede allora che il programma prosegue eseguendo operazioni diverse da quelle previste, oppure che il flusso di esecuzione si interrompe.

Le routine del sistema operativo rispettano questo tipo di restrizione, ed evitano di modificare aree di memoria dove si trova codice utente. Questo risultato si ottiene per esempio imponendo che i programmi utente non vengano caricati in posizione qualsiasi nella memoria, ma solo in un certo spazio: i moduli di sistema useranno solo la memoria rimanente.

Quando il programma utente termina, la memoria centrale diventa disponibile ad accogliere un nuovo programma da eseguire.

Si può dividere il tempo che intercorre tra l'inizio e la fine del programma in intervalli caratterizzati dalle diverse attività della CPU: • esecuzione di istruzioni del programma utente; • esecuzione di istruzioni del sistema operativo; • inattività, per esempio quando attende un input da tastiera.

Chiamiamo TempoUtente, TempoSistema e Tempolnattivo i tempi trascorsi complessivamente nelle tre situazioni, TempoTotale la loro somma e facciamo qualche considerazione: • il TempoUtente corrisponde al tempo speso dalla CPU per eseguire le “linee di codice”6 che sono nel

programma;

6 Ricordiamo che: sia un programma utente che una routine di sistema sono costituiti da istruzioni in codice macchina da eseguire in un certo ordine e quindi sono del tutto simili.

tempo sistema tempo inattivo tempo utente

Page 13: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 12 - 50

• il TempoSistema è il tempo speso dal sistema operativo sta lavorando per il nostro programma perché esegue i compiti richiesti dal programma. In questo tempo dunque la CPU è impegnata nell’esecuzione delle “linee di codice” 7 del sistema operativo;

• nel Tempolnattivo la CPU di fatto non sta facendo nulla se non aspettare che succeda qualcosa e quindi potrebbe eseguire istruzioni di altri programmi. Il tempo Tempolnattivo può essere grande rispetto agli altri (Tempo Utente e Tempo Sistema), perché la CPU, essendo molto veloce, può rimanere “inattiva” per molto tempo in particolare quando un programmi interattivo richiede l'intervento continuo dell'utente che, come è noto, è molto più lento della CPU. Ad esempio: il tempo che intercorre tra due battiture di tasti (decimi di secondo) è lunghissimo rispetto ai tempi di esecuzione della macchina (miliardesimi di secondo).

Nel tempo TempoTotale la macchina dunque non è disponibile per altri utenti, essendo impegnata dal programma in esecuzione (TempoUtente e TempoSistema), anche se in attesa di un evento esterno (Tempo Inattivo).

La sintesi che si può trarre da queste osservazioni è che si potrebbe sfruttare maggiormente la CPU facendo in modo che, nel tempo in cui non viene usata dal programma utente, venga comunque adoperata per eseguire altri programmi, eventualmente di utenti diversi.

In tal modo si ottiene un impiego più razionale della risorsa: invece di acquistare altre costose CPU, viene usata sempre la stessa.

L'idea, che le osservazioni suggeriscono, consiste nell'usare i meccanismi di sospensione dell'esecuzione, impiegati per le routine di sistema, per permettere l'esecuzione anche di altri programmi utente.

Il sistema operativo, ottenuto dalla realizzazione pratica di queste idee progettuali, viene detto multiprogrammato.

Per raggiungere questo obiettivo occorre complicare il sistema operativo che deve disporre di nuove capacità, non richieste nel caso della monoprogrammazione.

In particolare occorre che vengano sviluppate le routine di sistema che permettono di: • decidere quale istruzione far eseguire dopo quella attuale, se prelevandola dallo stesso programma o da

un altro; • realizzare meccanismi di protezione tra i diversi programmi, per evitare che i dati di uno vengano inquinati

dalle istruzioni dell'altro; • risolvere eventuali conflitti che possono sorgere per l'assegnazione di una determinata risorsa, per esempio

quando due programmi richiedono l'accesso ad un disco o ad una stampante.

Il sistema operativo deve intervenire periodicamente di propria iniziativa e non solo su richiesta di un programma: infatti le attività descritte devono avvenire automaticamente e non per effetto di esplicite istruzioni impartite dai diversi programmi. Questo significa, tra l'altro, che il Tempolnattivo recuperato non è tutto utilizzabile per l'esecuzione dei programmi degli utenti ma viene ripartito tra questi e le routine del sistema operativo. Si parla di system overhead, ossia di sovraccarico di lavoro imposto dal sistema operativo alla CPU.

Riassumendo, l'obiettivo da raggiungere è quello di ottenere il massimo rendimento dalla macchina a disposizione attraverso l'impiego dei tempi morti per la CPU, nei quali normalmente non sarebbe impegnata, per svolgere altri lavori: per ottenere questo risultato occorre impiegare una frazione del tempo disponibile per eseguire l'attività di gestione.

Si dice che una risorsa viene gestita in modo time sharing (a partizione di tempo), quando il suo uso viene concesso per un tempo che non può superare un massimo: questo intervallo viene chiamato time slice (fetta o quanto di tempo), esempio: 20-120ms.

Il time sharing è un concetto che viene applicato ai singoli dispositivi, più che alla macchina nel suo insieme: si può gestire in questo modo la CPU o la memoria centrale o entrambe, ottenendo effetti diversi.

Se la CPU di un sistema multiprogrammato viene gestita in time sharing, essa rimane assegnata ad un programma utente finché si verifica una delle seguenti eventualità: • il programma utente termina; • il programma utente richiede che vengano effettuate operazioni che coinvolgono altri dispositivi; 7 Ricordiamo che: sia un programma utente che una routine di sistema sono costituiti da istruzioni in codice macchina da eseguire in un certo ordine e quindi sono del tutto simili.

Page 14: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 13 - 50

• scade il time slice.

Appena accade uno di questi eventi, il controllo dell'unità centrale passa al sistema operativo che decide a quale tra gli altri programmi in memoria centrale spetti il prossimo time slice.

Quindi il sistema operativo deve disporre di un meccanismo automatico che prenda il controllo della situazione e verifichi a chi toccherà disporre della CPU per il prossimo time slice.

Il sistema operativo opera quindi un riassegnamento della CPU o context switch (cambiamento di contesto), ordine di 1ms.

Il tempo necessario a prendere tale decisione si chiama tempo di riassegnamento.

Le modalità con le quali il sistema operativo prende queste decisioni costituiscono un esempio di politica di gestione. La realizzazione più semplice consiste nell'assegnamento a rotazione o round robin (vedi politiche di schedulazione dei processi). Il programma a cui è stata tolta la risorsa viene messo in fondo ad una coda di programmi in attesa. Quando tutti gli altri avranno eseguito le operazioni nei time slice di competenza esso ripartirà da dove è arrivato. Naturalmente se uno o più di questi programmi risulta essere in attesa di altri eventi, il time slice verrà immediatamente riassegnato al programma successivo.

È possibile che un sistema operativo usi meccanismi di priorità che consentono ad alcuni programmi di essere eseguiti più rapidamente, per esempio concedendo un time slice più lungo ai programmi con priorità più elevata, oppure scegliendo di assegnare più spesso la CPU ai programmi con priorità più alta tra quelli in stato di pronto.

Un modo di visualizzare questi meccanismi è quello di immaginare ciascun programma in una coda specifica per la priorità che possiede. Il sistema può eseguire a turno i programmi che stanno al primo posto in ciascuna coda e usare un criterio per concedere più tempo macchina ai programmi che stanno nelle code a priorità più alta. Al termine del time slice ogni programma finisce in fondo alla coda che gli compete.

In sintesi, l'uso time sharing della CPU permette di realizzare ambienti multiprogrammati o multiutente senza necessità di disporre di diverse CPU. Si può dire che il sistema operativo virtualizza la CPU, creandone una molteplicità dove in realtà ne esiste solo una. È questa una caratteristica del time sharing: trasformare un singolo dispositivo fisico in molti dispositivi virtuali disponibili per un tempo inferiore.

In generale, una risorsa gestita a divisione di tempo viene trasformata in molte risorse simili, eventualmente con prestazioni inferiori alla risorsa originale.

La scelta della durata del time slice deve tenere conto del fatto che il sistema operativo utilizza una parte del tempo macchina ad ogni time slice per eseguire i suoi controlli ed effettuare le operazioni necessarie a riassegnare la risorsa CPU (o la memoria centrale o entrambe) e della necessità di servire tutti i programmi con una frequenza ragionevole. In particolare, se il time slice è troppo lungo i programmi in attesa restano molto tempo fermi e questo non è soddisfacente, soprattutto nei sistemi interattivi; se invece è troppo breve il sistema operativo deve intervenire spesso, sottraendo molto tempo all'elaborazione. Il valore di equilibrio migliore dipende principalmente dalla velocità della CPU e dal tipo di applicazione per cui è stato progettato il sistema di calcolo.

Prog.

P3 Prog.

P1 Prog.

P2

Prog.

P1

Prog.

P3 Prog.

P2

Prog.

P1

Tempo di riassegnamento Richieste di I/O

Prog.

P2

Fine richieste di I/O di P3

Fine richieste di I/O di P2

Fine time slice

Fine programma P3

Page 15: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 14 - 50

Il meccanismo delle priorità in questo caso è molto utile, perché permette, per esempio, di servire con frequenza opportuna i terminali interattivi, e di eseguire i programmi che invece non necessitano dell'intervento dell'operatore con minore rapidità, se questa non è indispensabile.

Va notato che quando più utenti adoperano la stessa periferica, per esempio di output, questa non sempre è gestita in modo time sharing. Per una stampante non esiste un time slice associato al funzionamento, ma ogni utente usa il dispositivo fintanto che gli serve e poi lo rilascia. Il time sharing presuppone invece sempre l'esistenza del time slice.

Sistemi multiprogrammati - interattivi

I processi

Da qui in poi, salvo specifica indicazione, si farà sempre riferimento ad un generico sistema di calcolo multiprogrammato e interattivo: il sistema dedicato ed il sistema batch, mono o multiprogrammati, si possono infatti vedere come casi particolari di quello trattato.

In un dato istante la situazione delle risorse sia la seguente: la CPU sta eseguendo un'operazione in risposta ad un'istruzione letta dalla memoria centrale; la memoria centrale contiene il codice di alcuni programmi utente e del sistema operativo; le periferiche di I/O e i dispositivi di memoria di massa colloquiano con gli elaboratori di canale.

Il compito del sistema operativo è di garantire la corretta evoluzione dello stato, assegnando le risorse in modo che tutti i richiedenti vengano prima o poi soddisfatti e realizzando la sicurezza per ciascun utente e per sé stesso. In particolare, la memoria centrale deve essere divisa tra gli utenti senza possibilità di accedere alle zone al di fuori della propria competenza impedendo così modifiche al codice di altri utenti o del sistema operativo. Questa attività ha luogo senza che gli utenti se ne accorgano, in modo automatico e periodico; in più, il sistema operativo mette a disposizione le proprie routine, l'esecuzione delle quali viene avviata su richiesta.

Prima di approfondire l'analisi occorre illustrare alcuni concetti, quelli di processo e processore, indispensabili per comprendere la struttura che schematizza il sistema operativo, secondo il modello che verrà illustrato in seguito.

Il termine processo definisce un insieme formato da un elenco finito di azioni da eseguire in sequenza e dai dati che vengono elaborati dalle stesse azioni.

Questo concetto è diverso da quello di programma almeno per due aspetti:

• un processo evolve nel tempo, al contrario dei programmi, intesi come traduzioni di algoritmi;

• i processi sono sequenziali, mentre i programmi contengono salti e cicli.

Chiamiamo processore l'oggetto che causa l'evoluzione del processo.

In memoria centrale, in un dato istante, possiamo trovare un certo numero di processi, uno dei quali sta evolvendo, altri sono pronti per essere serviti, altri devono attendere la terminazione di operazioni di I/O. Altri ancora sono momentaneamente parcheggiati su memoria di massa.

Linee di comunicazione

CPU (esegue

un’istruzione)

Sistema Operativo

P1

P2

P3

Memoria centrale Dispositivo di I/O

o unità di memoria di massa

Elaboratore di canale

Istruzione in esecuzione

Page 16: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 15 - 50

Per comprendere il concetto, possiamo dire che l'esecuzione di un programma genera almeno un processo, costituito dalla sequenza delle operazioni del programma.

Il sistema operativo interviene su questa situazione appena termina l'assegnazione dell'unità centrale al processo attuale.

Questo può avvenire per tre motivi:

• il processo termina, il sistema operativo libera l'area di memoria centrale occupata dal processo e la riempie con uno dei processi parcheggiati se ve ne sono.

• il time slice finisce, il sistema operativo sospende il processo attribuendogli lo stato di pronto ed assegna la CPU ad un altro processo che già si trovi in tale stato.

• il processo richiede un'operazione di I/O, questo caso richiede un trattamento meno semplice; infatti il processo non potrà proseguire finché l'operazione di I/O richiesta non sarà terminata, pertanto il sistema operativo gli attribuisce uno stato di attesa e genera un nuovo processo attivando le proprie routine.

Al termine dell'operazione di I/O il processo in attesa potrà passare nello stato di pronto.

Quindi gli stati possibili nei quali si può trovare un processo sono: • parcheggio, quando attende di essere caricato in memoria centrale; • pronto, quando attende che gli venga assegnata la CPU; • esecuzione, quando il processo è in evoluzione perché gli è stata assegnata la CPU; • attesa, quando richiede un'operazione di I/O su una periferica; • terminazione, quando il processo è stato completato e può essere tolto dalla memoria centrale.

I passaggi di stato sono i seguenti:

• da parcheggio a pronto: il processo viene caricato in memoria centrale e attende l'uso della CPU;

• da pronto ad esecuzione: la CPU viene assegnata al processo;

• da esecuzione a pronto: scade il time slice e al processo viene tolta la CPU;

• da esecuzione ad attesa: il processo richiede un'operazione di I/O e ad esso viene tolta la CPU anche se il time slice non è scaduto;

• da attesa a pronto: l'operazione di I/O è stata terminata e il processo viene messo ne coda dei processi pronti per l'uso della CPU;

• da esecuzione a terminazione: il processo è stato completato nella sua evoluzione.

I processi rientranti

Una interessante classificazione relativa ai programmi ed ai processi che essi generano è quella fra: rientrante o puro e non puro.

I programmi rientranti sono progettati in modo che una singola copia del codice in memoria possa essere condivisa ed eseguita contemporaneamente da utenti multipli o processi separati.

Dunque i processi rientranti o a codice puro tengono separate le parti che non vengono modificate durante l'esecuzione, come le istruzioni, dalle parti suscettibili di variazione, come le aree dati.

Processo

terminato

Processo

parcheggiato

Processo in

pronto

Processo in

attesa

Processo in

esecuzione

Fine del time slice

I/O eseguito

Richiesta di I/O

Schedulatore dei lavori

Schedulatore dei

processi

Controllore del traffico

Page 17: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 16 - 50

Si dicono non puri i processi per i quali tale suddivisione non è possibile, in quanto mescolano nella stessa zona istruzioni e dati.

Lavorando in multiprogrammazione, i normali processi utente sono indipendenti, ma può succedere che debbano interagire, comunicandosi dati o utilizzando le stesse routine di sistema (chiamate a compilatori, routine di Input/Output, etc.). Tenere distinte le aree di memoria, come accade ad esempio con le partizioni fisse, permette di ridurre il rischio di interazioni e di effetti collaterali, ma richiede la duplicazione di zone che contengono informazioni uguali mentre per i processi puri è sufficiente duplicare l'area che può variare, ossia la sua parte non pura.

Ad esempio: • per i programmi scritti in Pascal (o in C) è il compilatore stesso a produrre due aree separate per i dati e per le istruzioni; mentre per altri linguaggi (come i linguaggi assemblativi) è cura del programmatore rispettare tale distinzione;

• anche nel caso dei sistemi operativi è possibile distinguere fra codice puro e non puro: il kernel (vedi nucleo) dei sistemi operativi Windows NT è completamente rientrante, a differenza di quello di Windows 9x, le cui notevoli porzioni di codice a 16 bit derivate da MS-DOS non sono rientranti.

Ogni miglioramento comporta un aumento nella complessità di gestione. Ad esempio il sistema operativo deve sapere, per ogni parte non duplicata, il numero di processi nei quali interviene e può rilasciare l'area utilizzata da più processi solo quando l'ultimo processo ha terminato la sua elaborazione.

Le interruzioni

Le richieste di I/O hanno la caratteristica di durare un tempo a priori non prevedibile. Quando un evento avviene in tempi che dipendono da fattori esterni al sistema viene detto asincrono. Tipici eventi asincroni sono gli errori, la fine di una stampa, l'invio dati o comandi tramite dispositivi di ingresso.

Il verificarsi di questi eventi viene comunicato alla CPU usando il meccanismo di interrupt (interruzione): in pratica il dispositivo al livello del quale avviene l'evento invia un segnale alla CPU attraverso una apposita linea elettrica. Con questo meccanismo si può segnalare alla CPU che è successo qualcosa e che deve interrompere momentaneamente la sua attività per eseguire un compito particolare.

A seconda del tipo di interruzione vengono attivate diverse routine del sistema operativo che provvedono all'attuazione delle misure necessarie.

Le interruzioni sono segnali, generati in corrispondenza di particolari eventi, che fanno si che il programma in esecuzione venga interrotto e si possa passare ad eseguire dei programmi di servizio associati a quegli eventi.

Ogni evento che può causare un'interruzione genera una richiesta di interruzione con un segnale inviato all'unità centrale su una linea fisica il cui stato indica se la richiesta è attiva o no.

In risposta a questo segnale l'unità centrale interrompe la sequenza operativa che abbiamo visto analizzando il ciclo di macchina e si ha l'esecuzione forzata di una istruzione allocata in un'altra cella di memoria. L'esecuzione continua poi secondo le consuete modalità.

Un'istruzione macchina particolare, istruzione di ritorno dall'interruzione, permette di riprendere l'esecuzione del programma interrotto. Questo schema è illustrato in figura.

L'implementazione del concetto di interruzione differisce da un'architettura all'altra. Esistono comunque delle caratteristiche funzionali che sono comuni a tutte le architetture indipendentemente dalla loro implementazione.

• Memorizzazione della richiesta di interruzione

Una richiesta di interruzione deve essere mantenuta attiva fino a che l'unità centrale non risponde. Questo è necessario perché non sempre una richiesta può essere immediatamente soddisfatta. Ad esempio nel caso che

Page 18: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 17 - 50

vengano attivate contemporaneamente due richieste una di esse dovrà aspettare poiché l'unità centrale risponde a una richiesta per volta.

• Abilitazione e mascheramento delle interruzioni a programma

Il poter abilitare o disabilitare certe interruzioni da programma, cioè con apposite istruzioni, consente una maggior flessibilità nella gestione delle risorse di un sistema. Ad esempio il trasferimento dei dati ad un certo mezzo di I/O, a seconda dell'applicazione, può essere più convenientemente controllato a programma che ad interruzione o viceversa.

Per mascheramento delle interruzioni si intende la possibilità di ritardare, per un certo tempo, la risposta da parte dell'unità centrale. Le richieste di interruzione vengono quindi mascherate, nascoste, all'unità centrale per il tempo necessario.

• Salvataggio dello stato del programma

L'unità centrale in risposta ad una interruzione sospende l'esecuzione del programma. Lo stato del programma sospeso deve essere in qualche modo salvato così da poterne più tardi riprendere l'esecuzione correttamente. Questo implica la memorizzazione di registri dell'unità centrale che vengono usati nell'esecuzione di qualsiasi programma; fra questi il registro PC che contiene l'indirizzo della successiva istruzione del programma interrotto. • Salto forzato ad un nuovo programma, l'unità centrale viene forzata ad, eseguire un nuovo programma.

Questo implica una sostituzione forzata del contenuto del registro PC. • Identificazione della causa di interruzione, nel caso in cui uno stesso segnale possa essere causato da

più eventi deve essere possibile identificare la causa dell'interruzione. • Ripristino dello stato precedente all'interruzione, dopo aver servito la causa dell'interruzione deve

essere possibile riprendere l'esecuzione del programma interrotto nella stessa situazione in cui esso si trovava al momento dell'interruzione, senza quindi nessun effetto particolare indotto dall'interruzione sull'esecuzione del programma.

• Risoluzione di conflitti tra richieste di interruzione, se ci sono richieste contemporanee di interruzione a causa di eventi diversi, deve essere stabilito l'ordine in cui devono essere soddisfatte (priorità fra le interruzioni).

Vediamo ora alcuni esempi. 1. In caso di errore si deve generare un messaggio e decidere se il processo in errore deve terminare oppure

può proseguire. 2. Quando il clock di sistema causa lo scadere del time slice del processo in esecuzione, si genera

un’interruzione. Se, ad esempio, un time slice è pari a 1000 cicli di clock8, allo scadere di ogni 1000 cicli viene generata un’interruzione hardware di “fine time slice”. Queste interruzioni sono appunto di tipo sincrono perché sono eventi interni al processore, previsti e sincronizzati come le attività del processore stesso.

3. Le interruzioni sincrone rivestono particolare importanza anche nella programmazione in linguaggio Assembler (programmazione di basso livello) in quanto possono anche essere provocate volontariamente dal programmatore. Molte primitive di sistema vengono infatti rese disponibili proprio attraverso l'uso delle interruzioni: per esempio le operazioni di lettura e scrittura dei dati su disco. Programmando in Assembler, se si desidera leggere un blocco di dati da un file occorre scrivere alcune informazioni in determinate posizioni di memoria (per esempio il nome del file e la dimensione del blocco da leggere) e provocare un'interruzione per mezzo di un'istruzione particolare. Il sistema riceve l'interruzione, legge le informazioni allegate ed esegue l'operazione, copiando dal disco alla memoria i dati richiesti

8 Tutte le CPU lavorano seguendo un clock, un "orologio" interno al sistema che scandisce il tempo per compiere tutte le operazioni. Il processore svolge la sua attività in modo ciclico, ad ogni ciclo corrisponde l’esecuzione di un’operazione elementare (un’istruzione macchina) ed il clock fornisce una cadenza temporale per l’esecuzione delle operazioni elementari. La frequenza del clock indica il numero di operazioni elementari che vengono eseguite nell’unità di tempo e si misura in MHz (1 MHz corrisponde circa a un milione di istruzioni elementari/battiti al secondo) o GHz (1 GHz corrisponde circa a un miliardo di istruzioni elementari/battiti al secondo). Per esempio un computer ha un processore a 3 GHz vuol dire che il processore è in grado di eseguire (circa) 3 miliardi di istruzioni al secondo.

Page 19: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 18 - 50

Una tecnica d'uso più sofisticata consiste nello scrivere programmi che effettuano una ridefinizione (in inglese override) del comportamento normale del sistema.

4. Quando si digita un carattere sulla tastiera, l'evento viene comunicato al computer per mezzo di un'interruzione, e il codice corrispondente al carattere battuto è disponibile per l'elaborazione. Una tabella provvede quindi ad associare al codice del tasto un carattere ASCII che viene inoltrato dal sistema verso la sua destinazione, ossia al programma in elaborazione in quel momento, per esempio un elaboratore di testi. Alcune combinazioni di tasti devono però seguire una strada differente: per esempio, su un personal computer con Windows, la combinazione Ctrl + Alt + Canc permette di accedere ad una finestra dalla quale si possono far terminare i programmi attivi, mentre Ctrl + C in Linux fa terminare il programma attivo. Se si desidera definire delle combinazioni di tasti particolari, si può scrivere un programma che intercetta l'interruzione provocata dalla tastiera e valuta il codice del tasto premuto. Se tale codice corrisponde ad uno di quelli da trattare in modo particolare si eseguono le istruzioni opportune, altrimenti è desiderabile che il tasto venga trattato nel modo predefinito. Per far questo, nel programmasi può provocare di nuovo l'interruzione che attiva il modulo standard.

Riassumendo, si possono distinguere tre tipi fondamentali di interruzione: • interrupt asincroni, generati solo dall'hardware, che servono a segnalare alla CPU eventi non correlati al suo

orologio interno, come la fine di una stampa o di una scrittura su disco; • interrupt sincroni generati dall'hardware, che segnalano eventi accaduti in relazione all'orologio interno; • interrupt sincroni provocati via software, usati per accedere a routine particolari. Tale meccanismo, realizzato dal sistema di gestione delle interruzioni (Interrupt handler), prevede che sia il dispositivo di I/O a comunica al processore la propria richiesta di “attenzione” inviando al processore un segnale IRQ (Interrupt ReQuest, ovvero di richiesta di interruzione), a seguito di questa richiesta, il processore può interrompere temporaneamente la propria attività per eseguire la sequenza di istruzioni, prevista dal protocollo del I/O, detta routine di servizio.

Il meccanismo degli interrupt è utilizzato da quasi tutti i modelli di CPU9 esistenti sul mercato, perché è il modo più facile per interrompere il normale flusso del programma quando accade un evento asincrono perché inatteso.

Tale richiesta, a seconda dello stato in cui si trova la CPU, può anche essere accantonata per essere eseguita in un secondo tempo. A tale proposito esistono dei particolari tipi di IRQ (a volte chiamati NMI, Non Maskable Interrupt) che non possono essere accantonati ma devono eseguiti immediatamente. 9 Un’altra tecnica utilizzata è quella del polling che prevede la gestione dei dispositivi di I/O è totalmente A carico della CPU. Il polling è basato sulla scansione periodica di tutti i dispositivi per verificare se qualcuno di essi richiede un servizio.

Page 20: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 19 - 50

Gli IRQ esistono per gestire questo traffico di dati e per dare un ordine alle diverse richieste di elaborazione che vengono sottoposte al processore pertanto, ciascun dispositivo del PC, deve averne uno assegnato per poter funzionare.

Il sistema di configurazione plug and play ha cambiato la tradizionale assegnazione “manuale” degli IRQ ai dispositivi realizzandola in modo dinamico.

Alcuni IRQ sono assegnati di default a funzioni standard basilari (es: IRQ 1 per la tastiera) e non possono essere variati, altri IRQ sono liberi e possono essere assegnati a determinati tipi di dispositivi (es: di solito alla scheda audio è assegnato l’IRQ 5 oppure l’IRQ 10) come possiamo vedere dalla tabella delle assegnazioni standard:

Di regola un IRQ10 dovrebbe essere assegnato ad un solo ed unico dispositivo, ma alcune volte uno stesso IRQ può essere condiviso fra più dispositivi, anche se è sconsigliabile perché spesso può causare dei conflitti fra periferiche.

Gli IRQ sono spesso organizzati in gerarchie di priorità, dove un IRQ di basso livello può essere a sua volta interrotto da un IRQ di livello più alto. I diversi tipi di computer in genere standardizzano i loro IRQ in modo che ad un certo IRQ corrisponda sempre un certo tipo di evento esterno: un tasto premuto sulla tastiera, una comunicazione in arrivo dalla porta seriale e così via.

Il modello a macchine virtuali

Per entrare nel dettaglio delle funzioni svolte dal sistema operativo, si utilizza un modello che consente di mettere a fuoco i principali meccanismi di interazione tra le varie parti che lo costituiscono e di queste con l'esterno. La schematizzazione usata è di tipo gerarchico e viene detta a macchine virtuali.

Una macchina virtuale è un oggetto costituito da una macchina più semplice, in grado di eseguire un certo insieme di operazioni fisiche, e da un modulo che fornisce un'interpretazione logica di tali operazioni: l'insieme costituisce una nuova macchina in grado di eseguire operazioni logiche.

Il sistema operativo genera, a partire dalla macchina hardware, una gerarchia di macchine virtuali, ciascuna delle quali soddisfa principalmente a questi requisiti: • risolve il problema dell'utilizzo delle risorse (memorie di

massa, stampanti, video terminali, CPU) da parte dei moduli di livello superiore, rendendo accessibili le capacità della macchina di livello inferiore attraverso un insieme di comandi;

• moltiplica il numero dei dispositivi disponibili, accogliendo più richieste di quelle che il sistema può servire contemporaneamente, soddisfacendole nell'ambito delle politi che decisionali scelte.

10 Per controllare le effettive assegnazioni degli IRQ è necessario consultare l'apposito controllo in "Gestione delle Periferiche".

IRQ FUNZIONE/DISPONIBILITA' NOTE IRQ 0 Timer di sistema NON MODIFICABILE IRQ 1 Tastiera NON MODIFICABILE IRQ 2 Utilizzato dal secondo controller (IRQ 8-15) NON MODIFICABILE IRQ 8 Clock in tempo reale NON MODIFICABILE IRQ 9 Disponibile (reindirizzato sull'IRQ 2) IRQ 10 Disponibile IRQ 11 Disponibile IRQ 12 Mouse PS/2 IRQ 13 Coprocessore matematico NON MODIFICABILE IRQ 14 Controller primario IRQ 15 Controller secondario IRQ 3 Porta seriale COM 2 IRQ 4 Potar seriale COM1 IRQ 5 Porta parallela LPT 2; scheda audio IRQ 6 Controller floppy disk IRQ 7 Porta parallela LPT 1 Nota: gli interrupt sono elencati per priorità. Poiché il secondo controller degli interrupt si collega a cascata sull'IRQ 2 del primo controller, gli IRQ da 8 a 15 hanno una priorità più alta rispetto agli IRQ da 3 a 7. Alcuni interrupt (porte seriali, parallela, mouse PS2, ecc. ) sono disabilitabili da BIOS.

Page 21: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 20 - 50

Possiamo pensare all'insieme dei dispositivi fisici che costituiscono il computer come ad un livello zero, e all'utente come al livello più alto: il sistema operativo contiene i livelli tra lo zero e un livello molto vicino a quello dell'utente.

Questa struttura costituisce il così detto modello onion skin (buccia di cipolla), elaborato da H. M. Deitel nel 1983, e rappresenta il sistema operativo come una successione di strati costruiti sopra un nocciolo costituito dalla macchina hardware (livello zero), ciascuno dei quali rappresenta un livello di macchina virtuale.

Moduli e primitive

Ciascuno strato del sistema operativo costituisce un modulo, composto da programmi che vedono solo le procedure implementate dagli strati sottostanti, attraverso le primitive che queste mettono a disposizione, come richiesto dalla struttura modulare. Le primitive di ciascun modulo possono quindi essere invocate solo dai moduli di livello superiore.

Una primitiva11 è dunque una procedura standard per mezzo della quale il modulo mette a disposizione i propri servizi.

In sostanza a qualsiasi livello ci si collochi all'interno del modello, gli strati sottostanti vengono visti come un oggetto unico, che non corrisponde alla macchina fisica (e quindi è una macchina virtuale) e che è in grado di svolgere le funzioni richieste a quel livello. I livelli più bassi sono quelli più vicini all'hardware, quelli più alti sono vicini all'utente e alle sue applicazioni.

Il sistema operativo è dunque un insieme di programmi che sovrintende al corretto funzionamento delle apparecchiature che costituiscono il sistema di elaborazione.

Le richieste dell'utilizzatore vengono acquisite e gestite dal sistema operativo in modo coordinato, rispettando le cosiddette politiche di gestione, che sono regole scelte fra molte possibili per realizzare i meccanismi desiderati.

Le politiche di gestione possono essere definite come le norme di comportamento del sistema di elaborazione: indicano al computer come reagire agli stimoli e come rispondere alle richieste dell'utente, stabilendo gerarchie e priorità con le quali ogni richiesta deve essere servita.

La struttura formale di un sistema operativo è pertanto gerarchica: questo significa che i programmi che lo compongono si collocano a livelli diversi, si servono di programmi che stanno a livelli sottostanti e servono i programmi dei livelli superiori.

All'interno di ogni livello, si usa raggruppare tutti i programmi scritti per risolvere un problema, o una classe di problemi simili, in moduli.

Ogni modulo si può vedere come una scatola nera (in inglese black box) che contiene all'interno le competenze per risolvere un problema e presentare risultati in conseguenza dell'elaborazione di richieste. Quel che avviene all'interno di un modulo in realtà non è interessante per chi effettua la richiesta del servizio fornito, quindi all'occorrenza il modulo può essere modificato o anche riscritto.

Per i programmi che fanno uso del modulo, la cosa veramente importante è che questo continui a rispondere coerentemente alle richieste effettuate attraverso un insieme di procedure standard.

Per meglio comprendere il senso, si pensi al semplice gesto di effettuare una telefonata: la procedura standard consiste nel sollevare la cornetta, attendere il segnale e comporre il numero. Se la compagnia telefonica (il modulo) invia il segnale al destinatario attraverso linee terrestri, piuttosto che con il satellite o i ponti radio, la cosa non riveste grande importanza per l'utente. Se però improvvisamente cambiassero le modalità di accesso al servizio, per esempio imponendo di digitare una sequenza di 50 cifre segrete prima del numero di telefono, nessuno riuscirebbe più a telefonare.

Quindi, cambiando la procedura standard (primitiva) si è reso il modulo del tutto inservibile.

11 Quando un processo utente invoca delle primitive del sistema (ad esempio: accesso a periferiche) si ha: una supervisor call (SVC) e viene mandato in esecuzione il processo supervisore

MODULO

Primitive del modulo

Verso altri moduli o verso l’hw

Page 22: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 21 - 50

Le richieste dell'utilizzatore vengono quindi acquisite dal modulo, che le trasforma in modo che possano essere comprese ed eseguite da altri moduli di livello inferiore, o eventualmente dalla macchina stessa.

Naturalmente, l'esecuzione delle azioni viene permessa nel rispetto delle politiche di gestione.

Si è detto che i moduli che lavorano direttamente sulle risorse hardware del sistema costituiscono i livelli più bassi della gerarchia: essi impartiscono comandi alle diverse componenti fisiche per eseguire operazioni meccaniche od elettriche, come visualizzare un carattere su monitor, attivare un modem oppure scrivere un dato su un dischetto o nella memoria centrale.

Questi moduli permettono di richiedere risorse ai dispositivi usando comandi più comprensibili. Si dice che virtualizzano i dispositivi, ossia li trasformano in macchine astratte o macchine virtuali in grado di eseguire operazioni più complesse come se fossero elementari, definite in modo logico piuttosto che fisico.

Un'operazione logica corrisponde all'esigenza dell'utente di ottenere un risultato, per esempio scrivere un testo usando una stampante; la corrispondente operazione fisica consiste nell'eseguire molte operazioni elementari dipendenti dal particolare elaboratore e dalla particolare stampante sui quali l'operazione logica è stata richiesta. La stampa ad aghi usa una tecnologia completamente diversa dalla stampa laser o a getto di inchiostro, ma l'operazione eseguita è concettualmente uguale.

L'aspettativa dell'utente di stampare il proprio documento viene trasformata in richieste elementari al dispositivo e il sistemasi preoccupa che ognuna vada a buon fine, gestendo le varie situazioni di errore che si possono presentare senza che il richiedente debba più intervenire.

Più in dettaglio, per ottenere il risultato desiderato (la stampa del testo), occorre eseguire le primitive adatte dei moduli di alto livello, indicando quale documento si vuole stampare e su quale stampante.

Stampante ad aghi Stampante InkJet Stampante Laser

I moduli ai quali le primitive appartengono inoltrano le richieste ai moduli di livello inferiore usando le loro primitive e così avanti fino a raggiungere l'hardware.

Esso esegue materialmente l'operazione richiesta: i circuiti della stampante trasformano i comandi specifici ricevuti in sequenze di impulsi elettrici che attivano i dispositivi elettrici o meccanici coinvolti nell'operazione; nel caso della stampante ad aghi vengono spinti contro il nastro i sottili aghi che causano il trasferimento dell'inchiostro sulla carta, mentre per la stampante laser, il laser traccia sul tamburo fotosensibile l'immagine della pagina, in modo che il toner (lo speciale inchiostro solido usato anche per le fotocopiatrici) venga raccolto dal serbatoio e successivamente trasportato sulla pagina.

I comandi da impartire all'hardware nei due casi per ottenere il risultato voluto sono scritti in modo diverso, ma l'utente non è tenuto a conoscere i dettagli grazie al fatto che il sistema operativo trasforma il suo comando Stampa nei comandi hardware appropriati in modo invisibile.

Due dispositivi fisici differenti, per esempio due stampanti, corredati dai rispettivi moduli di sistema operativo, possono così diventare due dispositivi logici identici. L'unica condizione è che i moduli relativi mettano a disposizione del sistema le medesime primitive per eseguire le stesse operazioni logiche.

Volendo stampare su una stampante differente (stessa operazione logica), si usa la stessa primitiva ed il modulo corrispondente provvede a generare i comandi necessari per la specifica stampante (operazione fisica diversa).

Possiamo ora esprimere in termini meno intuitivi cosa si intenda esattamente per modulo ed elencarne le caratteristiche peculiari.

• Un modulo è quindi una collezione di routine che attivano i meccanismi fisici necessari per risolvere problemi logici di uno stesso tipo (per esempio le operazioni di ingresso/uscita o la gestione della memoria).

• Per quanto visto, i moduli devono mantenere un elevato grado di indipendenza, quindi ciascun modulo deve essere scritto senza conoscere la struttura interna degli altri moduli di sistema operativo.

• L'unico modo in cui un modulo può comunicare con un altro è attraverso le primitive da essi implementate. Viceversa, la sua struttura interna deve poter essere modificata senza che gli altri moduli se ne accorgano, purché le primitive che esso realizza non cambino.

Page 23: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 22 - 50

• In altre parole, un modulo è visibile solo attraverso le sue primitive, così come le reti idrica, elettrica o telefonica sono visibili solo attraverso i servizi che erogano. Se si apre il rubinetto esce acqua, se si chiama il servizio abbonati si può conoscere il numero di un abbonato al telefono, se si chiamala primitiva X si ottiene il risultato Y tutto questo senza dover sapere in che tubi passa l'acqua, dov'è la centrale telefonica o quali istruzioni contiene il modulo che è stato adoperato.

Se un sistema operativo è costruito con criteri di modularità, si può usarlo su macchine diverse sostituendo i soli moduli che operano sull'hardware, mantenendo lo stesso insieme di primitive.

Le macchine virtuali viste dai moduli di livello superiore saranno in questo modo uguali e questi moduli possono continuare a svolgere i propri compiti senza necessità di modifiche.

Per riassumere: macchine diverse vengono viste all'esterno solo come esecutrici di primitive, quindi se le primitive disponibili sono identiche, le macchine sono in grado di eseguire le stesse operazioni logiche. Per questo i moduli che accedono a queste primitive possono essere esattamente uguali.

Per misurare l’attitudine del sistema operativo ad essere eseguito su macchine diverse si utilizza il grado di portabilità.

La portabilità può essere realizzata a livelli diversi: • a un livello basso può riguardare semplicemente la possibilità di utilizzare gli stessi dati su macchine diverse

o con programmi diversi; • a un livello maggiore si possono eseguire programmi software su macchine diverse dopo aver ricompilato i

sorgenti; • a un livello ancora più alto si possono usare gli stessi applicativi in formato eseguibile su computer di

diverso tipo.

Possiamo anche dire che il grado di portabilità è tanto maggiore quanto e minore il costo delle modifiche necessarie per garantirne il funzionamento su macchine diverse. Se il sistema operativo e modulare questo costo e ridotto, perche le modifiche sono concentrate nei soli moduli interni anziché essere distribuite nell'intero corpo del programma, e pertanto i moduli esterni possono essere utilizzati senza cambiamenti.

Nello schema precedente la sostituzione dei moduli 1, 2 e 3 è sufficiente a far si che il sistema possa essere portato su altre macchine. Le frecce che collegano i moduli tra loro indicano che il modulo di livello superiore (identificato dal numero più alto) usa una o più primitive implementate dal modulo di livello inferiore, mentre le frecce che terminano sull'hardware indicano che il modulo usa direttamente le risorse hardware. I moduli dal 4 in poi non usano direttamente nessuna risorsa hardware, ma solo primitive rese disponibili dai moduli 1, 2 e 3, perciò se viene cambiato l'hardware con il corredo dei nuovi moduli 1, 2 e 3 che forniscono le stesse primitive, i moduli dal 4 in poi non possono accorgersene e continuano a funzionare esattamente come prima.

I device driver

Dato che alcuni dei programmi del sistema operativo interagiscono con le componenti hardware che costituiscono il computer, questo deve conoscere le caratteristiche dei dispositivi in modo da poterli controllare e adoperare.

È opportuno che il sistema operativo sia comunque in grado di accedere anche a dispositivi non previsti inizialmente, purché questi vengano forniti con il corredo del software necessario, comunemente chiamato device driver (pilota del dispositivo). In altri termini, lo stesso sistema operativo deve poter essere ampliato e personalizzato a seconda della macchina su cui viene installato.

M5

M4

M3

M2

M1

Hardware

Moduli esterni

Moduli interni

Page 24: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 23 - 50

I vari dispositivi elettronici che compongono l’hardware del sistema, per poter essere utilizzati, hanno quindi bisogno di questo particolare software (device driver) che sia a conoscenza dei dettagli del funzionamento del dispositivo e quindi in grado di gestirlo in maniera appropriata.

Infatti, considerando sia la varietà delle tipologie dei dispositivi presenti sul mercato sia l’enorme numero di produttori di hardware, è impensabile che un’applicazione possa gestire direttamente tutti i possibili dispositivi di cui ha bisogno. Ad esempio, un’applicazione che gestisce la stampa di un documento dovrebbe preoccuparsi di gestire la

stampa di un documento sui vari tipi (ad aghi, a getto di inchiostro, laser, ...) e modelli di stampante esistenti sul mercato. Non solo: un’altra applicazione, che ha a che fare con la stampante, dovrebbe anch’essa gestire la stampa sui vari modelli di stampante. Da qui nasce l’idea di delegare il compito di gestire dei dispositivi ad un software specifico (device driver).

Un driver è un software piuttosto contenuto, spesso scritte in assembly, in grado di gestire in maniera appropriata uno specifico dispositivo e di fungere da interfaccia tra il dispositivo e le applicazioni.

Il driver è scritto solitamente dal produttore del dispositivo hardware, dato che è necessaria un'approfondita conoscenza dell'hardware per poter scrivere un driver funzionante. A volte, i driver vengono scritti da terze parti sulla base della documentazione tecnica rilasciata dal produttore, se questa è disponibile.

Il codice dei driver si differenzia dal codice delle applicazioni (o programmi) perché non viene eseguito in modo autonomo dall'inizio alla fine ma viene richiamato di volta in volta quando ce n'è bisogno.

Quando un’applicazione vuole utilizzare il dispositivo in questione, indica al driver quale operazione vuol compiere sul dispositivo, senza dover entrare nei dettagli. È il driver stesso che, riconosciuta la richiesta, sa come farla eseguire nei dettagli al dispositivo.

Il driver permette al sistema operativo di utilizzare l'hardware senza sapere come esso funzioni, ma dialogandoci attraverso un'interfaccia standard, i registri del controllore della periferica, che astrae dall'implementazione dell'hardware e che ne considera solo il funzionamento logico. In questo modo hardware diverso costruito da produttori diversi può essere utilizzato in modo intercambiabile. Ne consegue che un driver è specifico: • sia dal punto di vista dell'hardware che pilota, • sia dal punto di vista del sistema operativo per cui è scritto.

Non è possibile utilizzare driver scritti per un sistema operativo su uno differente, perché l'interfaccia è generalmente diversa.

Man mano che le aziende producono nuovi dispositivi e li immettono sul mercato, esse provvedono a realizzare i driver per certi sistemi operativi. È chiaro che la spinta a produrre un driver per un determinato sistema operativo è tanto più forte quanto maggiore è la diffusione dello stesso, poiché ci saranno più potenziali clienti per il dispositivo prodotto. Visto che Windows, in tutte le sue forme, può essere considerato il sistema operativo attualmente più diffuso nel mondo, è molto probabile che un’azienda che produce un dispositivo fornisca anche i driver per poterlo utilizzare con Windows.

Le aziende produttrici di dispositivi hardware forniscono i driver per utilizzare i loro dispositivi, oltre che con Windows, anche con altri sistemi operativi (essenzialmente Mac e GNU/Linux) oppure rilasciano le specifiche dei propri dispositivi, permettendo a chiunque sia in grado e ne abbia voglia, di realizzare il driver per il sistema operativo desiderato. Esistono anche aziende che non pubblicano le specifiche dell’hardware che producono perché lo ritengono un segreto industriale da sfruttare come vantaggio sui concorrenti.

Ogni volta che un processo vuole accedere ad un dispositivo lo fa utilizzando una chiamate di sistema, la quale utilizza una funzionalità del driver. Una chiamata di sistema (system call) è una particolare funzione che esegue il passaggio dallo spazio utente (user space) allo spazio di nucleo (kernel space).

Page 25: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 24 - 50

Sui sistemi operativi moderni questo compito viene svolto spesso in modo automatico, o comunque senza intervento di personale specializzato. I dispositivi realizzati in tecnologia plug and play (inserisci e usa) colloquiano con il sistema in modo tale da "farsi riconoscere" e richiedere l'installazione dei driver corretti.

Il sistema operativo è così in grado di configurare tali dispositivi in modo che non si creino conflitti con dispositivi preesistenti e che l'insieme funzioni correttamente.

Ovviamente, un device driver scritto per uno specifico dispositivo può non funzionare con un altro simile ma non identico. Dato che questo programma parla direttamente con il dispositivo, deve usare un linguaggio che venga compreso dall'interlocutore, cioè dall'hardware: se il componente viene sostituito da un altro che non parla la stessa lingua, il dispositivo non funziona.

Per risolvere questo problema si tende a far si che dispositivi costruiti per fare fronte ad esigenze simili siano tra loro compatibili, nel senso che si possano sostituire gli uni con gli altri senza perdere funzionalità.

Questo non significa necessariamente che i dispositivi debbano essere identici, esattamente come non è necessario costruire biciclette tutte rigorosamente uguali per poterle vendere ad un ciclista che ha imparato su un modello specifico. È sufficiente che vengano rispettate alcune caratteristiche principali ben note.

Di conseguenza, molti dispositivi hardware vengono costruiti secondo standard affermati12, che ne regolamentano diversi aspetti come le dimensioni, le funzionalità supportate e i comandi che si possono impartire al dispositivo. Questi standard si sono imposti e continuano ad imporsi in diversi modi:

• in conseguenza del dominio sul mercato di una particolare azienda produttrice (INTEL, HP, CISCO, EPSON);

• per mezzo di normative erogate da istituti riconosciuti a livello internazionale come: ISO (International Standards Organization); di norma questo avviene quando il mercato di un tipo particolare di dispositivo non presenta un leader incontrastato come per esempio nel campo dei CDROM, per i quali esistono appunto raccomandazioni emesse da ISO.

• in seguito al lavoro di gruppi di ricerca costituiti da team di aziende concorrenti che impostano accordi per lavorare insieme nello sviluppo di nuovi componenti e tecnologie.

Il motivo per cui gli standard nascono in molti modi diversi è dovuto alla velocità del progresso tecnologico, per cui spesso chi inventa un dispositivo X nuovo dalle prestazioni soddisfacenti, ed ottiene successo commerciale, viene rapidamente seguito da altre aziende che lo riproducono simile e dichiarano che il loro prodotto è compatibile con il dispositivo X. Nasce così di fatto uno standard imposto dal mercato.

Quando una funzionalità diventa molto importante e richiesta, ma non esiste uno specifico standard nel settore, gli istituti internazionali vengono sollecitati ad emettere le loro raccomandazioni, ossia regole generali da rispettare, con lo scopo di stimolare i produttori a rendere più omogenei i loro dispositivi.

Sistemi operativi aperti vs sistemi operativi proprietari

Un sistema operativo aperto è costruito in modo da poter operare con una molteplicità di dispositivi, che possono essere reperiti sul mercato senza dover fare riferimento ad una ristretta cerchia di produttori: il sistema operativo Unix, per esempio, può controllare macchine fra loro molto diverse, costruite addirittura su unità centrali non compatibili. Un sistema operativo aperto permette l'uso di molti dispositivi hardware standard senza imporre particolari condizioni oltre alla scrittura di piccoli software (device driver).

Al contrario, un sistema proprietario (Windows, MacOS) è scritto per essere eseguito su un insieme ristretto e ben specifico di macchine, corredate o meno di specifici dispositivi.

L'esistenza dei sistemi operativi proprietari è giustificata dal fatto che soddisfano esigenze specifiche in modo molto efficace e che il servizio offerto dalla casa proprietaria è sufficiente a coprire tutte le esigenze dell'utenza a costi ragionevoli.

Facciamo qualche esempio: • Linux è un sistema operativo aperto quindi gratuito, libero (nessun problema di licenza), altamente

modificabile e quindi personalizzabile, veloce, sicuro.

12 Per esempio i personal computer compatibili IBM, le CPU compatibili INTEL, i lettori ed i masterizzatori per dischi ottici, le periferiche USB, le stampanti compatibili EPSON o HEWLETT PACKARD, le apparecchiature e le schede di rete CISCO e 3COM.

Page 26: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 25 - 50

• Nei sistemi operativi come Linux, dotati di un kernel monolitico, il driver è un modulo compilato insieme al kernel quindi, se una periferica non è supportata dal sistema operativo, non è possibile utilizzarla ma, fortunatamente, il kernel Linux supporta decine di migliaia di periferiche in modo nativo, quindi la maggior parte dell'hardware viene riconosciuto subito.

• Nei sistemi operativi con kernel ibrido come Windows o MacOS, quando è necessario aggiungere una nuova periferica, il driver viene caricato dinamicamente dal kernel. o MacOS è sistema operativo proprietario concepito appositamente per particolari dispositivi hardware

ed applicativi estremamente professionali (soprattutto nel campo multimediale), molto veloce, sicuro. o Windows è sistema operativo proprietario ma dotato di grande flessibilità perché consente il

funzionamento di tutti gli applicativi standard ed è compatibile con quasi tutto l’hardware sul mercato. Ad oggi la stragrande maggioranza delle applicazioni è concepita per Windows.

Il nucleo

L'unità centrale di processo (CPU) è un esecutore sequenziale di operazioni: costituisce pertanto un processore.

In ambiente multiprogrammato, la sequenza di operazioni eseguite è costituita da sottosequenze generate da processi diversi e dalle routine di interruzione.

Attraverso l'uso time sharing delle risorse, è possibile vedere la CPU come un insieme di processori virtuali assegnati ai singoli processi e funzionanti a turno. Se è possibile garantire che ciascun processore faccia evolvere correttamente il processo corrispondente, perde importanza il fatto che solo uno sia attivo in ogni istante: i veloci tempi di commutazione nell'uso della CPU da un processo all'altro forniscono a ciascun processo l'idea di avere un processore completamente a disposizione; questo processore fisicamente è uno solo, ma corrisponde a tanti processori virtuali che fanno avanzare i processi. I moduli esterni potranno perciò contare su una pluralità di processori senza più doversi preoccupare né dei problemi di assegnazione dell'unica CPU realmente presente, né delle interruzioni.

Il nucleo, chiamato anche kernel, è la parte del sistema operativo più vicina alla macchina, ed è strettamente dipendente dall'hardware. Le funzioni fondamentali del nucleo sono: • avvio e terminazione dei processi, • assegnazione della CPU ai diversi processi, • sincronizzazione tra i processi, • sincronizzazione dei processi con l'ambiente esterno.

Il nucleo comprende tutte le routine di risposta alle interruzioni e le procedure che assegnano la risorsa CPU ai diversi processi. Le norme che regolano queste assegnazioni vengono chiamate politiche di scheduling.

Fanno quindi parte del nucleo: • lo schedulatore dei lavori; • lo schedulatore dei processi; • il controllore del traffico; • il gestore delle interruzioni; • le procedure di sincronizzazione e comunicazione tra più processi necessarie per lo scambio di dati e

informazioni.

Lo schedulatore dei lavori

Determina in ogni istante il numero di lavori che risiedono in memoria centrale e quindi condiziona e controlla il grado di multiprogrammazione del sistema. Tiene aggiornate apposite tabelle che contengono le informazioni dello stato di ciascun lavoro (job) Sceglie ogni volta quale lavoro deve acquisire le risorse per avanzare, selezionandolo da una lista dei lavori in stato di “parcheggio”. Quando un job viene scelto genera un processo Quando un processo termina sovrintende e coordina il recupero delle risorse assegnate a quel processo. Per fare questo consulta i descrittori dei lavori. Ogni descrittore contiene le seguenti informazioni: • il nome del lavoro, • la data e ora di accettazione, • la priorità il tempo previsto di CPU,

Page 27: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 26 - 50

• l’elenco delle risorse da assegnare staticamente (dedicate per l’intero tempo di elaborazione), • l’elenco delle risorse da assegnare dinamicamente (assegnate al momento dell’uso e rilasciate subito

dopo), • l’indicatore dello stato di avanzamento del lavoro (step). Dato che un lavoro può generare più processi

viene indicato ogni processo già concluso e quello eventualmente in esecuzione. • il puntatore al lavoro successivo nella lista.

Politiche di schedulazione dei lavori

• First In First Out: I lavori vengono scelti nell’ordine in cui sono giunti. In questo caso può succedere che i tempi di risposta siano imprevedibili e spesso c’è una scarsa ottimizzazione delle risorse.

• Priorità statica: in questo caso viene assegnata ad ogni lavoro che arriva una priorità calcolata in base ad alcuni parametri, ad esempio al tempo presunto di utilizzo di alcune risorse. C’è però il rischio che alcuni lavori, quelli con priorità basse, restino troppo in attesa se arrivano continuamente lavori con priorità più alta.

• Priorità dinamica: in questo caso viene assegnata ad ogni lavoro che arriva una priorità calcolata in base ad alcuni parametri, come nel caso precedente, ma con il crescere del tempo di attesa viene incrementata la priorità; si tiene quindi conto dell’anzianità del lavoro per evitare che rimanga troppo tempo nella lista

Schedulatore dei processi

Determina in ogni istante il processo che deve essere portato da stato di pronto in stato di esecuzione, assegnandogli quindi la risorsa processore.

Per fare questo consulta i descrittori dei processi (PCB - Process Control Block).

Ogni descrittore contiene le seguenti informazioni: • il nome del processo • l’indirizzo del descrittore del processo che l’ha generato (es.: per un processo di I/O viene posto in

questo campo l’indirizzo del processo che l’ha richiamato) • la lista degli indirizzi dei descrittori dei processi richiamati • lo stato di avanzamento • l’immagine nel processore (contenuto dei registri di lavoro, del registro dei flags, del program counter,…) • l’immagine nella memoria (le informazioni sulle aree di memoria assegnate al processo) • le informazioni relative alle altre risorse assegnate al processo • il tempo di CPU già usato, i limiti di tempo, … • il puntatore al processo successivo nella lista

Politiche di schedulazione dei processi

Lo schedulatore dei processi opera sulla lista dei processi in stato di pronto per scegliere, in base ad una certa politica, quale processo portare in stato di esecuzione. Esistono diversi algoritmi di schedulazione dei processi che, per un corretto funzionamento del sistema, devono fare in modo di avere sia processi che usano molto la CPU, sia processi che usano molto le periferiche (I/O). In questo modo si evitano tempi di risposta inaccettabili per i programmi interattivi in un caso e inattività del processore nell’altro.

Tra le politiche di scheduling, la più semplice è quella round robin che prevede una coda di processi pronti ed un insieme di processi in attesa.

Quando ad un processo viene tolta la CPU esso viene messo in fondo alla coda se rimane in stato di pronto oppure passa in stato di attesa: in entrambi i casi la CPU viene assegnata al primo processo nella coda.

Page 28: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 27 - 50

Si può raffinare questa politica organizzando i processi pronti su diverse code, corrispondenti alle diverse priorità (round robin a più livelli). I processi stato di pronto vengono posti su code corrispondenti alle diverse priorità assegnate a ciascuno: al momento di scegliere il processo da mandare in esecuzione vengono favoriti quelli a priorità più elevata. Il gestore dei processi (scheduler), che è anch'esso un processo, ha la priorità massima, cosi come il processo che si occupa della gestione delle interruzioni (interrupt handler) deve avere priorità maggiore rispetto a qualunque altro processo. E’ importante osservare che la priorità non ha nulla a che vedere con la velocità con cui un processo e eseguito: la potenza della CPU è un dato fisso. La priorità entra in gioco solo quando il sistema deve decidere qual e il prossimo processo che deve andare in esecuzione: questa operazione si chiama context switch, cioè il passaggio dal contesto di esecuzione di un processo al contesto di esecuzione di un altro. I processi a priorità più elevata possono essere favoriti in diversi modi: • assegnando loro time slice più lunghi; • scegliendoli più spesso all'interno delle code di priorità. Quando un processo a bassa priorità è in esecuzione sulla CPU e un processo a priorità più alta ritorna da un'operazione di I/O (esce dallo stato di attesa e passa in stato di pronto), il primo processo viene interrotto e il secondo va immediatamente in esecuzione sulla CPU: questo meccanismo si chiama preemption (letteralmente, prelazione). Con questa gestione delle priorità si garantisce che i processi privilegiati vengano serviti più di frequente. Nello stesso tempo occorre evitare la situazione nella quale alcuni processi rimangono fermi per troppo tempo (starvation). Se sono in esecuzione processi che hanno la stessa priorità, il sistema prevede che ognuno di essi vada in esecuzione per un certo tempo e che poi la CPU venga passata a un altro e cosi via. In questo modo, anche se un processo non ha la necessità di interrompersi per un'operazione di I/O o per un altro motivo, non mantiene il possesso della CPU per tempi troppo lunghi, che impedirebbero agli altri processi di accedere alla CPU e procedere con il proprio lavoro.

Questo si può impedire adottando una politica mista, assegnando cioè time slice differenti, oppure garantendo che le code a priorità più alta non siano mai più lunghe di quelle a priorità più bassa: per

Processo

terminato

Processo

pronto

Processo

pronto

Processo

pronto

Processo

parcheggiato

Processo in

attesa

Processo in

esecuzione

Fine del time slice

I/O eseguito

Richiesta di I/O

Processo

terminato

Processo

pronto

Processo

pronto

Processo

pronto

Processo

parcheggiato

Processo in

attesa

Processo in

esecuzione

Fine del time slice

I/O eseguito Richiesta di I/O

Processo

pronto

Processo

pronto

Processo

pronto

Processo

pronto

Processo

pronto

Processo

pronto

Algoritmo di

scelta

Coda di priorità 0 (alta)

Coda di priorità 1 (media)

Coda di priorità 2 (bassa)

Processi fra cui

scegliere

Page 29: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 28 - 50

esempio diminuendo la priorità dei processi in esecuzione da più tempo. Comunque la politica di gestione adottata deve garantire che tutti i processi vengano prima o poi serviti e quindi possano terminare.

Il controllore del traffico

Questo modulo ha il compito di controllare l'avanzamento dei processi ed in particolare deve: • tener traccia dello stato di tutti i processi attivi; • provvedere a far cambiare stato ai singoli processi, in base alle particolari condizioni che si verificano nel

sistema; • coordinare la sincronizzazione e la cooperazione tra i vari processi. Per compiere la prima funzione, il controllore del traffico si avvale del descrittore di processo, compilandolo in tutte le sue parti man mano che lo stato del processo subisce variazioni. La seconda funzione consiste nel compiere tutte quelle operazioni che determinano il cambiamento di stato di un processo: generazione di nuovi processi, gestione delle diverse liste dei descrittori, interazione con gli altri moduli del sistema operativo per assegnare o riprendere il controllo delle risorse, inizializzazione dei registri del processore nel momento in cui questo viene assegnato ad un processo con i dati reperiti dal relativo descrittore, etc. Per compiere tutte queste operazioni risulta indispensabile sincronizzare l'esecuzione sia dei moduli di sistema operativo che dei vari processi, in modo che le diverse operazioni vengano compiute dai diversi dispositivi nel corretto ordine di precedenza. Vi possono essere ad esempio dei processi attivi che vogliono comunicare tra loro, come nel caso di un processo di I/O che, nel momento in cui termina, deve riattivare il processo che l'ha generato. In questo caso il controllore del traffico deve essere in grado di accettare chiamate da parte del processo di I/O e di smistarle verso il processo principale per farlo evolvere dallo stato di attesa allo stato di pronto.

Tutte queste operazioni prendono il nome di sincronizzazione e comunicazione tra processi.

La sincronizzazione tra i processi

La necessità di condividere le risorse di un sistema di elaborazione genera il problema della sincronizzazione dei processi. La ripartizione di queste richieste necessita quindi di un coordinamento che assicura la sequenza corretta delle operazioni.

Lo schedulatore dei lavori, quando genera un processo per l'esecuzione, gli assegna staticamente tutte le risorse non condivisibili necessarie al processo.

Solitamente queste risorse coincidono con quelle la cui assegnazione dinamica darebbe luogo ad una sovrapposizione di effetti tali da rendere errata l'interpretazione delle informazioni.

Immaginiamo ad esempio di assegnare a turno dinamicamente la stessa stampante a due processi in esecuzione. Se i processi richiedono solo saltuariamente l'uso di tale risorsa per stampare una riga, potrebbe capitare che le righe di stampa, appartenenti ai due processi, vengano mescolate tra di loro. Questa situazione, in cui si verificano errori legati alla velocità relativa dei processi in esecuzione, è detta race condition (condizione di corsa).

Analizziamo in dettaglio l’esempio riportato sopra: • in situazione di multiprogrammazione due processi utilizzano la stessa stampante; • ciascuno dei due processi chiede di stampare delle linee; • a seconda di come vengono fatti avanzare i due processi l’uno rispetto all’altro (scheduling) può darsi che

le linee stampate da uno precedano quelle stampate dall’altro come può darsi che si mescolino le une con le altre.

In questo caso bisogna fare in modo che la stampante sia utilizzata da un processo alla volta, così il primo processo che ne ha bisogno comincia ad utilizzarla e l’altro aspetta fino a che il primo non ha finito. I processi lavorano dunque in condizioni di mutua esclusione e le risorse vengono assegnate staticamente. In questo modo il problema viene superato, ma nasce un nuovo inconveniente: quando un processo molto lungo utilizza la risorsa solo nell'ultima parte, questa risulta inagibile per molto tempo per gli altri processi, anche se, in realtà rimane inattiva.

Questo problema si può risolvere facendo assegnare staticamente dallo schedulatore dei lavori, solo le risorse richieste esplicitamente dall'utente.

Page 30: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 29 - 50

Sarà allora compito del gestore del traffico assegnare tutte le altre risorse, comprese quelle non compatibili. Per queste ultime l’assegnazione verrà fatta ancora staticamente, ma solo a partire dal momento in cui processo ne richiede l'uso per la prima volta.

La risoluzione di questo problema può essere estesa affrontando formalmente tutta la categoria dei problemi legati all'interferenza e alla cooperazione fra processi.

Interferenza e cooperazione tra i processi

Spesso i processi non possono evolvere in modo del tutto indipendente ma devono essere sincronizzati per garantire un perfetto funzionamento del sistema. In particolare, si dice che più processi interferiscono tra loro quando, da un punto di vista logico, potrebbero evolvere in modo indipendente se non dovessero usufruire della stessa risorsa.

In questo caso sarà compito del controllore del traffico garantire che in ogni istante la risorsa sia assegnata ad uno solo dei processi richiedenti e che ognuno di questi, dopo un tempo o meno lungo, la possa usare (problema della mutua esclusione).

Si dice invece che due processi cooperano quando sono logicamente interconnessi, cioè quando, per evolvere, uno dei due deve usare un qualche tipo di risorsa prodotto dall'altro.

In questo caso, ovviamente, lo stato di avanzamento di un processo dipende strettamente dallo stato di avanzamento degli altri processi con cui condivide risorse. Quindi problemi di competizione su tali risorse, devono essere risolti direttamente dai processi, comunicando tra loro per mezzo di opportuni messaggi di sincronizzazione. Di conseguenza i programmi associati ai processi dovranno contenere apposite istruzioni (primitive e di sincronizzazione) per la produzione ed il consumo di messaggi.

Ricordando che il sistema di elaborazione, preso come riferimento, è dotato di più processori (un processore centrale ed alcuni processori di I/O), e che quindi più processi possono essere contemporaneamente in esecuzione su processori diversi, analizziamo i meccanismi più comuni usati per garantire detta sincronizzazione.

I semafori binari e la primitiva TEST AND SET

Nella maggior parte degli schemi di sincronizzazione, ogni risorsa è rappresentata attraverso una variabile, detta semaforo binario, che può essere considerata come una "spia" dello stato della risorsa associata. In particolare, il semaforo può solo assumere il valore 1 quando la risorsa non è disponibile e 0 nel caso contrario.

Quando un processo necessita di una risorsa, deve controllarne la disponibilità leggendo il valore del semaforo e, nel caso in cui la risorsa sia occupata, deve porsi in attesa finché il semaforo segnala via libera.

Molto spesso per effettuare questo tipo di operazione ci sia avvale di una primitiva di sistema denominata TEST AND SET. Si tratta di una sequenza di istruzioni la cui esecuzione non può mai venire interrotta e che esplica le seguenti funzioni: • esamina il valore del semaforo associata alla risorsa richiesta (test) e ne tiene traccia nel registro di stato, • pone a 1 il valore del semaforo (set).

Poiché l’esecuzione della TEST AND SET non può mai venire interrotta la fase di test continua finché la risorsa non viene rilasciata dal processo che la detiene, alla fine della stessa il valore del semaforo sarà sicuramente a 1, indipendentemente dal valore che aveva originariamente; ciò garantisce che, all'uscita dalla TEST AND SET, la risorsa risulti in ogni caso occupata e che quindi non possa essere assegnata ad altri mentre il processore sta effettuando il controllo di disponibilità.

Page 31: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 30 - 50

Una volta utilizzate la risorsa, il processo dovrà porre nuovamente il semaforo a 0, liberandola.

Con questa tecnica la sincronizzazione e la mutua esclusione vengono garantiti direttamente dai processi senza l'intervento del sistema operativo, a scapito però di un'alta occupazione dei processori. Ogni processo, infatti, dovrà rimanere in esecuzione sul proprio processore anche durante la fase di attesa della

risorsa, eseguendo continuamente il ciclo appena descritto.

Le primitive WAIT e SIGNAL

La gestione della sincronizzazione può essere demandata al nucleo del sistema operativo (in particolare al controllore del traffico), in modo da interrompere l'esecuzione di un processo che richiede una risorsa finché questa non risulti disponibile.

In questo caso il processo effettua l'operazione di TEST AND SET una sola volta e, se la risorsa non è disponibile, invoca un'altra primitiva di sistema, detta WAIT13, che lo porrà in stato di attesa con gli altri processi che hanno richiesto la stessa risorsa (coda di attesa della risorsa R).

Successivamente richiamerà lo schedulatore dei processi, il quale assegnerà il processore ad un nuovo processo. In modo analogo, una volta ultimata l'operazione, il processo che sta usando la risorsa pone a 0 il semaforo ed invoca un'apposita primitiva del sistema operativo, SIGNAL14, la quale si preoccuperà di estrarre dalla coda uno dei processi e di riportarlo allo stato di pronto.

I semafori a contatore e le primitive P e V

Una forma più generale delle strutture di sincronizzazione basate sui semafori fu presentata da Dijkstra15 nel 1968; essa si basa sull'uso di semafori a contatore e su una coppia di procedure di sincronizzazione denominate P e V. Un semaforo a contatore è una variabile intera il cui valore viene modificato ogniqualvolta un processo chiede l'uso di una risorsa o la vuole rilasciare. Al semaforo è associata una lista dei processi che attendono dal semaforo l’autorizzazione all’uso della risorsa. Prima che inizi l’esecuzione dei processi che usano quel semaforo questo viene inizializzato con un valore S0. Quando un processo richiede l'uso della risorsa il valore del semaforo viene decrementato di 1, mentre viene incrementato dello stesso valore quando la risorsa viene rilasciata. Le primitive P e V hanno il compito di effettuare queste operazioni sul semaforo e, nello stesso tempo, di richiamare le primitive di sincronizzazione WAIT e SIGNAL, onde garantire una corretta gestione delle code di attesa. A questo proposito va ribadito che P e V, pur essendo composte da più istruzioni elementari, formano una struttura indivisibile (primitiva) che non può essere interrotta durante l'esecuzione. Per questo motivo, nei sistemi ove P e V non sono direttamente implementate come istruzioni macchina, esse vengono sempre fatte precedere da un'istruzione che inibisce ogni tipo di interruzione (mask) e fatte seguire da un'istruzione analoga che le riabilita (unmask).

Le primitive P e V consentono di ottimizzare le funzioni del controllore del traffico. Infatti, la funzione SIGNAL che ha il compito di riportare un processo in stato di pronto, viene invocata solamente dopo aver

13 pron. [weɪ t] 14 pron. [ˈ sɪ gnl] 15

Edsger Wybe Dijkstra (pronunciato dǫikstra) ha studiato fisica teorica all'Università di Leida. Ha lavorato come ricercatore per la Burroughs Corporation agli inizi degli anni '70. Nel 1972 ha ricevuto il Premio Turing. Ha lavorato all'Eindhoven University of Technology nei Paesi Bassi e in seguito tenne la cattedra di informatica all'Università del Texas di Austin. Si ritirò nel 2000. È morto il 6 agosto 2002 dopo una lunga malattia.

Page 32: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 31 - 50

verificato che la coda non è vuota.

È oltre a dirimere eventuali competizioni per l'uso di una risorsa, i semafori e le primitive P e V hanno consentito di risolvere anche problemi di sincronizzazione legati alla cooperazione tra processi.

Il problema del produttore del consumatore

Il problema del produttore-consumatore è un esempio classico di cooperazione tra processi. Il problema descrive due processi, uno produttore (in inglese producer) ed uno consumatore (consumer), che condividono un buffer comune, di dimensione fissata.

Compito del produttore è generare dati e depositarli nel buffer in continuo. Contemporaneamente, il consumatore utilizzerà i dati prodotti, rimuovendoli di volta in volta dal buffer. Il problema è assicurare che il produttore non elabori nuovi dati se il buffer è pieno, e che il consumatore non cerchi dati se il buffer è vuoto.

La soluzione per il produttore è sospendere la propria esecuzione se il buffer è pieno (WAIT); non appena il consumatore avrà prelevato un elemento dal buffer, esso "sveglierà" il produttore (SIGNAL), che ricomincerà quindi a riempire il buffer. Allo stesso modo, il consumatore sospenderà la propria attività se il buffer è vuoto (WAIT); non appena il produttore avrà scaricato dati nel buffer, “risveglierà” il consumatore (SIGNAL). In questo caso il buffer è costituito da una sola variabile.

Questa soluzione può essere implementata tramite delle strategie di comunicazione tra processi, tipicamente con dei semafori.

Analizziamo ora in dettaglio un generico problema “produttore-consumatore” quando questi condividono un buffer di tipo vettoriale.

In un generico problema del produttore-consumatore il buffer è un vettore che può contenere al più N messaggi, tutti dello stesso tipo (ad esempio numero o stringa).

È evidente a questo punto che le due operazioni dovranno essere opportunamente sincronizzate per far sì che C acceda all’area comune solo quando P vi ha depositato un dato. Inoltre occorrerà evitare che P cerchi di depositare un nuovo dato prima che C abbia

prelevato il precedente.

Descriviamo ora, attraverso un esempio di esecuzione la soluzione proposta da Dijkstra, che utilizza due semafori METTERE e PRENDERE (inizializzati rispettivamente ad 1 ed a 0) e le primitive P e V.

PROCESSO PRODUTTORE .. ripeti

[produzione del dato] .. .. [caricamento nell’area comune] esegui P(METTERE) deposita il dato esegui V(PRENDERE)

finché devono essere prodotti dati

PROCESSO CONSUMATORE .. ripeti

[prelevamento del dato dall’area comune] esegui P(PRENDERE) preleva il dato esegui V(METTERE) [uso del dato] .. ..

finché ci sono dati

Il processo PRODUTTORE produce il primo dato e, prima di porlo nel buffer comune, va a controllare che questo sia vuoto (METTERE>0). Dato che il semaforo è stato inizializzato a 1, la primitiva P dà via libera e pone il semaforo stesso a 0.

Supponiamo ora che, mentre il dato viene prodotto e depositato nel buffer, il processo CONSUMATORE abbia bisogno di prelevare il dato; in tal caso il CONSUMATORE esegue una P sul semaforo PRENDERE, che è stato inizializzato a 0 e, poiché con il decremento viene raggiunto un valore negativo, e il processo viene messo in stato di attesa.

Quando il PRODUTTORE ha posto il dato nel buffer, esegue la V(PRENDERE) che incrementa il valore del semaforo (riportandolo a 0) e, attraverso la SIGNAL, riporta in stato di pronto il CONSUMATORE, il quale una volta entrato in esecuzione, avrà subito accesso al buffer.

Page 33: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 32 - 50

Supponiamo ora che, nell'intervallo di tempo necessario al CONSUMATORE per prelevare il suo dato, il PRODUTTORE richieda nuovamente l'uso del buffer: poiché il valore del semaforo METTERE era divenuto 0, la P (METTERE) lo fa diventare negativo e il PRODUTTORE verrà posto è stato di attesa finché il CONSUMATORE non lo risvegli era attraverso una V (METTERE).

Come si può vedere, con questo sistema di sincronizzazione il PRODUTTORE può accedere al buffer solo quando questo è vuoto ed il CONSUMATORE, invece, quando lo stesso buffer è pieno.

Questa soluzione, concettualmente molto semplice, introduce però un nuovo problema: se i tempi necessari ai due processori per produrre-consumare un dato sono molto diversi (è il caso ad esempio di dati prodotti dalla CPU e consumati dal controllore di una stampante), il processo più veloce subirà continui rallentamenti, ponendosi molte volte stato di attesa.

Per rendere meno dipendenti tra loro gli avanzamenti dei due processi, si può pensare di utilizzare un buffer multiplo in cui possono essere immagazzinati n dati. In questo caso occorrerà impedire al PRODUTTORE l'accesso al buffer solo quando l’area è piena e, in modo analogo, impedire al CONSUMATORE di cercare di prelevare un dato quando il buffer è vuoto. Per garantire questo tipo di sincronizzazione si può utilizzare ancora una soluzione proposta da Dijkstra, che diventa così una soluzione di carattere generale. In questo caso si dovrà però inizializzare il semaforo METTERE con un valore pari alla dimensione del buffer (n).

Osserviamo per concludere che, mentre nel caso di un buffer elementare erano sufficienti due semafori binari per garantire la sincronizzazione, nel caso di buffer multipli risulta indispensabile l'uso di semafori a contatore.

Sincronizzazione attraverso i messaggi

In questo caso si suppone che i due processi in interazione possano comunicare direttamente tra loro inviandosi, attraverso un opportuno canale di comunicazione, dei messaggi, detti appunto messaggi di sincronizzazione, che rappresentano l'unica risorsa realmente condivisa dai processi.

La gestione dei messaggi viene fatta dai processi attraverso le due primitive SEND e RECEIVE: con la SEND un processo chiede che il messaggio che ha prodotto venga salvato in un'apposita area affinché possa essere poi letto dal destinatario, mentre con la RECEIVE il processo destinatario andrà a verificare se gli è stato inviato qualche messaggio e, in caso positivo, lo può prelevare, ricevendo anche il nome del processo che l'ha inviato.

Possiamo quindi immaginare che la primitiva SEND abbia la forma:

SEND «messaggio» a «nome del processo destinatario»

e che l'effetto della RECEIVE sia:

RECEIVE «messaggio» da «nome del processo che l'ha inviato»

La sincronizzazione tra i processi è garantita dalla primitiva RECEIVE, la quale impone al processo che l'ha invocata di attendere fino a che non gli viene restituito il messaggio e il nome di chi l'ha inviato.

Lo stallo

Quando due o più processi interagiscono fra loro, l'avanzamento del primo dipende da quello degli altri. In una situazione di questo tipo può verificarsi il caso di due processi che non possono mai avanzare perché in attesa ciascuno di un messaggio che deve essere generato dall'altro: si parla in questo caso di stallo o abbraccio mortale (deadly embrace).

Per meglio chiarire questa situazione, facciamo riferimento ad un esempio.

Supponiamo che un processo A richieda più volte una certa risorsa R e la possa rilasciare solo dopo aver ottenuto una seconda risorsa K. Contemporaneamente un secondo processo B richiede più volte la risorsa K e la può rilasciare sul solo dopo aver ottenuto la risorsa R.

Se i tempi di utilizzo delle risorse da parte dei due processi non sono stati ben calcolati, si potrebbe verificare la seguente sequenza di eventi:

• A richiede ed ottiene l'uso di R

Page 34: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 33 - 50

• B richiede ed ottiene l'uso di K • A richiede e non ottiene l'uso di K e viene posto in attesa senza che però venga rilasciata R • B richiede e non ottiene l'uso di R (perché ancora assegnata ad A) e viene posto in attesa senza che però

venga rilasciata K.

A questo punto A potrebbe tornare in esecuzione, e quindi rilasciare R, solo quando B rilascia K. Ma questo non potrà mai accadere perché B può tornare in esecuzione, e quindi rilasciare K solo se A gli comunica che è rilasciato R.

I due processi rimangono così bloccati all'infinito in attesa di un evento che non potrà mai accadere.

Data la gravità del problema sono state sviluppate diverse tecniche che, pur introducendo alcuni inconvenienti, permettono di prevenire la situazione di stallo. Vediamone brevemente alcune.

E’ possibile ignorare il problema pretendendo che il problema non esista; la politica dello struzzo è una soluzione ragionevole se: • lo stallo capita raramente, • il costo per evitare lo stallo è troppo elevato.

Linux e Windows usano principalmente questo approccio perché fanno un compromesso tra convenienza correttezza E’ possibile, al contrario, usare un protocollo per prevenire o evitare lo stallo facendo il modo che il sistema non entri mai in stallo, per fare questo si potrà: • Prevenire: far uso di metodi che assicurino che nessuna delle condizioni necessarie allo stallo si verifichi • Evitare: fornire in anticipo al sistema operativo informazioni aggiuntive riguardanti le risorse che un

processo richiederà e userà durante la sua attività Un’ulteriore soluzione permetterà al sistema di: entrare in stallo, individuare la situazione di stallo, ed infine eseguire il ripristino.

La gestione della memoria

Il secondo livello del modello a macchine virtuali simula l'esistenza di una pluralità di unità di memoria centrale, ciascuna associata ad uno dei processori virtuali generati dal nucleo, mascherando ai livelli successivi la limitazione fisica della memoria centrale reale.

Gestione della memoria a partizioni fisse

Si consideri il seguente esempio che illustra le modalità attraverso le quali viene materialmente realizzata la convivenza dei processi all'interno della memoria centrale.

Si abbia una memoria centrale di 2000 locazioni o indirizzi, ciascuno dei quali può contenere un'istruzione in linguaggio macchina16, 500 dei quali sono occupati dal codice del sistema operativo. Restano pertanto disponibili 1500 locazioni per i processi degli utenti.

16 In realtà le dimensioni di questi dispositivi partono da almeno 500.000 indirizzi.

A richiede ed ottiene l'uso di R

B richiede ed ottiene l'uso di K

A richiede ed ottiene l'uso di R

B richiede ed ottiene l'uso di K

Page 35: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 34 - 50

Un modo di dividere questi indirizzi consiste nel ripartirli in blocchi di dimensioni fisse, per esempio 10 blocchi di 150 indirizzi. Ciascun blocco può essere libero oppure occupato da un programma di dimensione minore di 150 istruzioni. Una tabella contiene le informazioni relative a ciascun blocco: se sia libero od occupato e da quale programma. Quando si richiede l'esecuzione di un programma, il sistema operativo consulta la tabella e lo carica in un blocco libero, mentre quando un programma termina provvede a liberare il blocco corrispondente.

Questo metodo viene detto a partizioni fisse ed è il più semplice da realizzare ma presenta due limiti fondamentali:

• il numero massimo di processi che possono essere allocati in memoria è prefissato;

• un blocco contenente un processo molto breve viene considerato comunque occupato e perciò lo spazio rimanente risulta sprecato.

Gestione della memoria a partizioni variabili

Questi problemi sono evitati se non si impone un insieme fisso di partizioni, ma si caricano i programmi ovunque ci sia spazio sufficiente ad accoglierli. All'inizio il caricamento avviene in sequenza ma al procedere dell'attività lo scaricamento dei programmi terminati genera spazi di lunghezza variabile in posizioni casuali della memoria. Ne consegue che il sistema operativo deve usare una tabella più complessa della precedente, contenente informazioni sull'allocazione dei singoli processi e sugli spazi liberi disponibili.

Questa seconda politica di uso della memoria centrale è detta a partizioni variabili e sfrutta meglio della precedente la risorsa, al prezzo però di un maggior carico di lavoro svolto dal sistema operativo.

La scelta della partizione dove caricare un nuovo programma può essere fatta in due modi: • si carica nella prima zona libera sufficientemente grande per contenere il programma, usando l'algoritmo first fit (prima area libera);

• si carica nella zona libera più piccola tra quelle adatte a contenere il programma, usando l'algoritmo best fit (miglior area libera).

La seconda soluzione è meno veloce della prima ma più razionale, in quanto mantiene ampi spazi liberi per quanto più tempo possibile.

In realtà, l'analisi statistica sui due algoritmi ha mostrato come il first fit risulti essere mediamente più efficiente del best fit: infatti si perde meno tempo usando il primo posto libero e creandolo se non si trova, piuttosto che cercando tutte le volte il posto migliore.

Quale che sia la soluzione scelta, nel tempo si vengono a formare spazi vuoti tra un programma e l'altro, che sono troppo piccoli per ospitare un programma e che costituiscono perciò uno spreco. Si può ovviare a questo inconveniente ricompattando il codice in memoria quando la situazione peggiora oltre un limite fissato, per esempio quando ci sono più di x spazi liberi di dimensione inferiore ad y locazioni.

Memoria

B0

B1

B2

B3

B4

B5

P1

P2

P3

P4

Sistema Operativo

Libero

1

2

3

4

5

P1

P2

P3

P4

0

Blocco Programma

Tabella

Page 36: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 35 - 50

Finora si è supposto implicitamente che il caricamento di un programma in memoria riguardi tutto il suo codice: questo però non sempre è possibile e, se anche lo fosse, può non essere necessario.

Tecniche di overlay: paginazione e segmentazione

Nel caso di programmi molto grandi, di dimensioni confrontabili con quelle della memoria centrale, la loro allocazione sarebbe problematica e una volta avvenuta monopolizzerebbe la risorsa. Se poi la dimensione del programma fosse superiore, la sua allocazione non sarebbe possibile.

Si adottano perciò tecniche dette di funzionamento in overlay (sovrapposizione), basate sull'osservazione che è sufficiente avere in memoria centrale una porzione per volta di ciascun programma, lasciando il resto in memoria di massa, caricando altre porzioni solo quando necessario e liberando memoria quando non servono più. Si usa un meccanismo di interruzione di tipo sincrono per segnalare l'avvenuto caricamento di un segmento richiesto.

Concretamente, questo significa usare parti del disco (memoria lenta) per memorizzare informazioni che dovrebbero risiedere in memoria centrale (memoria veloce), ma che in un certo momento non sono necessarie. La memoria centrale virtualmente disponibile diviene allora più grande. I processi hanno a disposizione la memoria centrale che serve, anche se in realtà essa è solo virtuale, in quanto non corrisponde alla memoria fisica. In questo contesto, il caricamento di un programma viene realizzato con l'allocazione della prima porzione e delle informazioni che riguardano la localizzazione, sui supporti di memoria di massa, delle porzioni restanti.

I programmi che realizzano questi meccanismi si collocano al secondo livello nel modello onion skin e generano una macchina virtuale che assegna una memoria centrale di dimensioni quasi arbitrariamente grandi ad ogni processo: il limite superiore di tali dimensioni è costituito dalla capacità dei dischi, molto superiore a quella della memoria centrale fisica.

Ovviamente la memoria virtuale impone un rallentamento nell'esecuzione dovuto ai trasferimenti di codice dal disco: se questi possono essere eseguiti parallelamente alla normale attività del sistema usando gli elaboratori di canale, l'effetto complessivo sull'efficienza è però minimo.

Comunque nel progetto del sistema operativo è qualificante l'uso di algoritmi che minimizzino il numero di tali trasferimenti in modo da evitare per quanto possibile le interruzioni nell'elaborazione.

La gestione della memoria virtuale si realizza attraverso due diverse tecniche di suddivisione dei programmi in blocchi: la paginazione e la segmentazione.

Page 37: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 36 - 50

Paginazione

Ogni programma viene considerato diviso in blocchi di eguali dimensioni detti pagine logiche; analogamente la memoria centrale viene divisa in pagine fisiche di dimensioni uguali a quelle delle pagine logiche.

Una tabella riassume la situazione nella quale si trovano le varie pagine di ogni programma.

In particolare, per ogni pagina occorre sapere: • se occupa una pagina fisica; • la pagina occupata; • la posizione sul disco della pagina logica; • altre informazioni, come il flag (costituito da un bit) che indica se la pagina è stata modificata.

Ad ogni accesso alla memoria si verifica se la pagina richiesta è presente in memori centrale, e, se non lo è, il sistema operativo provvede a caricarla in una pagina fisica libera. Se tutte le pagine fisiche sono occupate, occorre scaricare una delle pagine presenti in memoria centrale (page-out).

Per migliorare l'efficienza del sistema, è opportuno che la pagina che si decide di scaricare non venga richiesta subito dopo: la decisione riguardo a quale pagina debba essere scaricata è un esempio di politica di gestione. Una scelta ragionevole potrebbe essere quella di scaricare una pagina che da un certo tempo non viene richiesta, supponendo che non lo sarà ancora per un po'.

Si può allora aggiungere, nella tabella, un flag per ogni pagina, che viene azzerato periodicamente dal sistema (per esempio ogni secondo) e posto uguale ad 1 quando la pagina viene richiesta. Quando è necessario scaricare una pagina, il sistema operativo ne sceglie una tra quelle con il segnalatore azzerato.

Per ogni pagina logica facente parte del programma, la tabella di gestione della paginazione contiene: • un bit P che costituisce il flag di Presenza: vale 1 se la pagina logica occupa una pagina fisica, 0 se non la

occupa; • un gruppo di bit IF che indicano l'Indirizzo Fisico della pagina occupata: se la pagina logica non è presente

il contenuto di questi bit non ha importanza; • un gruppo di bit ID che indicano l'Indirizzo su Disco (memoria di massa) della prima parola della pagina

logica: questo serve anche se la pagina logica è presente in memoria centrale, perché se essa contiene dati che vengono modificati durante l'elaborazione occorre ricopiarla su disco quando viene scaricata;

2

1

3 3

Memoria Centrale

00

00

11

MM

xxxx ---- 00

---- 11

---- 11

IIDD IIFF PP

Modifica MM

Indirizzo su disco IIDD

Indirizzo fisico IIFF

Presenza pagina PP

Page out

Programma P1 Sistema Operativo

P1 - 2

P1 - 1

P2 - 3

Libero

Libero

Libero

P2 - 2

P2 - 1

Libero

Page 38: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 37 - 50

• un bit M che costituisce il flag di Modifica: vale 0 fintanto che nessuna parola della pagina è modificata dal momento in cui questa è stata allocata in memoria l'ultima volta; diventa 1 alla prima modifica. Se al momento di scaricare la pagina, M vale zero si può evitare la ricopiatura su disco risparmiando tempo.

Al momento della richiesta di una pagina logica, la consultazione della tabella permette di verificare se la pagina logica è allocata e, se non lo è, ne viene effettuato il caricamento a cura del sistema operativo; nella stessa tabella si legge l'indirizzo su memoria di massa della pagina richiesta.

Il vantaggio principale della paginazione è la semplicità dovuta al fatto che tutte le pagine, logiche o fisiche, hanno eguali dimensioni, mentre il difetto più importante è l'arbitrarietà con cui le pagine logiche vengono generate suddividendo il programma, il che generalmente aumenta il numero di chiamate tra pagine diverse e perciò diminuisce l'efficienza.

È opportuno precisare due concetti lasciati finora sottintesi: • anche le routine del sistema operativo risiedono in memoria centrale; • le tabelle delle pagine occupano anch'esse memoria.

La paginazione riguarda solo la parte di memoria centrale libera, nel senso che le pagine contenenti il sistema operativo e le tabelle non devono mai essere scaricate. In realtà alcuni moduli di sistema operativo possono venire scaricati in caso di bisogno perché il loro uso non è molto frequente.

Le pagine contenenti il nucleo del sistema operativo (il codice e i dati sui quali opera) restano fissate nella memoria e non vengono mai paginate su disco.

Il meccanismo che impedisce il paging su disco di alcune parti della memoria viene indicato con il termine pinning (letteralmente, puntare con uno spillo).

Segmentazione

Con questa seconda tecnica di gestione della memoria virtuale la suddivisione del programma viene effettuata sulla base di criteri logici e può essere controllata dal programmatore. Ciascun blocco risultante da tale suddivisione ha lunghezza arbitraria, talvolta limitata a valori inferiori ad una lunghezza massima, e viene detto segmento.

Un programma non molto complesso può essere diviso in un segmento che contiene i dati ed un segmento per il codice da eseguire, mentre al crescere della complessità è opportuno raggruppare in segmenti le procedure che più frequentemente si chiamano tra loro, e i dati che vengono più spesso usati insieme. La ripartizione deve cioè seguire il criterio del minimo numero di chiamate tra segmenti diversi.

Compatibilmente con tale criterio è bene ridurre le dimensioni dei segmenti, perché ciò facilita il compito del sistema operativo.

Page 39: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 38 - 50

La memoria centrale non viene divisa in blocchi statici predefiniti ma in blocchi aventi dimensioni variabili. Questo conduce immediatamente a due conseguenze negative: da un lato la memoria diventa soggetta a frammentazione, e dall'altro le tabelle da impiantare per gestire la memoria virtuale con i segmenti sono più complesse da usare che nel caso della paginazione.

Per ogni segmento dei programmi da eseguire occorre sapere: • se è presente in memoria; • qual è l'indirizzo dove inizia; • dove si trova sul disco; • le sue dimensioni.

È utile disporre anche di una tabella delle aree di memoria libere da consultare ed aggiornare ad ogni richiesta di allocazione di nuovi segmenti e ad ogni terminazione di programma.

La tabella per la segmentazione contiene le informazioni richieste per ogni segmento ossia:

• un flag di Presenza P (un bit); • l'Indirizzo di Impianto IDI del segmento, cioè l'indirizzo della locazione di memoria centrale che contiene

la prima parola del segmento; • la Dimensione del Segmento DS che serve quando si deve allocare il segmento, per trovare un'area libera

adatta; • l'Indirizzo su Disco ID del segmento.

La segmentazione presenta come la paginazione vantaggi e svantaggi impliciti, tra questi ultimi evidenziamo i seguenti: • la memoria si frammenta rapidamente, dato che quando si scarica un segmento esso viene rimpiazzato

normalmente da un segmento più piccolo, lasciando dello spazio inutilizzato. A questo si può ovviare con routine che provvedano a compattare tale spazio spostando i segmenti in modo che siano adiacenti (garbage collection).

• non è semplice costruire con scaricamenti aree libere di dimensioni assegnate.

L'esempio della figura seguente mostra un'immagine della memoria in un istante in cui contiene diversi segmenti: si osservi che per poter caricare un nuovo segmento che richiede 100 locazioni occorre scaricare due segmenti. Un modo semplice di risolvere il problema consiste nel partire dall'inizio e scaricare segmenti

Sistema Operativo

P1 - 2

P1 - 1

P2 - 3

Libero

Libero

Libero

P2 - 2

P2 - 1

Libero

0

Memoria Centrale

00

00

11

MM

xxxx

----

----

IIDD

---- ---- 00

xxxx 11

xxxx 11

DDSS IIDDII PP

Indirizzo su disco

Modifica

Dimensioni del segmento

Indirizzo d’impianto nella RAM

Presenza pagina

IIDD

MM

DDSS

IIDDII

PP

2

1

3

Programma P1

500

600

650

804

1008

1232

Page 40: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 39 - 50

finché si raggiunge la dimensione voluta, ma in questo modo i segmenti all'inizio vengono penalizzati costantemente, mentre quelli alla fine vengono scaricati molto raramente.

Un modo migliore può consistere nello scaricare segmenti a partire da un punto variabile della memoria: la prima volta dalla locazione 0, la seconda dalla locazione X, la terza dalla locazione 2X e così via, in modo da garantire che tutta la memoria (e quindi tutti i segmenti) venga coinvolta.

Ancora meglio, si possono assegnare dei punteggi ad ogni segmento, e favorire lo scaricamento dei segmenti con punteggi peggiori.

È chiaro che per ottenere prestazioni migliori occorre complicare notevolmente gli algoritmi di controllo.

Questa osservazione è valida in generale: qualsiasi operazione si possa svolgere attraverso un software, si può anche realizzare via hardware con prestazioni tanto migliori quanto più l'operazione è complessa. Il prezzo da pagare consiste nel fatto che l'hardware ha costi di sviluppo molto più elevati, giustificati solo in caso di produzioni elevate o di esigenze molto particolari, ed è molto più difficile e costoso da modificare una volta realizzato.

Segmentazione con paginazione dinamica

È possibile anche combinare le due tecniche presentate, suddividendo in pagine ciascun segmento:

• si aggiunge ai vantaggi della segmentazione la facilità d'uso della memoria paginata,

• si ha maggiore complicazione delle routine software per la gestione della memoria virtuale e di un aumento del carico di lavoro per il sistema operativo.

Le periferiche

Dispositivi hardware

Esistono in commercio diversi dispositivi periferici di ingresso/uscita, che si possono collegare all'unità centrale: terminali video, tavolette grafiche, plotter, stampanti, lettori di codici a barre.

Come è noto le principali componenti dell’unità centrale, in particolare CPU, memoria e dispositivi di I/O, sono interconnesse tramite bus che consentono il trasferimento di indirizzi, dati e istruzioni e segnali di controllo mediante la trasmissione di segnali. Il bus è dunque un tipo di canale (channel) che può essere di tipo seriale o parallelo.

Un solo bus può collegare tra loro più dispositivi. Le connessioni elettriche del bus possono essere realizzate direttamente su circuito stampato oppure tramite un apposito

Page 41: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 40 - 50

cavo. Nel primo caso, se il bus adotta una trasmissione parallela, spesso è riconoscibile a vista perché si nota sul circuito un nutrito gruppo di piste compatte e disposte in parallelo che vanno a toccare i vari componenti della scheda elettronica. Un bus può adottare anche una trasmissione seriale. Il progredire della tecnologia sembra preferire questa forma a quella parallela, che tra l'altro soffre di maggiori ingombri e spesso anche di maggiori costi

I bus di I/O hanno caratteristiche specifiche che hanno ripercussioni rilevanti sul resto del sistema in quanto tutti i dispositivi esterni da connettere (dischi, nastri, stampanti, video, etc.) devono essere collegati tramite opportune schede di interfaccia (dotate di opportuni connettori) ad essi compatibili. Ai bus possono essere anche connessi più componenti per gestire la comunicazione con i dispositivi periferici (controller). I dispositivi collegati al bus possono trovarsi sia nella condizione di dover trasmettere (master) che in quella di dover ricevere (slave). Ad esempio quando la CPU ordina al controller del disco di leggere o scrivere un blocco, la CPU si comporta da master ed il controller da slave.

Nei sistemi più evoluti quindi la CPU non gestisce direttamente le operazioni di I/O, ma le delega ad un'interfaccia intelligente o ad un coprocessore denominato processore di input/output o controller di periferica. Il processore è detto anche genericamente canale di I/O. Il canale di I/O effettua autonomamente le operazioni di I/O mentre la CPU gestisce soltanto le operazioni di avvio e di controllo del canale mentre il processore di I/O si occupa esclusivamente all'esecuzione delle operazioni di I/O. Spesso il controller è adibito alla gestione di più periferiche.

I controller delle periferiche sono presenti sin dalla prima generazione di computer elettronici in quanto normalmente la periferica è molto più lenta dell'unità di elaborazione centrale. La presenza del controller della periferica evita quindi che l'unità di elaborazione centrale, sollevata dalla gestione delle periferiche, subisca pesanti rallentamenti; in questo modo la CPU è libera di utilizzare tutta la sua capacità di calcolo in compiti in cui è richiesta tale capacità.

La funzione delle periferiche è dunque quella di trasmettere dati fra l’elaboratore ed i suoi utenti. Gli aspetti fondamentali di un sistema di I/O si riferiscono alle modalità di trasferimento dei dati al mezzo periferico e viceversa ed a come viene tenuto conto della diversa velocità operativa dell’unità centrale rispetto alle periferiche. Due importanti schemi di controllo delle operazioni di I/O sono: • interruzione di programma

L'interruzione (interrupt), come già detto, è un meccanismo con cui una periferica può segnalare all'unità centrale che ha completato la trasmissione dati. L'unità centrale di elaborazione, quando riceve un segnale di interruzione da un mezzo periferico, interrompe l'esecuzione del programma che è in corso (programma in stato di esecuzione) e comincia ad eseguire un altro programma appositamente definito per la gestione di quel mezzo. Questo secondo programma termina con una istruzione che fa riprendere l'elaborazione del primo programma dal punto in cui era stato interrotto. Con questa tecnica è possibile far compiere all'unità centrale elaborazioni utili mentre è in corso l'operazione di ingresso/uscita e allo stesso tempo servire la periferica appena questa è stata completata.

• accesso diretto alla memoria (DMA) I dispositivi di I/O più veloci, supportano una modalità di trasferimento dei dati da e verso la memoria centrale detta DMA (Direct Memory Access) che non richiede l’uso della CPU poiché è gestito da uno specifico controller. La tecnica di accesso diretto alla memoria (Direct Memory Access, DMA) implica sia il fatto che il trasferimento dei dati avviene direttamente fra la memoria centrale e l'unità periferica, sia il fatto che esso non viene controllato dal programma dato per dato.

La parte meccanica viene controllata da un controllore del dispositivo (device controller) o adapter

Page 42: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 41 - 50

È il metodo preferito quando si devono trasferire grosse moli di dati. Una circuiteria apposita (DMA Controller) si preoccupa di eseguire il trasferimento di dati da una periferica alla memoria (o viceversa). La circuiteria deve essere in grado di fungere da bus master, ossia deve generare gli indirizzi ed i segnali di controllo secondo la tempistica opportuna.

Il DMA Controller deve inoltre essere in grado di negoziare con la CPU l’acquisizione del controllo del bus ed il suo rilascio. Il DMA, tramite il controller di accesso diretto (DMAC), ha quindi il compito di gestire i dati passanti nel bus permettendo a periferiche che lavorano a velocità diverse di comunicare senza assoggettare la CPU a un enorme carico di interrupt che ne interromperebbero continuamente il rispettivo ciclo di elaborazione. Il trasferimento tramite canali DMA, essendo eseguito da dispositivi hardware appositi, è caratterizzato da un'alta velocità ed è quindi associato ad unità periferiche veloci come controller di unità a disco,

schede grafiche e schede audio, la porta della stampante LPT1. Utilizzando il "Gestione delle Periferiche" è possibile visualizzare l'assegnazione dei canali DMA.

Ogni dispositivo installato nel computer utilizza uno o più "canali" per comunicare con la CPU. Nel sistema Plug and Play gli indirizzi IRQ, DMA, I/O, e gli indirizzi di memoria sono assegnati dinamicamente all'accensione del PC.

Mentre l'unità centrale è responsabile delle vere e proprie elaborazioni dati, il processore di I/O provvede al trasferimento dei dati fra la memoria centrale e i dispositivi periferici.

La comunicazione fra l'unità centrale e il processore di I/O generalmente segue questo schema:

• l'unità centrale fa iniziare l'operazione di I/O attivando il processore di I/O, indicandogli quale mezzo periferico deve usare e l'indirizzo in memoria centrale a partire dal quale può trovare altre istruzioni;

• il processore di I/O legge dalla memoria centrale le istruzioni che deve eseguire (queste istruzioni sono chiamate comandi per distinguerle dalle istruzioni eseguibili dall'unità centrale), le interpreta ed esegue sul mezzo le operazioni indicate.;

• l'unità centrale può inoltre conoscere lo stato dell'processore di I/O e la fase di avanzamento delle operazioni, con opportune istruzioni che esaminano il registro di stato dell'processore di I/O, in modo da poter prendere decisioni circa la gestione di varie operazioni di I/O.

Il gestore delle periferiche

Il terzo livello del sistema operativo ha come obiettivo principale quello di gestire le periferiche fornendo all’utente una visione astratta in modo tale che l’utente: • abbia l’impressione di essere l’unico utilizzatore della periferica, • effettui le operazioni di I/O in maniera indipendente dalle caratteristiche fisiche del dispositivo usato.

Page 43: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 42 - 50

Il gestore delle periferiche (device management) consente quindi di:

• definire dispositivi virtuali secondo alcuni criteri principali: o mettere a disposizione le

capacità delle periferiche nascondendo i reali meccanismi con i quali esse colloquiano con il processo, attraverso primitive di tipo generale ("leggi", "scrivi", "apri il canale", "chiudi") più potenti delle funzioni di cui dispongono le periferiche stesse. Per esempio, la scrittura di una stringa di caratteri su una stampante è un'operazione che richiede un numero elevato di operazioni elementari della stampante.

o gestire i più comuni contrattempi che si possono verificare nelle operazioni stesse (errori di trasmissione, periferiche disattivate).

In questo modo l'utente, attraverso le sue applicazioni, può utilizzare le periferiche senza preoccuparsi delle caratteristiche fisiche e delle operazioni fisiche che vengono eseguite per svolgere la funzione logica richiesta: lettura di un dato da un'unità di input o scrittura di dati su un'unità di output.

• sovrintendere alle operazioni dei processori di I/O che, come abbiamo visto, sono dei processori dedicati che eseguono esclusivamente i programmi di canale.

I moduli associati alle operazioni di gestione di una singola periferica sono conglobati in un programma detto handler17 della periferica che ha il compito di:

• creare i programmi di canale, • inizializzare le operazioni di I/O, • gestire le interruzioni prodotte dalla periferica ed ottimizzare il processo di trasmissione.

I programmi di canale, una volta memorizzati in memoria centrale, in modo analogo ai programmi che sono eseguiti dall'unità centrale, vengono eseguiti dal processore di I/O comunicando poi all'unità centrale che ha finito di eseguire il proprio programma tramite un'interruzione.

Come ottimizzare la gestione delle periferiche

Sarebbe auspicabile disporre di un processore di canale per ogni tipo di periferica ma, molto spesso, il numero di canali utilizzati all'interno del sistema è di gran lunga inferiore a quello delle periferiche.

È evidente a questo punto che, per effettuare il trasferimento dati dalla memoria ad una periferica, è indispensabile che esista almeno una linea che unisca la memoria alla periferica, in modo che quest'ultima possa essere assegnata al processore di I/O. Per decidere se un percorso può essere assegnato ad un processore di I/O, il controllore del traffico di I/O dovrà verificare lo stato di ogni dispositivo, consultando la lista dei descrittori delle periferiche e dei canali. Così, ad esempio se un processo P1 vuole accedere al disco D1, verrà occupata alla linea che unisce la memoria al disco attraverso il canale A. Se a questo punto un secondo processo P2 chiede di accedere al disco D2, questo gli sarà negato, poiché l'unico percorso che unisce D2 alla memoria passa attraverso il canale A già occupato. Si vengono così a creare dei "colli di bottiglia" che possono pregiudicare il buon rendimento del sistema. Per ovviare a quest'inconveniente sono state sviluppate diverse tecniche hardware tendenti a minimizzare questo fenomeno e quindi ad ottimizzare l'uso dei dispositivi di I/O.

17 pron. [hændlǩȼ]

Memoria Centrale

Canale 1

Disco 1

Disco 2

Disco 3

Nastro 2

Nastro 1

Page 44: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 43 - 50

Periferiche indipendenti

Una prima soluzione consiste nell'utilizzare delle periferiche dotate di opportuni dispositivi, i quali consentono alle stesse di effettuare alcune delle operazioni necessarie per il trasferimento dati, senza l'assistenza costante da parte del canale.

In questo modo, mentre la periferica opera autonomamente, il processore di canale potrebbe essere usato per inizializzare una nuova operazione di I/O su una periferica diversa.

Ad esempio, si potrebbe pensare di sfruttare la capacità delle unità a disco di effettuare autonomamente il posizionamento della testina, per ridurre i tempi di occupazione del canale. Infatti, mentre l'unità a disco effettua il posizionamento della testina in base all'indirizzo ricevuto dal canale, quest'ultimo potrebbe essere assegnato alla gestione di operazioni similari su altre periferiche.

Per poter sincronizzare opportunamente le operazioni di I/ O su tutte le periferiche collegate allo stesso canale, si usano opportuni segnali di interruzione (interrupt), che vengono attivati ogni volta che un dispositivo (canale o periferica) ha terminato il proprio lavoro.

Queste interruzioni, dette interruzioni di fine I/O vanno ad influenzare lo stato di ciascuno dei componenti presenti sulla linea di trasmissione, dando una panoramica completa dei dispositivi disponibili per nuove operazioni:

1. un segnale di "fine uso del canale", indicherà che il processore di canale è libero, mentre lascerà invariato lo stato della periferica che sta ancora lavorando autonomamente e quindi è ancora occupata.

2. un segnale di "fine operazione di I/ O", indicherà che sia processore di canale che la periferica risultano liberi e di conseguenza che l'intera linea è disponibile.

Con un'organizzazione di questo tipo, sarà compito del sistema operativo andare a controllare, ogni volta che viene richiesta un'operazione di I/ O per verificare se tutti i componenti che formano la linea di trasmissione sono disponibili.

Periferiche bufferizzate

Una seconda soluzione consiste nell'usare periferiche dotate di aree di memoria autonome (buffer), in cui depositare temporaneamente i dati nel corso delle operazioni di I/O.

Ciò consente di ridurre i tempi morti legati alla minore velocità della periferica rispetto al sistema e di conseguenza utilizzare il canale solo per il tempo strettamente necessario all'invio dei dati lungo la linea di trasmissione.

Così, ad esempio, se si utilizza una stampante bufferizzata, il canale non dovrà attendere la fine dell'operazione di stampa di un dato, prima di inviare il successivo, ma li potrà trasmettere in sequenza fino al completo riempimento del buffer.

In questo modo non saranno necessarie continue sospensioni nella trasmissione e l'operazione di I/0 potrà logicamente considerarsi conclusa dopo l'invio dell'ultimo dato, anche se in realtà non tutti i dati trasmessi sono ancora stati stampati.

Tecniche di allocazione a periferiche virtuali

Il problema di utilizzare in modo ottimale le periferiche di tipo dedicato ha suggerito l’idea di convertirle in risorse condivise, in modo tale da poter far avanzare parallelamente diversi lavori che le richiedono.

In pratica ciò significa simulare le apparecchiature di I/O con opportune aree di memoria su disco, su cui depositare temporaneamente i dati in ingresso o in uscita, creando così delle periferiche virtuali.

Il gestore delle periferiche può quindi offrire, a diversi utenti, la possibilità di aumentare in modo virtuale il numero delle periferiche a disposizione attraverso lo spooling: il termine deriva da SPOOL acronimo di Simultaneous Peripheral Operations On Line, cioè sistema di operazione periferica simultaneamente in linea. La tecnica di spooling quindi consente a diversi processi l'uso contemporaneo della stessa periferica.

Page 45: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 44 - 50

Nei sistemi interattivi multiutente è frequente il caso in cui sono collegate stampanti in numero inferiore a quello dei terminali, perciò se più utenti richiedono contemporaneamente l'esecuzione di comandi che generano output stampato, ci si viene a trovare in una situazione di conflitto.

Questa può essere risolta generando gli output dapprima su disco (file di spool) in aree riservate ai vari utenti e lanciandone successivamente la stampa di uno per volta.

L'ordine di stampa segue la logica della coda, FIFO (First In First Out), perciò vengono stampati gli output nell'ordine con cui i relativi programmi terminano. Tale ordine può essere alterato per mezzo di meccanismi di priorità.

In questo modo tutti gli utenti possono portare a compimento l'esecuzione dei loro programmi che prevedono la stampa su carta, anche se la stampante in quel momento non è disponibile, perché l'output del programma viene messo in un file della coda di spool e verrà mandato alla stampante appena questa si sia resa disponibile.

L'utente, attraverso lo spool, ha come l'impressione di avere a disposizione la risorsa richiesta, anche se in realtà questo avviene solo a livello virtuale, in quanto la periferica fisica viene assegnata a più utenti in tempi diversi.

Si osservi che il meccanismo di spool non è rigorosamente a divisione di tempo, in quanto non esiste il time slice. L'effetto che ne consegue è però molto simile, dato che come il time sharing moltiplica il numero delle risorse virtuali.

Il file system

Il file system, quarto livello del modello a macchine virtuali, provvede alla virtualizzazione delle memorie di massa e genera una macchina costituita da una pluralità di dispositivi indipendenti l'uno dall'altro, ciascuno dei quali ha a disposizione tutte le risorse virtuali che gli possono occorrere. Tutto ciò che viene registrato su memoria di massa prende il nome di file: testo, programma, comando, routine, dati, immagine, filmato, suono.

In particolare nelle applicazioni gestionali i file di dati sono organizzati a record (per esempio, in un archivio anagrafico, i dati relativi ad una persona) e su di essi si opera in modo analogo a quanto si fa con gli archivi cartacei, creandone di nuovi e distruggendoli quando non servono più, aggiungendo o togliendo record o modificandoli; le operazioni di apertura e chiusura consentono rispettivamente l'inizio e la terminazione delle operazioni su un determinato file.

Il file system consente all'utente, e in particolare al programmatore, di riferirsi ai file attraverso nomi simbolici di identificazione, senza preoccuparsi degli aspetti riguardanti la gestione del supporto di memoria di massa, o della registrazione fisica dei dati sul supporto.

Le principali funzioni del file system riguardano quindi i seguenti aspetti:

• gestire in modo ottimale lo spazio disponibile della memoria di massa per le registrazioni richieste dagli utenti;

• garantire all'utente l'accesso ai dati contenuti in un file, in modo molto veloce, anche in presenza di richieste di accesso allo stesso file da parte di più utenti;

P1 P2 P3

Sistema interattivo multiutente

Files di SPOOL su disco

Ordine di stampa FIFO (First In First Out)

Page 46: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 45 - 50

• fornire agli utenti meccanismi di protezione dei file, a diversi livelli (protezione dalla lettura del file, protezione dalla scrittura e cancellazione del file, protezione dalla esecuzione di programmi), rispetto a interventi dannosi o non autorizzati da parte di altri utenti;

• rendere disponibili in modo semplice le operazioni di uso comune sui file, quali la copia di un file, la cancellazione, il cambio del nome, l'elenco dei file presenti sul supporto di memoria di massa, la visualizzazione delle informazioni di un file (spazio occupato, data di creazione, protezioni).

I più comuni supporti di memoria di massa sono i dischi magnetici, manipolabili dal sistema attraverso dispositivi detti controller (controllori) che realizzano le operazioni di accesso tramite motori e testine magnetiche.

I dischi si considerano divisi in anelli concentrici detti tracce e in fette radiali dette settori: l'intersezione tra una traccia ed un settore è detta zona e contiene un certo numero di byte. I motori posizionano la testina su un byte

per volta, quando vengono fornite loro le coordinate di tale byte (traccia, settore e posizione nella zona). Possiamo vedere quindi come operazioni elementari della macchina il posizionamento e l'elaborazione di un byte.

Il file system consente di riferirsi alle informazioni registrate in termini di identificatori piuttosto che di indirizzi fisici, adoperando allo scopo le directories o tabelle dei

descrittori che contengono per ciascun file alcuni dati significativi quali: • l'identificatore (il nome del file); • informazioni sulla posizione dove esso è collocato sul disco; • la data di creazione; • il numero di record contenuti; • la dimensione del record; • le modalità consentite di accesso (esecuzione, lettura,

scrittura, accesso vietato), differenziate per i vari utenti.

Ciò significa per esempio che alcuni utenti sono autorizzati a leggere il file ma non possono modificarlo. Inoltre possono essere memorizzate le password (parole chiave) di accesso al file.

Per ridurre i problemi di frammentazione della memoria di massa, i file possono essere ripartiti in blocchi logici allocati in blocchi fisici di eguali dimensioni distribuiti all'interno del supporto, quindi nella tabella dei descrittori occorrerà specificare in una lista gli indirizzi di inizio dei vari blocchi fisici occupati dal file.

I file vengono quindi divisi in blocchi di dimensioni uguali fra loro e, analogamente, i dischi vengono divisi in aree della stessa dimensione. Dovendo scrivere un file sul disco non è necessario che esista uno spazio contiguo grande a sufficienza per tutto il file, ma basta che ci sia un numero di aree libere uguale o superiore al numero di blocchi del file.

Una directory deve essere memorizzata anch'essa su disco, perché le informazioni che contiene non devono andare perse allo spegnimento del sistema. D'altra parte, per essere consultata dal sistema operativo deve essere ricopiata in memoria centrale, dove viene arricchita con dati riguardanti lo stato dinamico dei file in essa descritti, in particolare se sono aperti, se in lettura o scrittura e qual è stato l'ultimo record indirizzato.

Questo richiede che la totalità dei descrittori dei file presenti sui supporti vengano raggruppati su più directories realizzando un doppio vantaggio:

• non dover occupare molta memoria centrale con descrittori inutili;

• poter raggruppare nella stessa direttrice file tra loro correlati, per esempio tutti i file creati da un certo utente.

Inoltre è possibile assegnare lo stesso nome a due file che si trovano in direttrici diverse.

Page 47: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 46 - 50

I sistemi operativi Unix, Linux e Windows usano un sistema gerarchico di directories strutturato ad albero. Esso viene realizzato osservando che una directory può essere vista come un file e pertanto può essere descritta in un'altra direttrice e può contenere descrittori di altre ancora.

Una directory equivale ad un file nel senso che si tratta di dati scritti sul disco in una certa posizione: si tratta quindi di uno o più blocchi, simili a quelli che costituiscono i file, scritti in aree del disco, esattamente come i file.

La directory di livello più elevato è detta root (radice), non è contenuta in altre directories ed è allocata in posizione fissa e nota al sistema, mentre quelle dei livelli inferiori possono essere dislocate ovunque sui supporti e vengono raggiunte attraverso le genitrici che ne contengono i descrittori.

La struttura ad albero risulta composta da nodi non terminali (le directories) e nodi terminali (foglie) che sono i file veri e propri.

I movimenti lungo l'albero corrispondono a caricamenti in memoria centrale delle diverse direttrici: quella presente in un certo momento è detta directory corrente ed i file in essa descritti possono essere individuati dal loro identificatore. Per individuare file descritti in altre direttrici si dovrà invece indicare il loro pathname (nome di file espresso attraverso un cammino), elencando gli identificatori di tutti i nodi che uniscono la directory corrente con il file desiderato.

Quando il nome del file viene descritto elencando tutti i nodi che occorre attraversare a partire dalla root fino ad arrivare al file, si dice che viene usato il pathname assoluto o globale. Quando invece l'attraversamento inizia dalla directory corrente, si dice che il nome del file viene descritto con il pathname relativo.

Con riferimento alla figura precedente, il pathname assoluto del file leggimi.txt è il seguente (usando la notazione del sistema Linux con il carattere di backslash per la root e per il separatore): \Documenti\5AMercurio Francese\Testi\leggimi.txt.

Se invece la directory corrente è la directory Documenti, il pathname relativo del file leggimi.txt è: 5AMercurio Francese\Testi\leggimi.txt.

Alcuni sistemi operativi, in particolare Linux, consentono di trattare le periferiche con le stesse procedure usate per i file, permettendo di associare ai dispositivi di I/O descrittori simili a quelli usati per i file veri e propri.

Quando un utente si connette all'elaboratore, il sistema operativo gli assegna due file, che, operando con un terminale, corrispondono alla tastiera e al monitor e vengono considerati come file standard di ingresso e di uscita (standard input e standard output). Il monitor viene utilizzato anche come file dove vengono mandati i messaggi di errore (standard error).

Root

Nodo non terminale

Nodo terminale

(foglia) = File

Struttura ad albero

Page 48: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 47 - 50

Questo significa che, in mancanza di specifiche diverse, espressamente indicate dall'utente, il sistema acquisisce dati e comandi dalla tastiera e invia l'output al video.

L'utente ha la possibilità di indicare al sistema file di input o output alternativi a quelli standard e si parla allora di ridirezione dell'input o dell'output.

Nella fase di messa a punto di un programma, per esempio, può risultare comodo scrivere su un file i dati di ingresso usati per provare il programma e ridirigere l'input del programma su tale file. In questo modo si evita di dover digitare tutti i dati ad ogni esecuzione.

In modo analogo si può ridirigere l'output, per esempio verso una stampante.

L'interprete di comandi

L'ultimo livello del modello a macchine virtuali è costituito dall'interprete comandi o shell, un programma che riceve in ingresso le richieste di esecuzione di operazioni, espresse usando il linguaggio comandi.

I sistemi più semplici limitano i comandi possibili alle richieste di esecuzione di programmi di sistema o scritti dagli utenti.

Nel caso del sistema operativo Linux il linguaggio comandi permette la scrittura di veri e propri algoritmi strutturati (script): comprende infatti costrutti di selezione, iterazione e operazioni di assegnamento e consente di calcolare espressioni.

L'interprete del prompt dei comandi nel sistema operativo Windows contiene un insieme minimale di comandi per la gestione del personal computer; permette anche di scrivere script (i file BAT) contenenti la struttura di controllo if per la selezione semplice.

L'evoluzione dei sistemi operativi ha portato con sé anche un crescente miglioramento delle modalità di interazione tra utente e sistema operativo, indicate con il termine interfaccia utente, cioè il modo con il quale l'utente può chiedere al sistema operativo l'attivazione di funzioni.

Nei primissimi computer, dove il sistema operativo era quasi inesistente, la maggior parte delle operazioni venivano attivate mediante l'uso di interruttori. Successivamente venne introdotto l'uso della telescrivente, cioè di una tastiera e di un rotolo di carta, con i quali avveniva il colloquio tra utente e computer. I comandi erano molto sintetici nel lessico e avevano una sintassi molto limitata.

L'interattività con il sistema operativo venne in seguito migliorata con l'introduzione dei videoterminali. Il terminale dedicato all'interazione con il sistema operativo veniva indicato con il termine console, cioè quadro di controllo, parola rimasta tutt'oggi nella terminologia corrente dell'informatica.

Nelle versioni moderne dei sistemi operativi l'interprete di comandi presenta all'utente sul video una riga sulla quale l'utente può scrivere da tastiera il comando (riga comandi): all'inizio della riga viene evidenziato un insieme di caratteri che richiamano l'attenzione dell'utente (prompt).

Una componente importante degli interpreti tradizionali a riga comandi è l'analizzatore sintattico, un programma che verifica la correttezza formale (lessico e sintassi) delle richieste dell'utente.

In anni più recenti l'interfaccia con l'utente presenta sul video un menu di scelte possibili (spesso elencate utilizzando la lingua nazionale) all'interno delle quali l'utente

può scegliere la funzione che vuole chiedere al sistema operativo: tipicamente sono menu a tendina (pull-down), cioè sono presentati sul video dall'alto verso il basso, oppure menu pop-up, cioè compaiono all'interno dello schermo video.

Ancora più recentemente, soprattutto nell'ambito dei personal computer, si è consolidato l'uso di interfacce grafiche per stabilire il colloquio con il sistema operativo, per esempio con il sistema Windows: sul video vengono presentati alcuni schemi grafici (icone, finestre e puntatori) che ricordano le prestazioni attivabili dal

Page 49: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 48 - 50

sistema operativo. L'utente, in modo facile, sceglie la funzione desiderata selezionando l'icona corrispondente mediante strumenti di puntamento guidati dal mouse.

L'evoluzione dell'interfaccia utente risponde alla necessità di conciliare il crescente raffinamento dei sistemi operativi e l'ampliamento delle sue funzioni con l'estensione del numero di utenti finali del computer: l'interazione con il sistema operativo non è più riservata a specialisti di informatica e perciò l'interfaccia deve essere il più possibile amichevole (user friendly).

L'utente viene collocato a un livello molto lontano dall'hardware e dal nucleo del sistema operativo: le caratteristiche reali di funzionamento della macchina e tutti i problemi ad esso collegati rimangono nascosti all'utente finale, il quale può così concentrare la sua attenzione sull'applicazione richiesta.

La tecnologia moderna è già ora in grado di prefigurare un'ulteriore evoluzione dell'interfaccia utente basata sull'interazione vocale.

Processi padre e processi figlio Il processo di esecuzione dell'interprete comandi viene considerato il processo padre degli altri processi che verranno lanciati nel corso della sessione di lavoro. Quando viene richiesta l'esecuzione di un programma da linea comandi (cioè da tastiera), l'interprete comandi apre un processo per lanciare l'analizzatore sintattico e trasformare la riga di comando digitata dall'utente in un insieme di parametri da restituire al processo padre (l'interprete comandi). Questo riprende il controllo e, se il processo figlio è terminato senza errori, apre un altro processo per eseguire il comando vero e proprio. In un sistema operativo multitasking è possibile aprire più processi che vengono eseguiti contemporaneamente: ciascuno di questi a sua volta può lanciare l'esecuzione di altri processi, perciò lo stato in cui si trova l'utente in un dato istante si può vedere come un albero, la cui radice è costituita dall'interprete comandi e i nodi sottostanti dai processi figli, figli dei figli e così via. A partire dall'accensione del computer, vengono attivati molti processi in successione, ciascuno dei quali è processo figlio rispetto al precedente. Quando il calcolatore viene acceso, occorre che alcune operazioni vengano eseguite per metterlo in condizione di funzionare normalmente. In particolare occorre caricare il sistema operativo in memoria centrale, copiandolo dai supporti di memoria di massa sui quali è permanentemente registrato. A ciò provvede un programma registrato su ROM chiamato IPL (Initial Program Loader, caricatore di programma iniziale) che assume il controllo della CPU all'accensione. La registrazione su ROM è permanente, non scompare cioè allo spegnimento del sistema, al contrario di quanto avviene per la RAM che costituisce la memoria utente. L'IPL realizza quindi il caricamento del sistema operativo in memoria centrale eventualmente attraverso un solo modulo di sistema, il quale assume il controllo e carica il resto. Il caricamento viene chiamato bootstrap, termine del gergo informatico che deriva dal nome che in americano viene dato alle linguette sul lato posteriore degli stivali da cowboy. Bootstrapping potrebbe essere tradotto con "sollevarsi tirandosi per le linguette degli stivali", visualizzando così il fatto che il sistema operativo provvede a caricare sé stesso in memoria centrale. Talvolta il caricamento del sistema operativo non è completo ma riguarda solo i moduli di livello più basso, mentre gli altri vengono gestiti a pagine o a segmenti.

In fase di bootstrap viene caricato in memoria il nucleo (kernel) oltre ad altro soft necessario alla fase di partenza del sistema.

Prima di tutto viene mandata in esecuzione la parte del nucleo che gestisce tutti gli processi (gestore dei processi).

Questo primo processo che è il generatore di tutti gli altri processi è sempre presente in memoria e ha la massima priorità nell'ordine di esecuzione.

Esso attiva la fase di inizializzazione del sistema, per il controllo delle risorse dispone di attivazione delle linee collegate ai terminali.

Per ogni terminale viene poi attivato un processo di connessione che lo collega lo mente all'unità centrale e fa apparire sul video la maschera di identificazione dell'utente (login o logon). L'utente fornisce il nome ed eventualmente la password: i dati forniti vengono controllati e in caso positivo viene fornito a ciascun utente un ambiente di lavoro (shell) con il quale è possibile ottenere dal sistema operativo, con opportuni comandi, le funzioni necessarie all'applicazione richiesta.

La shell rimane attivata sul terminale fintanto che l'utente decide di scollegarsi (logout).

Page 50: sistema operativo v2014 - lnx.poggiodelpapa.comlnx.poggiodelpapa.com/appunti/s_o/sistema_operativo_v2014.pdf · 1 1982 - Definizione del protocollo TCP/IP e della parola "Internet"

Pag. 49 - 50

Occorre aggiungere che, oltre ai processi indicati, il processo di inizializzazione lancia anche altri processi, quali il gestore dello spool sulla stampante e il gestore dell'accounting, cioè il controllo dei tempi di accesso al sistema da parte degli utenti.

La chiusura del sistema viene di norma richiesta dall'amministratore di sistema, mentre il singolo utente può soltanto scollegare il proprio terminale.

La procedura di chiusura (indicata con il termine shutdown) deve controllare le sessioni di lavoro aperte sui vari terminali e lanciare agli utenti un messaggio invitandoli a scollegarsi entro un tempo prefissato. Trascorso tale termine i processi in corso vengono comunque chiusi (abortiti secondo il gergo informatico): insieme ad essi termina anche .l processo di gestione dello spool e dell'accounting.

I software di sistema

Ai livelli più esterni e quindi più vicini all'utente, il sistema operativo mette a disposizione alcuni ambienti software, detti anche programmi di utilità, concepiti per agevolare l'utente nella sua attività di programmazione, sia attraverso comandi espliciti, sia attraverso routine che vengono richiamate da programma. Talvolta l'insieme dei moduli del sistema operativo e di questi ambienti software viene genericamente indicato con il termine di software di base.

Gli ambienti software di sistema comprendono:

• Editori di testi, consentono di scrivere e modificare i programmi sorgente, ma anche ogni altro tipo di testo, come lettere, articoli, libri che possono poi essere memorizzati su file e stampati.

• Compilatori, sono i programmi che trasformano in codice macchina i programmi utente, scritti nei diversi linguaggi disponibili, come C, C++, Java. Questi programmi svolgono una funzione analoga a quella di un traduttore di libri che legge un libro scritto in una lingua e ne scrive la traduzione in un'altra.

• Linker (Collegatori), sono programmi che svolgono un compito importante, unendo tra loro i risultati di compilazioni diverse. Il loro ruolo verrà chiarito meglio spiegando le diverse fasi del processo di creazione di un programma.

• Interpreti per l'esecuzione di programmi scritti in linguaggio evoluto traducendo ed eseguendo un'istruzione per volta. Un interprete svolge la funzione di un traduttore simultaneo, che ascolta un discorso in una lingua e riesprime i concetti che sente in un'altra. Se gli si sottopone lo stesso discorso una seconda volta egli riesegue le stesse operazioni svolte in precedenza.

• Debugger (letteralmente, spulciatore) per l'individuazione degli errori di runtime o bug (in italiano bachi). Per mezzo di un debugger, il programmatore può eseguire un programma in modo controllato, potendo vedere per esempio i valori assunti dalle variabili di un programma mentre questo viene eseguito una istruzione per volta. Il programmatore può anche impostare dei breakpoint (punti di interruzione), in modo che un programma si arresti in corrispondenza dell'esecuzione di una istruzione precisa. La verifica dei valori delle variabili in tale punto permette di individuare eventuali errori commessi scrivendo il programma.

• Gestori di maschere per il data entry, che facilitano le operazioni di creazione modifica degli archivi; le procedure che costituiscono questi programmi possono essere richiamate dall'utente nei suoi programmi e consentono di generare maschere vidi adatte alle varie applicazioni. Funzionalità simili sono a volte disponibili anche per realizzazione di stampe (report).

• Gestori delle comunicazioni, che riguardano le funzioni connesse con il collegamene tra risorse informatiche di tipo diverso, a piccole o grandi distanze. Per esempio, Un dispone di programmi per la consultazione e l'inoltro della posta elettronica e può collegarsi ad altri computer usandone le risorse.