131 59 156MB
italian Pages [213]
COLL.
Paolo Ancilotti Maurelio Boari Anna Ciampolini Giuseppe Lipari
e
613
Sistemi operativi Seconda edizione
McGraw-Hill Milano• New York. San Francisco .Washington D.C . • Auckland Bogota • Lisboa • London • Madrid • Mexico City • Montreal New Delhi • San Juan • Singapore • Sydney • Tokyo • Toronto
Sommario
Copyright © 2008, 2004
The McGraw-Hill Companies, S.r.l. Publishing Group Italia Via Ripamonti, 89 - 20139 Milano
McGraw-Hill
~
A Divisio11 of'J1ie McGraw-HiU Oimpa11its
I diritti di traduzione, di riproduzione, di memorizzazione elettronica e di adattamento totale e parziale con qualsiasi mezzo (compresi i microfilm e le copie fotostatiche) sono riservati per tutti i Paesi. Nomi e marchi ~i~ati nel testo sono generalmente depositati o registrati dalle rispettive case produttnc1.
1 Concetti introduttivi
1
2 Gestione dei processi
49
3 Sincronizzazione dei processi
91
4 Gestione della memoria
123
5 Gestione delle periferiche (1/0)
177
6 Il file system
215
7 Protezione e sicurezza
235
8 I sistemi operativi Unix e Linux
253
9 Il sistema operativo Windows
301
A Elementi di sincronizzazione in ambiente distribuito
327
B Multithreading in Java
349
e
367
Linguaggio di comandi {shell) in UNIX
381
D Sistemi operativi embedded
\
Publisher: Paolo Roncoroni Editor: Alessandra Porcelli Produzione: Donatella Giuliani Grafica di copertina: G & G Sìampa: C.N.S. srl, Ciserano (Bg) Printed in Italy ISBNJO 8838664323 ISBN 978-88386-6432-8 89 PSPS 2020 2019 2018
Indice
Prefazione Ringraziamenti dell'Editore 1 Concetti introduttivi 1.1
Principali funzioni di un sistema operativo 1.1.1 Facilità di programmazione e portabilità dei programmi 1.1.2 Gestione delle risorse 1.1.3 Protezione, sicurezza, tolleranza ai guasti 1.1.4 Astrazione di macchina virtuale 1.2 Cenni storici sull'evoluzione dei sistemi operativi 1.2.1 I primi sistemi di elaborazione 1.2.2 I primi sistemi batch 1.2.3 Sistemi batch multiprogrammati 1.2.4 Sistemi time-sharing 1.2.5 Sistemi in "tempo reale" 1.2.6 Sistemi operativi per personal computer 1.2.7 Sistemi operativi per sistemi paralleli e distribuiti 1.3 Richiami di architetture dei sistemi di elaborazione 1.3.1 Il processore La memoria 1.3.2 1.3.3 Dispositivi d'ingresso/uscita 1.3.4 Meccanismo d'interruzione 1.3.5 Accessi diretti alla memoria (DMA) 1.3.6 Meccanismi di protezione 1.4 Struttura dei sistemi operativi 1.4.1 Principali componenti di un sistema operativo 1.4.2 Principali modelli strutturali 1.5 Sintassi utilizzata nel testo Sommario Note bibliografiche Domande di riepilogo Problemi
Xl XVII
1 1 3 4 5 6 7 7 8 9 14 16 18 19 20 21 22 25 26 30 32 34 34 39 44 45
46 47 48
Indice IX VIII l_ nd_ic_e___ ~ - - -
49 4 Gestione della memoria
2 Gestione dei processi
. . di' processo Definizione Stati di un processo . processo Descrittore dI u~ Code di processi Cambio di contesto . dei processi . e terrninaz1one . 2.6 Creazione . 1· processi a processi 2.7 Interazione tra. 2.8 Nucleo di un sistema f ' t-Come-First-Served (FCFS) 2.9 Scheduling . JF) 2 9 I Algontmo irs. i°9'2 Shortest-Job-F~~t (S Time-First (SRTF) .9.3 Shortest-Remammg2· · b' (RR) 2 9 4 Round-Ro m . 'taria hedulazione su base pnon. " . . 2.9.5 Se . "a code multiple . . . · tempo reale 2·9·6 Schedulazione · · · di s1stem1 m 2.9.7 Schedula~1~ne d r g per sistemi multimediali 2.9.8 Algoritmi d1 sche u m 2.10 Processi leggeri (thread) Sommario Note bibliografiche Domande di riepilogo Problemi
2.1 2.2 2.3 2.4 2.5
50
51 54 55 57 57 58 60 63
67 69
70 71 74 75 77 82 83 86 87 87 88
3 Sincronizzazione dei processi
91
Tipi di interazione tra i processi Problema della mutua esclusione . 3.2.1 Soluzioni al problema della mutua esclusione 3.3 Problema della comunicazione 3.4 Semafori 3.4.1 Soluzione al problema della mutua esclusione 3.4.2 Soluzione al problema della comunicazione 3.5 Primitive send e receive 3.6 Soluzione al problema di comunicazione tra processi 3.6.1 Sincronizzazione tra processi comunicanti 3.7 Blocco critico 3.7.1 Condizioni per il blocco critico 3. 7.2 Metodi per il trattamento del blocco critico 3. 7.3 Individuazione di eventuali blocchi critici e successivo ripristino Sommario Note bibliografiche Domande di riepilogo Problemi
91
3.1 3.2
95 96
98 100 100 102
104 106 108
109 114 115
119 120 121 121 122
4.1
Introduzione alla gestione della memoria 4.1. l Analogie con la gestione della CPU 4.1 .2 Differenze rispetto alla gestione della CPU 4.2 Aspetti caratterizzanti la gestione della memoria 4.2. l La memoria virtuale 4.2.2 Rilocazione statica e dinamica - Memory Management Unit 4.2.3 Organizzazione della memoria virtuale 4.2.4 Allocazione della memoria fisica 4.2.5 Dimensionamento della memoria virtuale 4.3 Tecniche di gestione della memoria 4.3.1 Memoria partizionata 4.3.2 Memoria segmentata 4.3.3 Memoria paginata 4.3.4 Memoria segmentata e paginata 4.3.5 Gestione degli spazi virtuali Sommario Note bibliografiche Domande di riepilogo Problemi 5 Gestione delle periferiche (1/0)
5.1 5.2
Concetti generali Organizzazione logica del sottosistema di I/O 5.2.1 Livello indipendente dai dispositivi 5.2.3 Livello dipendente dai dispositivi 5.3 Gestore di un dispositivo 5.3.1 Processi esterni Gestione di un dispositivo a controllo di programma 5.3 .2 5.3.3 Gestione di un dispositivo a interruzione 5.3.4 Gestione di un dispositivo in DMA 5.3.5 Flusso di controllo durante un trasferimento 5.3.6 Gestione del temporizzatore 5 .4 Gestione e organizzazione dei dischi 5.4.1 Organizzazione fisica dei disc?i . . . 5.4.2 Criteri di ordinamento dei dati su disco e d1 scheduhng delle richieste di trasferimento 5.4.3 Dischi RAID Sommario Note bibliografiche Domande di riepilogo Problemi
6 Il file system 6. 1 6 _2
Organizzazione del file system La struttura logica del file system
123
123 124 125 126 127 129 135 137 140 141 142
148 157
169 170 174
174 175
175 177
178 181 181
187 189
191 192 193 199 200 201 203
203 206
209 212
212 213 213
215 215 217
x
1ndicee _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ __ _ _ Indice Xl
6.3
6.4
6.2.1 Il file . 6·2·2 La directory . della struttura logica del file system .2.3 Gest10ne 6 A cesso al file system . fil c ttu dati e operazioni per l'accesso a1 e .3. J Stru re 6 6.3.2 Metodi di .accesso Organizzazione fisica . . 6.4.1 Tecniche di allocaz10ne dei file
Sommario Note bibliografiche Domande di riepilogo Problemi 7 Protezione e sicurezza . . . . 7. 1 Modelli, politiche e meccamsm1 d1 protezione 7.2 Domini di protezione . . . 7.3 Il modello matrice degli acces 1 7.3.1 Rappresentazione dello stato d1 protezione 7.3.2 Rispetto dei vincoli di acce so 7.3.3 Modifica dello tato di protezione 7.4 Realizzazione della matrice degli accessi 7.4.1 Lista di controllo degli accessi (ACL, Access Control List) 7.4.2 La lista delle capability ( C_List, Capability List) 7.5 Sistema di sicurezza multilivello 7.6 Controllo degli accessi basato sui ruoli (Role Based Access Control, RBAC) 7.7 Basi di calcolo fidate 7.8 Autenticazione degli utenti 7.8.1 Autenticazione tramite parole chiave Sommario Note bibliografiche Domande di riepilogo Problemi 8 I sistemi operativi Unix e Linux
8.1
8.2
8.3
84 ·
Introduzione a Unix 8.1.1 La storia di Unix 8.1.2 Linux Architettura de~ sistema operativo UNIX 8·2· 1 Organizzazione I processi nel sistema operativo U . 8.3. J Caratteristiche nix 8.3.2 Immagi d' 8.3.3 Syst nce I un processo Unix em ali per la ge f . 8.3.4 Lo schedu1· · s IOne di processi L mg m Unix a gestione della mem . . ona nel sistema Unix
217
218 220 221 221 223 225 226 231
232 232 233
235 235 237 239 239
239 240 241 241 242 243
8.5
Il file system 8.5.1 Organizzazione logica del file system di Unix Protezione 8.5.2 8.5 .3 Organizzazione fisica del file system di Unix 8.5.4 Strutture dati del kernel per l'accesso a un file 8.5.5 System Cali per l'accesso a un file 8.6 Interazione tra processi 8.6.1 Sincronizzazione: i segnali 8.6.2 System Cali per l' uso dei segnali 8.6.3 Comunicazione: pipe 8.7 Interazione con l'utente 8.7.1 Lo shell 8.7.2 Comandi, argomenti, opzioni 8.8 I thread nel sistema Linux 8.8.1 Gestione di thread secondo lo standard POSIX: la libreria pthreads 8.8.2 Sincronizzazione tra thread Linux 8.8.3 Un esempio di sincronizzazione tra thread . Sommario Note bibliografiche Domande di riepilogo Problemi 9 Il sistema operativo Windows
9 .1
245 246 247 248 249 250 251 251
253 253 253 254 255 255 256 257 258 260 265 266
Struttura generale 9.1.1 Evoluzione storica 9 .1.2 Sottosistemi e moduli del nucleo 9.1.3 Struttura a microkernel 9.1.4 Kernel Objects 9.1.5 Sicurezza e controllo degli accessi 9.2 Gestione dei processi e dei thread 9.2.1 Lo schedulatore 9.3 Sincronizzazione fra thread 9.3.1 La famiglia di funzioni Interlocked 9 .3 .2 Oggetti di sincronizzazione 9.4 Gestione della memoria virtuale 9.5 File system Sommario Note bibliografiche Domande di riepilogo
A Elementi di sincronizzazione in ambiente distribuito
A.1 A.2
Introduzione alle reti A.1.1 Il modello OSI e la rete Internet Sviluppo delle applicazioni di rete A.2.1 Il modello cliente-servitore A.2.2 Le socket di Unix BSD
266 267 268 271 273 275 278
278 280 282 284 284 285 286 287 289 293 297 298 298 299 301
301 301 302 305
306 306
309 311 314 314
316 322 323 325 325
326
327 327
328 331 332 332
Xli 1ndiccEe! _ _ _ _ _ _ __ _ _ _ _ _ _ _ _ _ __ __ _ _ _ __
Strutture dati associate alle socket A.2.! S stem Cali per l'uso del_le socket _ A.2. ~ . esecuzione remota d1 comandi A.3 Un esemp10. sommario Note bibliografiche Problemi
B Multithreading in Java 8.1 B2
·
Ambiente di sviluppo e ambiente di esecuzione I thread in Java · I hr d ereaz10n · e di thread mediante estensione della c asse t ea . . . : _ Creazione di thread mediante 11nplementaz1one 8 22 dell'interfaccia Runnable B. 2.3 Grafo di stato dei thread Java. d . hr d J 8.2.4 Priorità e algoritmi di schedulmg e1 t ea ava Sincronizzazione in Java B 3.1 Accessi esclusivi a un oggetto e sezioni critiche s:3.2 Sincronizzazione diretta: metodi wait e notify B 2.1
350 351 352
Sommario Note bibliografiche Problemi
Linguaggio di comandi (shell) in UNIX
367
C. l
367 367 369 369
Comandi di uso più comune C. l. l Gestione del file system C. l .2 Monitoraggio e gestione dei processi C. l.3 Input/output dei comandi: filtri, ridirezione e piping C.2 Programmazione shell C.2.1 Variabili C.2.2 Sostituzioni, metacaratteri e quoting C.2.3 Comandi per il controllo del flusso di esecuzione C.3 Esempio conclusivo Sommario Note bibliografiche Problemi
D Sistemi operativi embedded D. l Embedded Linux D.2 Windows CE D.3 Symbian D.4 L? standard OSEKfVDX Sommano Note bibliografiche
Prefazione
349
353 354 355 356 357 360 365 365 365
8.3
e
.
336 337 344 347 347 347
377 378
Il sistema operativo costituisce uno dei componenti fondamentali di ogni sistema di elaborazione, in particolare è quello con cui l'utente entra direttamente in contatto quando accede al sistema, sia nei casi in cui tali accessi siano finalizzati all'esecuzione di programmi applicativi sia nel caso più particolare in cui l' accesso sia fmalizzato al progetto e alla realizzazione di nuove applicazioni. Lo scopo di questo testo è quello di classificare e presentare le principali funzioni che vengono svolte dal sistema operativo, introducendo i concetti fondamentali che sono alla base del loro sviluppo, illustrando le principali componenti che li caratterizzano e la loro organizzazione. Il libro è specificamente concepito come testo per un primo insegnamento sui sistemi operativi, insegnamento che rappresenta una parte essenziale di ogni corso di laurea in Ingegneria Informatica o in Informatica. Esso nasce da una lunga esperienza di ricerca e di insegnamento nel campo dei sistemi operativi in ambito sia universitario (presso le Università di Bologna e di Pisa e presso la Scuola Superiore di Studi Universitari Sant' Anna di Pisa) sia industriale e applicativo . Il testo pertanto si rivolge prioritariamente a un pubblico studentesco, in particolare gli studenti dei corsi di laurea in Ingegneria Informatica e in Informatica e più in generale a quelli dei corsi afferenti alla Classe di lauree in Ingegneria dell' Informazione, ma anche a un pubblico di professionisti, siano essi utenti o sviluppatori di nuove applicazioni.
379 379
Contenuti
372 372
373 374
381
383 384 385 386
Bibliografia
388 389
Indice analitico
391
3-91
Il libro si articola in nove capitoli e quattro appendici. I capitoli, a loro volta, sono suddivisi in tre parti: la prima, corrispondente al capit?l~ 1, è introdutti~a all' argomento; la seconda, corrispondente ai capitoli d~l 2 al e u:centrata sulle cm~ue componenti principali di un sistema operativo d~d1cat~ 1:spe~1~a_men~e ~11~ ge~hone dell'unità centrale di elaborazione, della memona, dei _d1sp?s1t~v1 pentenc1'. dei file e del· e si·curezza·, la terza , corrispondente 8 e 9,. e dedicata . . . a1 cap1toh , . a due caIa pro tez1one · d. tud· no incentrato sui sistemi Umx e Lmux e 1 altro sul sistema Wmdows . Le Sl l S 10, U · · d · · · d" "b · · A ndici riguardano alcuni elementi introdutt1v1 e1 s1stem1 1strl mtl, pqua ttro appe . . d. B ·11· . di . A la gestione dei thread nel lmguagg10 Java, Appen ice , 1 mguagg10 d pen ice ' · · · · · · b dd d A d. D comandi (shell) in Unix, Appendice C, e 1s1stem1 operativi em e e , ppen ice .
7,
XIV Prefazi~on~e:___- - - - - - - - - - - - - - - - - - - - - - - - -
Prefazione capitolo vengono introdotte le princi. 1 1) In questo pnm0 b oduzione (Capito o . · a· e viene presentata una reve panorami• Intr d I ,sterna opera v 0 . d . . li funzioni svolte a s . . . erativi per meglio compren ere 1 pnncipa , 1 · e dei s1stem1 op ' . . 1 storica sull evo uzion tt e le motivazioni che 1anno portato al loca b del loro proge o . 1 . d' . . i che stanno alla ase . . t . rassegna Je varie tipo og1e 1 s1stem1 opeP qumdi passa e m . · V ro sviluppo. Vengon?. e alle finalità per cui sono stati proge~at1. engono rativi, distinguendoli 1_n ~as . trutture interne di un sistema operativo, le compo1 inoltre presentate le prmcipa .1 s d in cui tali componenti sono organizzate. Per ttenzzano e 11mo O · · · nenti che Io cara . . · le funzioni del sistema operativo s1 mterfac. ndere il modo m cw . h' . l . meglio compre . fi . h della macchina vengono ne 1amatl a cum con. I omponent1 1s1c e ' .d . e . ciano con e e . . . le principali componenti estmate a 1ormre il . h't1 tturali e m part1co 1are, 1 . cett1 are e . ' Infine viene sinteticamente presentata a smtassi . rt al sistema opera1ivo. ' , ·1· . suppo O . • d' programmazione che verra utl 1zzato nei successivi di ~no _pseudo-lmguaJ~~oriv~re gli algoritmi e presentare gli esempi. st0 cap1t?h del ~e per . e della CPU (Capitoli 2 e 3). Nel Capitolo 2 viene introdotGestione dei processi e . d . d . . . • to il concetto di processo, fondam~ntale ~er, lo s~1lup~o e1 mo ~m1 s1s.tem1 mul. · le sue principali propneta. Viene mtrodotta 1 astrazione CPU tiprogramma11, e . . · · ne illustrato come, per effetto d1 questa astrazione, possono essere 1 v1rtua e e vie . . · · · d · · ignorati dai singoli processi aspetti quah sospens1~ne e na~d1~~z1one _e1 provc~ss1, criteri di assegnazione della CPU e trattamento de~ se~na1~ 1 mte_~z1?~e. ~en~ inoltre mostrato come la CPU virtuale risulti amcch1ta 111 termm1 d1 1struz10111 elementari, di primitive per la comunicazione e sincronizzazione con gli altri processi (compresa la comunicazione con i dispositivi di ingresso/uscita visti come processori esterni) e per la creazione ed eliminazione dei processi. Vengono descritte le principali funzioni e strutture dati che costituiscono il nucleo del sistema operativo. Il Capitolo 3 è viceversa dedicato alle interazioni tra processi, sia di tipo competitivo per l'uso di risorse comuni sia di tipo cooperativo per lo scambio di informazioni tra processi. Infine viene descritto il fenomeno del blocco critico (deadlock) e le principali tecniche per la sua gestione. • Gestione della memoria (Capitolo 4). Partendo dagli aspetti che accomunano i crit_eri di gestione delle due risorse CPU e memoria, quali per esempio i meccanismi p~r la c_reazione e gestione di risorse virtuali, vengono illustrati gli aspetti cara~enzzan~i la g~stione della memoria, quali la sua organizzazione sia logica sia fisica, .la nlocaz1one degli md·mzz1 · · Iog1c1 · · nei· comspon · d enti· mdmzzi · · · · fiis1c1, · · Ja . protezione delle mfonnaz'10 · 1 d' . . . . si e 1, b. . .. m e a con 1v1s10ne d1 codice e dati tra processi d1ver. . h .. . . on o iett1vo d1 illustrare I principale ali 1 d . e vane tecmc e utilizzate per gestire la memona . ' a uce e1 precedenf1 tf1 .. . . . msmi e i relativi algo ·tm· d. aspe , vengono presentati i pnncipah mecca1 1 allocazione dell · con nfenmento · · tutto a1. supporti fomifn a memona, soprat. . i a questo proposito d' tt . . ' crommo d1 dispositivi MMu (M ire amente m hardware, noti con l aGestione dei dispositivi ·ri _e':1ory Management Unit). scritti i principali servizti~e~~cdl(lC~pitolo S). In questo capitolo vengono de1 a sistema ope t' un adeguat 0 . . · . supporto all'ese · ra ivo per assicurare ai processi descntto com tal'1 . . cuz1one delle oper . . d' . . . il li'vell e_ serv1Z1 siano generai aziom i mgresso/uscita. V iene o supen · . mente s dd · · · · . . . · tivi stessi I ore, m cui sono contenute I u iv1si m due hvelh gerarchici: , e o strato infi · e component' · d' · i m !pendenti dai disposienore, contenent e Ie compone t· "d n L evice-dependent" co-
XV
.
me i "device driver" V . . . . . . . . . .. . . · engono 111ustrah alcuni esempi d1 dev1ce dnver d1stm·· ' guen do 1 casi m cu 1 1I d'1 sp_os1tivo lavora a interruzione di programma da quelli in . , cm e pre~ente un canale d1 Accesso Diretto alla Memoria (DMA). Viene illustrato anche ·' m · part1co · Iare d e1· d1spos1hv1 · · · · d1· me. . 11 caso della gestione del t·uner e pm moria d1 massa (dischi). · · 1·1 aspetti· relativi · · al• Gestione . dei file . (Capitolo . 6) · Questo capi·to1o tratt a I· pnnc1pa la g~stl.~n~ dei file ,_ r~ahzzata dal sistema operativo mediante una delle compon_e nh PI~ impo_rtanh, 11 file system. Il ruolo di questa componente all'interno del sistem~ e ~o~1r~ adeguate astrazioni e meccanismi per l'archiviazione delle inform?z.1om nei dispositivi di memoria di massa. Concetto centrale di questo capitolo e 11 file, che rappresenta l'unità di archiviazione delle informazioni nel file system. Il ~apitolo ~escrive inizialmente l'organizzazione del file system mediante la defimz10ne d1 quattro livelli, ognuno dedicato alla soluzione di particolari problemi inerenti alla gestione dei file. Vengono quindi illustrate le funzionalità di ciascun livello e le soluzioni comunemente adottate per la loro realizzazione. In particolare, partendo dal livello più alto, vengono trattati gli aspetti relativi alla presentazione del file system alle applicazioni, introducendo il concetto di directory come contenitore di file; successivamente vengono prese in considerazione le problematiche relative all'accesso ai file, includendo una breve trattazione sulla protezione del file system, requisito fondamentale nei sistemi multi-utente. Viene infine affrontato il tema delle tecniche di allocazione dei file , analizzando i pro ed i contro degli approcci più diffusi. • Protezione e sicurezza (Capitolo 7). In questo capitolo viene presentato il problema del controllo degli accessi dei processi alle risorse di un sistema di elaborazione, illustrando il significato di alcuni concetti fondamentali quali modelli, politiche e meccanismi di protezione e indicando anche come questi ultimi vengono implementati a livello di sistema operativo. Viene introdotta la matrice di controllo degli accessi come modello per i vari sistemi di protezione e al tempo stesso come meccanismo per verificare l'applicazione delle relative politiche. Infine, viene affrontato il problema centrale per la sicurezza di un sistema di elaborazione. • Il sistema operativo Unix (Capitolo 8). In questo capitolo vengono presentate le caratteristiche di Unix, uno dei più diffusi sistemi operativi moderni. In particolare, dopo una breve illustrazione della storia di Unix e delle sue varie versioni, vengono descritte l'architettura generale del sistema, lo shell e le principali system cali. Viene spiegata la struttura di un processo Unix insieme al criterio di scheduling adottato per allocare la CPU. Vengono descritte l'organizzazione sia fisica sia logica del file system, insieme alle principali strutture dati utilizzate nel kernel per quanto riguarda l'accesso ai file. Relativamente alle interazioni tra processi vengono descritti, anche con esempi, i meccanismi dei segnali e delle pipe. Viene poi illustrata la gestione dei thread in Linux, introdotto come sistema derivato da Unix, descrivendo i meccanismi di sincronizzazione e confrontandoli con quelli offerti dalla libreria pthreads secondo lo standar~ POSI!. . • Il sistema operativo Windows (Capitolo 9). In questo capitolo viene fornita una breve panoramica sul sistema operativo. Microsoft ~~~o~s. Si tr~tta di uno d~i sistemi operativi più diffusi al mondo, sicuramente 11 pm diffuso sistema operativo sui Persona! Computer oltre che nel settore dei server. Di Windows esi~tono
X~V~l~Pr'.:e~fa~zi_on~e~:>_ - - - - - -- - - - - - - - - - -- - - - - - - - -
. t· he anche molto differenti l'una rispetto all'altra l fu . . , . . . con carattens ic diverse vers1~m, , . ne è focalizzata sulla struttura e e nz1onahta forniIn questo ca~,t~lo I_attenzi~T Windows 2000 e Windows XP. Dopo una breve te dalle versioni Wm dows d 't . tema e su come tale struttura sia evoluta net introduzione sulla ~truttu~~'al~a s~engono descritte la gestione dei processi e dei passare da una verS10ne a . ' la struttura del file system. thread, la gest!one d~lla n:1emo~: :mbiente distribuito (Appendice A). In questa Elemen_ti di smcron~z~t1?n~cuni cenni relativi alla programmazione di applicaappendice vengono 1om1 t a ffr 1 d. ·b ·t In particolare, vengono a ontate a cune problema. .. . ztont m ambiente 1stn UI 0 . · · · d" ·b · · . . · ,. t ·,one tra processi nel caso mcm essi siano 1stn mti mdittche re 1at1ve a11 m eraz · · d · versi. no d.1d.1una rete di· calcolatori · A questo scopo. viene mtro . otto. 11 meccani. ket come strumento di base per realizzare la smcromzzaz10ne tra smo deIl e soc · , d. ·1· V . esaminandone le proprietà e le modahta 1 uti 1zzo. engono infine proces SI , d h . .. mostrati alcuni esempi di utilizzo delle socket assumen o c e 1 processi interagenti vengano eseguiti in ambiente Unix. , . . • Multithreading in Java (Appendice B). Java e un hnguagg10 concorrente, nel quale sono presenti, come costrutti linguistici, molti dei concetti esaminati nei vari capitoli del testo, in particolare i concetti di thread, di applicazioni multithreading e di condivisione di dati fra thread. Lo scopo di questa appendice è duplice: da un lato esemplificare tali concetti utilizzando uno strumento linguistico adatto a questo scopo, dall'altro fornire un raccordo fra i contenuti del testo e quelli di un secondo volume relativo all'approfondimento degli argomenti dei sistemi operativi e della programmazione concorrente e distribuita. Data per sconta~a una gen~rale cono_scenza dei principali concetti della programmazione object onent~d. e dt come tait concetti sono stati calati nel linguaggio Java, vengono illustrati •. m~ccan!s•_n_i linguistici fomiti da Java per creare e attivare thread, gli strume~t, d1spombilt per controllarne la schedulazione sulla Macchina Virtuale J~va e, m~ne,_ vengono illustrati alcuni esempi di interazione tra thread. • Linguaggio di c?mandi (shel)) !n Unix (Appendice C). In questa appendice vengpono approfo nd ite le carattensttche del linguaggio comandi bash introdotto nel aragrafo 8.8 In part· J . · ,c_o are,_~engono presentati alcuni tra i comandi di uso più comune, e vengono po, fomiti · . . shell. i concetti necessan per lo sviluppo di programmi d" D . . • Sistemi operativi embedded (A che peculiari di questa importa ptpen ice . )-1? 0 ?0 aver nchiamato le caratteristin e categona di s1st · · · · . t1. '· pnnc1pali aspetti di quattro . t . . . enu operativi, vengono descritper la loro ampia diffusione Sis e1TI1 operativi che, per le loro caratteristiche e t . . , rappresentano quattr . ~~ a cate~ona dt applicazioni embedded· i s ~ esempi par~digmatici della ' ~y~b,~n (per le applicazioni di telefì . . yste~ Embeded Lmux, Windows appltcaz,om automotive. oma mobtle), e lo standard OSEK per la
Scelta degli argomenf I
. e organizzazio
d
.
Il tema ,dei sistemi operativi è ne el hbro gnare I argomento in un molt? vasto e chiunque ab . . fondo: quali argomenti tra~orso umversitario si è trov /1~_avuto ti compito di inseare e approfondire e quat· a O i fronte a delle scelte di 1sorvola O · re nmandare del tutto
Prefazione
XVII
ad altri insegnamenti Anch l d. . , e ne caso 1 questo libro e stato necessario prendere del1 d .st. . 1 . · e ;c, o~t r~ ~~tva mente a questo aspetto. La scelta che ha guidato gli autori tenuto conio! ad~c 1e ~fi a 1oro ~luriennale esperienza di insegnamento della materia' è stata que a 1 c1assi 1care glt argom en t'L m · due categone, . non del tutto indipendenti: . . ' • da . questo hbro . . . un lato un insieme di argo men t·t d.1 base, que 11 1. trattati. m che si. ntt~~e debbano ~ar parte d~l bag~glio culturale e professionale di chiun~ue si laurei m Ingegnena Informatica o m Informatica· • da~l'~ltro, gli a~gomenti a carattere più speci;listico, come per esempio quelli relat1VL_ alle ~r~h,tetture di sistemi più complesse, tipiche dei sistemi distribuiti, e quelli relativi alle _problematiche inerenti la programmazione di sistema, tipiche della programmazione concorrente e distribuita e che fanno parte di un secondo volume [2] dedicato a chi è interessato ad approfondire gli studi mediante un corso di Laurea Specialistica. In questo senso il libro risponde perfettamente alle esigenze del nuovo Ordinamento Didattico degli studi universitari. Da queste considerazioni discende il motivo per cui è stata privilegiata, nel libro, la scelta degli argomenti trattati, cercando di esaminare i concetti fondamentali comuni ad una varietà di sistemi operativi diversi e illustrando i concetti trattati mediante esempi ivi inclusi due importanti casi di studio (Unix e Windows). Sempre per i precedenti motivi è stato deciso di privilegiare la trattazione degli argomenti con riferimento ad una tradizionale architettura monoelaboratore e di non fare riferimento a nessuno specifico linguaggio di programmazione ma di utilizzare, come linguaggio di presentazione degli esempi, uno pseudo-linguaggio " C-like". lnfme, come raccordo al secondo volume relativo agli argomenti più specialistici, sono state inserite le due appendici sulla sincronizzazione in ambiente distribuito e sul linguaggio Java inteso come veicolo per la trattazione degli argomenti relativi alla programmazione concorrente e distribuita. All'indirizzo internet www.ateneonline.it/ancilotti sono disponibili, per gli studenti, le soluzioni dei problemi presentati nel testo e, per i docenti, i lucidi.
Novità della seconda edizione La seconda edizione di Sistemi operativi è frutto non solo delle osservazioni emerse nell'ambito dei corsi tenuti dagli Autori, ma anche dei numerosi e utili commenti ricevuti sulla prima edizione del libro. Gli interventi consistono in un aggiornamento e revisione trasversale di tutto il testo, nell'integrazione di nuovi capitoli e sezioni per g~antire u~a _co_p e~r~ di argomenti più aderente ai corsi e nello sviluppo di apparati pedagog1c1 di utthta per lo studente. Di seguito indichiamo le modifiche più significative apportate alla precedente edizione: • Nell'ambito del Capitolo 2, relativo alla gestione dei processi, è stato completamente riscritto e notevolmente esteso il paragrafo relativo alle strategie di scheduling. In particolare, dopo aver definito i parametri in base ai quali viene valuta-
XVIII Prefaz~io~n~e_ _ _ _ __ _ _ _ _ _ _ _ _ _ __ _ _ _ ______
. t·vo vengono descritti e illustrati i principali algo, d" n sistema opera, ' .. b h . . 11 · . ta la bonta 1u . . . ei sistemi operat1v1 ate sia m que 1 ttme-sha·on· di scheduhng adottati sia n • n I ring e in quelli real-t~me. tivo alla sincronizzazione dei processi, è stato ap3 1 • Nell'ambito del Capitolo • re astione delle condizioni di blocco critico, illustran· d" . . l'argomento su 11a ge profon d1to ., quanto riguarda la prevenzione mam1ca delle ritmo pm famoso per l' I d0 ~ ~o . . . 1'al oritmo del banchiere. . . . ~ond1z1om ~1stallo. g itolo il 7, relativo a1 temi della protezione e della E stato aggmnto un nuovo cap ' Appendice e, relativa allo shell di Unix. relativa ai sistemi operativi embedded. E stata aggmnta a nuova ' . . . · ,·tolo ivi incluse le append1c1, sono state poste alcune doAlla fine d1 ogm cap ' . · · h 1 · . . e sono stati proposti alcum problemi e e, comp ess1vamente mande d1nep11ogo . . . · d. · ' hanno lo scopo di consentire al ~ett?re ~1 venfica~e 11 hvedl~o 1 ~bo_m_pre ns1_one dedei problemi sono 1spom 111 su 1 sito web . soluz1om . glI. argomen0· trattati · Le www.ateneonline.it/anctlott1.
Ringraziamenti dell'Editore
~icurezza. .
• f stata agg~unta 1la nuova Appendice o
Paolo Ancilotti Maure/io Boari Anna Ciampolini Giuseppe Lipari
L'Editore ringrazia i revisori che con le loro preziose indicazioni hanno contribuito alla realizzazione della seconda edizione di Sistemi operativi: Jurgen Assfalg, Universita' degli Studi di Firenze Monica Bianchini, Universita' degli Studi di Siena Alberto Broggi, Universita' degli Studi di Parma Augusto Celentano, Universita' Ca ' Foscari Venezia Daniele Prigioni, Universita' degli Studi dell 'Aquila Marco Lapegna, Universita' degli Studi di Napoli "Federico II" Antonino Mazzeo, Universita' degli Studi di Napoli "Federico II" Mario Verdicchio, Universita' degli Studi di Bergamo
1 Concetti introduttivi
In questo primo capitolo vengono presentate le principali funzioni che il sistema operativo svolge nell'ambito di un sistema di elaborazione. Viene anche presentata una breve panoramica storica sull'evoluzione dei sistemi operativi per meglio comprendere i principi che stanno alla base del loro progetto e le motivazioni che hanno portato al loro sviluppo. Vengono, quindi, passate in rassegna le varie tipologie di sistemi operativi, distinguendoli in base alle finalità per cui sono stati progettati. Per affrontare le problematiche relative allo sviluppo delle componenti di un sistema operativo è necessario conoscere la struttura di un sistema di elaborazione e, in particolare, le componenti hardware con le quali il sistema operativo deve interfacciarsi. Per questo motivo vengono brevemente richiamate quelle componenti della struttura fisica di un sistema di elaborazione a cui verrà fatto riferimento nei capitoli successivi del testo. Vengono quindi presentate le principali strutture interne di un sistema operativo, le componenti che lo caratterizzano e il modo in cui tali componenti sono organizzate. Infine, viene sinteticamente presentata la sintassi di uno pseudo-linguaggio di programmazione che, nei successivi capitoli del testo, verrà utilizzato per descrivere gli algoritmi e presentare gli esempi.
1.1 Principali funzioni di un sistema operativo Un sistema operativo è un componente software di un sistema di elaborazione il cui compito principale è quello di controllare l'esecuzione dei programmi applicativi e di agire come intermediario tra questi e la macchina fisica (hardware) con lo scopo di facilitarne l'uso e, al tempo stesso, di garantire che tale uso sia effettuato in maniera efficace ed efficiente. In modo molto schematico, potremmo rappresentare un sistema di elaborazione come un insieme di tre macro-componenti, organizzati gerarchicamente in tre livelli: il livello hardware, sul quale gira il sistema operativo che a sua volta offre le proprie
2 Capitolo 1 Concetti introduttivi 3
Lisa~
riferim_ento i~diretto si rende necessaria per controllare l'accesso alle risorse della rr~acchma fisica._ A questo livello appartengono anche i componenti del sistema di prog~ammaz!?ne (compilatori, caricatori, linker). Analogamente appartiene a ques~o l_ivello I interprete dei comandi o shell, cioè quel particolare programma tramite il quale l' utente specifica al sistema i compiti che questo deve svolgere.
Edoardo~
Giacomo ~
Programmatore di applicazioni Livello delle
Programma Videogioco
di videoscrittura
applicazioni
Shell di comandi
Programmatore
Interfaccia (chiamate di sistema)
di sistema
Livello di sistema operativo
Unità cen trale di elaborazione Memoria principale
~
G::J
GJ Stampante
Interfaccia di rete
Livello Hardware
Mo use
Figura 1.1 Struttura schematica di un sistema di elaborazione.
funzioni ai programmi applicativi richiesti dagli utenti. In Figura 1.1 viene illustrata schematicamente la relazione fra i tre componenti e gli attori di un sistema di elaborazione: •
•
•
II livello hardware, o della macchina fisica, è quello che corrisponde ai componenti fisici del sistema e comprende il processore, la memoria principale (volatile) e le unità periferiche, come la tastiera, il video, il mouse, le memorie di massa ecc. Lo scopo di questo livello è quello di mettere a disposizione dei programmi le risorse necessarie per la loro esecuzione. Per questo motivo, nel seguito, ci riferiremo ai vari componenti hardware con il termine di risorse fisiche. In questo senso il processore è una risorsa così come lo sono la memoria, la stampante ecc. II livello del sistema operativo, che corrisponde a un insieme di componenti software che hanno il compito di gestire le risorse fisiche della macchina offrendo ai programmi applicativi un'interfaccia standard più semplice da usare rispetto a quella offerta direttamente dai componenti hardware. Tale interfaccia è composta da una serie di funzioni che possono essere invocate dai programmi applicativi per intervenire sulle componenti hardware del sistema in maniera controllata ed efficiente. Il livello dei programmi applicativi che, come dice il nome, corrisponde all'insieme delle applicazioni utilizzate direttamente dagli utenti del sistema. I programmi utente non interagiscono mai direttamente con l'hardware, ma sempre tramite l'interfaccia del sistema operativo. Quindi, per esempio, se un programma utente deve visualizzare un messaggio sul video deve invocare delle opportune funzioni del sistema operativo che si occuperanno di eseguire tale compito. Questo tipo di
In definitiva, il sist~ma o~erativo non è altro che un insieme di programmi che nasco?dono la _macchm~ fisica alle applicazioni. Un programma applicativo opera sulle n~orse ~siche per 1.l tramite delle funzioni del sistema operativo il quale, quindi, fornisce a1 programmi applicativi un'interfaccia costituita da un insieme di funzioni che mascherano la struttura della macchina fisica facendo vedere loro una macchina virtuale più semplice da usare. Tale astrazione permette al programmatore di strutturare un programma applicativo in maniera indipendente dalla maggior parte dei dettagli architetturali della macchina fisica. Programmare direttamente l'hardware è un compito complesso, tedioso e soggetto a errori. Inoltre, tale astrazione facilita la portabilita' dei programmi su differenti architetture hardware. Questo aspetto relativo alla facilità di programmazione e alla portabilità dei programmi rappresenta sicuramente uno dei principali obiettivi di un sistema operativo. Il fatto che l'accesso alle risorse della macchina fisica avvenga sempre tramite le funzioni del sistema operativo consente a quest'ultimo di gestire le risorse in modo tale da ottimizzarne 1'uso secondo quelle che sono le finalità del sistema di elaborazione. È questa una delle funzioni più importanti svolte dal sistema operativo tanto che, in taluni casi, si tende a rappresentare il sistema operativo come un insieme di gestori di risorse. Un'altra funzione svolta dal sistema operativo è quella di garantire la protezione e la sicurezza dei dati dei vari utenti del sistema di elaborazione. Connessa con questa c'è anche quella relativa alla gestione di eventuali malfunzionamenti che si possono verificare durante l'esecuzione di un programma. L' obiettivo, in questo caso, è quello di verificare la possibilità di recuperare il corretto funzionamento del sistema. Queste sono solo alcune delle principali funzioni svolte da un sistema operativo che adesso cercheremo di approfondire brevemente. In realtà, non è possibile fornire un elenco esaustivo poiché tali funzioni cambiano spesso da sistema a sistema. 1.1.1 Facilità di programmazione e portabilità dei programmi
Perché un programma possa essere eseguito è necessario che allo s.tesso .siano_ dedicate alcune risorse della macchina fisica. Per prima cosa è necessa1:o can~are 11 pro~ gramma in memoria principale e quindi è necessario che una porzione d1 questa gh venga dedicata. È poi necessario dedicare al programma l'uso ,del p~oce~sore .affinché questo possa eseguire le istruzioni che lo compongono. ~u~ dars_1 _P~l ~~e 11 proesecuzione debba operare su alcum d1spos1t1v1 d ingresso/ gramma duran te la Sua . . . . · · 1 ·d ·t · per leggere dei dati dal disco e per fornire 1 nsu1tat1 su v1 eo o usci a, per esempi 0 stamparli sulla stampante. . . . . · meg1 1·0 tale concetto , cons1denamo. per .esempio . un programma uten. . P er c hianre d1 massa te c he legge d e1· dah· da un dispositivo di memonzzaz1one . . . .(per esempio . . il. disco fisso) e li mostra a video (per esempio 11 comando cat nei s1stem1 operahv1 Unix, 0 il comando type nei sistemi Windows).
4
Capitolo 1 Concetti introd uttivi 5
· · · · Jmen te c he 1·1 si·stema di elaborazione non preveda 1mz1a . . . alcun sistema . S uppomamo operativo. Il programma quindi deve inter~grre ?trettamente c?n d1vers~ parti ?ella macchina fisica. Anzitutto è necessario cancare il programma _111 me_mo_~,a e attivare la sua esecuzione caricando nel registro "contatore delle 1_Sfruzwnz (program · · pom · ter) l't"ndirizzo della counter o mstructwn . prima . istruzione , . ,del. programma. . · d ·1 amma deve mterag1re con I umta. d1 ,memonzzaSuccess1vamente, quan o 1 progr .· zione di massa per leggere i dati memorizz~ti ~ul s~pport? magnetico, e nec~ss~110 che lo stesso esegua tutta una serie di istruz1om part1col~n, che sono quelle previste per accedere allo specifico dispositivo. Ci~ imp.li~a, per 11. pr?gra1~1~natore, un~ ~onoscenza approfondita di tutti i dettagli reahzzattv1 dt ogm d1spos1t1vo con cui il suo . . . . . . .. . . . programma dovrà operare. Purtroppo in commercio esistono moltt modelh d1vers1 d1 d1spos1t1~1 d1 m_emoi:i~zazione di massa, ognuno con le proprie caratteristi~he e _con le propne funz1onaltt~. Per cui se il programma dovesse essere in grado d1 funzionare anche su_ un altro sistema ~u cui è installato un diverso dispositivo, sarebbe stato necessano progra~marlo in modo da riconoscere il particolare dispositivo e adattare le proprie routme di lettura dati al dispositivo in questione. Inoltre, il programma deve essere in grad~ di individuare i propri dati all'interno del dispositivo che può contenere anche molti dati diversi (file). . . . . . . . . Lo stesso problema si ha nel caso in cm s1 voghano v1Sual1zzare 1 dati sul dispositivo di uscita (per esempio il terminale video del sist~ma). Il programmat~re deve conoscere i dettagli interni del dispositivo per poter scnvere un programma m grado . . . di interagire con esso. Nel caso in cui il sistema di elaborazione comprenda un sistema operativo, 11 compito del programmatore risulta estremamente più semplice poiché non è più necessario conoscere i dettagli della macchina fisica ed è possibile concentrarsi esclusivamente sulla funzionalità del programma in quanto le interazioni con l'hard~are vengono demandate al sistema operativo. In pratica, ogni interazione con ~n particolare dispositivo fisico può essere programmata chiamando altrettant~ ~nz10~1 of~erte dal sistema operativo. Sono queste funzioni che hanno il compito d1 mte~ag1re ?1rettamente con i dispositivi e quindi di conoscere tutti i dettagli della macchma fisica. 1.1.2 Gestione delle risorse I moderni sistemi di elaborazione sono in grado di eseguire più programmi contemporaneamente. Questo è sicuramente vero per tutti quei sistemi che offrono il loro servizio a più utenti contemporaneamente (sistemi multiutente). Per esempio, nello schema di Figura I .1 Edoardo accede al sistema localmente, tramite la tastiera e il video; Lisa e Giacomo accedono al sistema da remoto, tramite un'interfaccia di rete. Oppure si pensi a un sistema di elaborazione dedicato alla gestione di una banca. In questo caso, l'accesso al sistema avviene da parte degli operatori che, tramite i terminali presenti agli sportelli della banca, possono eseguire contemporaneamente varie transazioni. Ma l'esecuzione contemporanea di più programmi è desiderabile anche all'interno di un normale persona! computer. Si pensi a un normale PC tramite il quale si può navigare su Internet e, allo stesso tempo, ascoltare della musica, editare dei file di testo, e così via. La tecnica utilizzata per consentire l'esecuzione contemporanea
di più programmi all'interno di un unico sistema di elaborazione è nota come tecnica di _,~iultip~ogramma! ion~ e sarà esaminata in dettaglio nel seguito. Cio che e necessar~o evidenziare fin da ora è il fatto che, se più programmi sono contemporaneamente m esecuzione su uno stesso sistema nasce la necessità di coordi~are l' accesso alle risorse della macchina da parte dei' vari programmi al fine di evitare c?mportamenti i_ndesiderati. Si pensi, per esempio, al caso di due programmi ch_e voghono stampare 11 loro output sulla stampante. E possibile che i due programmi eseg~ano l' oper~z!~n~ di stampa "contemporaneamente" generando quindi delle s~ampe_mcompre_ns1bih. E compito del sistema operativo garantire che le due operaziom d1 stampa siano eseguite in sequenza. La stessa cosa vale per tutte le altre risorse fisiche per le quali i programmi in esecuzione necessariamente competono. Se, per esempio, due programmi sono in esecuzione ma il sistema dispone di un solo processore, è compito del sistema operativo ripartire il suo uso tra i due programmi e consentire quindi che gli stessi possano procedere, un po' l'uno un po' l'altro. Analogamente è necessario gestire la memoria fisica affinché sia possibile caricarvi i diversi programmi in esecuzione. Anche lo spazio fisico su disco costituisce una risorsa da gestire opportunamente affinché ciascun programma possa memorizzarvi i propri file senza compromettere quelli degli altri. Oltre alle risorse fisiche il sistema operativo deve poi gestire anche altre risorse, costituite da dati e funzioni comuni (risorse logiche) qualora queste possano essere utilizzate da più programmi. Le tecniche adottate dal sistema operativo per la gestione delle risorse e le varie strategie adottate per una loro corretta allocazione ai programmi in esecuzione, variano molto da sistema a sistema. È dalla scelta di queste strategie che dipende la tipologia di applicazioni a cui il sistema è in grado di fornire un migliore servizio. 1.1.3 Protezione, sicurezza, tolleranza ai guasti Gli aspetti relativi alla protezione e alla sicurezza sono particolarmente importanti nei sistemi multiutente. In questi, ogni utente deve essere protetto dalle possibili interferenze degli altri. Quindi, un sistema deve garantire la riservatezza (privacy) e la protezione delle informazioni. Questi aspetti sono diventati particolarmente critici con l'avvento delle reti di calcolatori e la possibilità di accedere a sistemi remoti collegati in rete. È ormai noto che ogni sistema collegato in rete è sempre sogg~tt? alla possibilità di "attacchi" da parte di utenti "maliziosi" (hacker). I moderni s~stemi dedicano meccanismi sempre più raffinati per garantire che un utente "malizioso" non possa accedere alle informazioni riservat~ de?li al~ utenti. Co~se~enza dello sviluppo delle reti di calcolatori è anche la d1ffus1o~e d1 p~ogra~1 parhco~ larmente nocivi (i cosiddetti "virus") che vengono spesso ~cevuti tramite mess~gg1 di posta elettronica e che, una volta _caricati n~l sistema colpito, producono danm anche molto gravi all'intero sistema di elaboraz1~ne. , . . . . Nei moderni sistemi operativi multiutente e fac~lta d1 ?gnt utente d_ec1~er~ quali 11 sistema d e1· SUOI· dati· rendere pubblici e quali mantenere nservat1. Per esempio, · · l· . Windows 2000 ( e la sua evoluzione Windows XP) sono s1stetn1 mu tmten. . . . . l' operat1vo te e, come tali, forniscono la protez10ne delle mformaziom nservate e accesso contemporaneo a più utenti.
6
Capitolo 1 Concetti introduttivi
La protezione e la sicurezza del sistema rispetto a intrusioni sono tra i compiti più importanti di un sistema operativo. Aziende, istituti bancari e altri enti possono subire notevoli danni economici nel caso in cui un utente non autorizzato acceda ai dati del sistema dedicato alla loro gestione. Anche la protezione da eventuali guasti che si possono verificare nei componenti fi ici è un aspetto importante di ogni sistema operativo. Vedremo, per esempio nel Capitolo 5 riservato alla gestione dei dispositivi d ' ingresso/uscita, le tecniche adottate per far fronte ai molti eventi anomali che si possono verificare durante un ' operazione d' ingresso dati o un trasferimento in uscita dei risultati. Altri eventi anomali che si possono verificare durante la vita di un sistema non sono necessariamente riconducibili a guasti . In certi casi, per esempio come conseguenza delle tecniche di allocazione delle risorse, il sistema può generare dei malfunzionan1enti. Un esempio, il blocco critico, sarà trattato nel Capitolo 3, dove verranno illustrate le varie strategie adottate per far fronte a questi particolari tipi di malfunzionamenti. 1.1.4 Astrazione di macchina virtuale
Come già indicato precedentemente, il sistema operativo - realizzando le funzioni indicate nei precedenti paragrafi - genera una macchina virtuale sulla quale girano i programmi applicativi. L'interfaccia di programmazione che il sistema operativo fornisce ai programmi utente viene indicata genericamente come API (Application Programming Inter/ace) di sistema. Le operazioni offerte dall 'API di un sistema operativo vengono indicate anche col termine di chiamate di sistema (system calls), a indicare che tali operazioni sono realizzate in software tramite funzioni che vengono chiamate dai programmi applicativi. Spesso sono anche indicate con il termine di primitive in quanto, per un programma applicativo, una chiamata di sistema deve essere vista come se fosse un 'istruzione macchina anche se, in realtà, viene realizzata in software ali 'interno del sistema operativo. Il termine primitiva indica proprio che l'esecuzione di una funzione di sistema deve avvenire in modo tale che il suo comportamento sia equivalente a quello di un 'istruzione macchina, cioè in fonna atomica (non divisibile). Questo aspetto delle primitive e la tecnica per la loro realizzazione verranno illustrati in dettaglio nel Paragrafo 3.4.1. Come indicato in Figura 1.1, il programmatore applicativo utilizza le funzioni offert~ dall'API del sistema operativo per scrivere le proprie applicazioni. E, viceversa, compito del programmatore di sistema realizzare tutte le funzioni del sistema operativo operando direttamente sulla macchina fisica (interfaccia hardware). Lo sviluppo dei sistemi operativi ha profondamente influenzato anche lo sviluppo delle architetture dei moderni processori. Molte delle caratteristiche presenti nei moderni microprocessori derivano dalla necessità di fornire al sistema operativo supporti sempre più efficienti per l'esecuzione delle sue funzioni. . Le funzionalità offert~ dalla macchina virtuale dipendono dal tipo di sistema operat1~0 che, _a sua _vol!a,_ d1?end_e dall'ambito applicativo per cui è stato progettato. Infatti, setton apphcattv1 d1vers1 hanno bisogno di sistemi operativi con differenti caratteristiche. Per esempio, applicazioni di controllo per sistemi dedicati hanno neces-
7
sità completamente diverse d 11 . . app 11caz1oni transazionali e queste, a loro volta esl·genze d"!Verse da ap l° ·a e· d" . . ' . . . . P icaziom I calcolo mtens1vo come nel caso di complessi ti . . , programmi sc1enttfict Nei . . : . paragra 1 success1v1 verra presentata una panoramica delIe d iverse categone d1 sistemi operativi.
1.2 Cenni storici sull'evoluzione dei sistemi operativi I moderni sono molto potenti· e comp 11ca · t·1. n·1 conseguenza, . . sistemi . di elaborazione . . a~~he 1sistemi operativi so?o programmi complessi che devono svolgere molti comp1t1. Per comprendere ~egho le funzionalità di un sistema operativo moderno, è utile fare una breve panoramica sull'evoluzione storica dei sistemi operativi. 1.2.1 I primi sistemi di elaborazione
I primi calcolatori, fino alla metà degli anni '50, erano macchine enormi ed enormemente costose, che venivano usate soprattutto in campo militare O scientifico. Essi avevano una forma ben diversa da quella attuale. Le uniche periferiche d' ingresso erano costituite dai lettori di schede perforate e di nastri perforati, mentre le periferiche di uscita erano le stampanti e i perforatori di schede. Non era previsto nessun sistema operativo e l'utente programmatore interagiva direttamente col calcolatore per il tramite della consolle della macchina. Quando sulla macchina non giravano programmi (stand-by), era possibile prendere visione del contenuto (in binario) dei vari registri di macchina mediante opportune file di lampadine sulla consolle. Analogamente, mediante opportuni interruttori sempre sulla consolle, era possibile impostare un valore binario e inserirlo manualmente in un qualunque registro della macchina o in una qualunque locazione di memoria. In questo modo, era possibile per l'utente caricare un programma in memoria e, inserendo l'indirizzo della prima istruzione nel program counter, attivarne manualmente l'esecuzione. Un tipico programma scritto in linguaggio sorgente, per esempio in FORTRAN, veniva preliminarmente perforato su schede. Ogni scheda conteneva un'istruzione dove ogni carattere era rappresentato mediante un codice di perforazione. Quindi veniva caricato in memoria il compilatore che, una volta attivata manualmente la sua esecuzione, produceva il programma tradotto perforando il risultato della traduzione ancora su schede. A questo punto, posizionato il programma tradotto sul lettore di schede, veniva attivato ancora manualmente il caricatore per trasferire in memoria il programma tradotto. E infine, di nuovo manualmente, ne veniva attivata l'esecuzione. Questo tipo di comportamento, che prevedeva di continuo l'intervento manuale dell'utente, implicava un'efficienza di uso delle costose risorse di macchina paurosamente bassa, meno dell' 1%. È sufficiente pensare che per eseguire un tipico lavoro (job) costituito dall'esecuzione in sequenza di tre programmi, il compilatore, il caricatore e il programma utente, era necessario un tempo complessivo dell'ordine di decine di minuti, quando il tempo di reale esecuzione della CPU era limitato a pochi secondi. E tutto ciò, ovviamente, in assenza di eventuali errori di programmazione . Inoltre questo tipo di comportamento prevedeva che l'utente fosse particolarmente esperto del funzionamento del sistema. L'unico reale vantaggio era costituito dal fatto che, operando direttamene sulla macchina, l'utente poteva effettuare la fase di test
8
Capìtolo 1 Concetti introduttivi
e debugging di un programma in modo molto efficiente operando direttamente tramite la consolle. Gli unici programmi di sistema presenti su questi primi sistemi di. elab?razi?ne erano costituiti dai componenti del sist~ma 1i programmazi?ne ~ con:ipilaton, can~atori, debugger) e, più tardi, anche da hbrene, soprattutto hbrene d mgress?/_uscita, utili per semplificare l'accesso ai dispositivi senza doverne conoscere tutti 1 complessi dettagli realizzativi. 1.2.2 I primi sistemi batch
È per far fronte ai gravi problemi di ef~cienza di uso delle costose risorse. di n~a~china, tipici dei primi sistemi di elaborazione, che nacquero, tra la fine degh anm 50 e l'inizio degli anni '60, i primi sistemi operativi. Il primo obiettivo fu quello di ridurre l'intervento manuale dell'utente. Ciò fu ottenuto nel seguente modo:
temente (da ciò deriva il nome di · t . b h . . . . . . . . . s1s emi ate con cm questi pnm1 s1stem1 operativi sono stati conoscmti) In qu t d -1 . . . b .· es o mo o 1 monitor poteva passare dall'esecuzione di un JO a ~uella del Job successivo senza soluzione di continuità. L'intervento manuale dell oper~tor~ avveniva solo alla fine dell'esecuzione di un batch di job. A quel punto vemva inserito sul lettore un nuovo batch, raccolto durante l'esecuzione · d'1nuovo natt1vata · · del batch precedente. , e la mace h'ma veniva manualmente . . Con que~t,a tecnica l'efficienza aumentò pur rimanendo molto bassa (nell'ordine d1 poche umta percentuali). Le caratteristiche essenziali di questo tipo di sistemi erano tre: •
1. I programmi componenti il sistema di programmazione furono resi disponibili su
memoria di massa, all'epoca nastri magnetici. 2. L'utente-programmatore forniva il proprio programma sorgente a un operatore, unico abilitato a operare direttamente sulla macchina. Per abilitare l'utente a specificare di quali programmi di sistema avesse bisogno per portare a termine il suo lavoro (job) fu definito un linguaggio di controllo, detto anche job contro! language (JCL) (l'antenato dei moderni shell). Utilizzando tale linguaggio l'utente presentava all'operatore il proprio pacco di schede contenente, oltre alle schede su cui erano perforati sia il programma sorgente che i dati da elaborare, anche le cosiddette schede di controllo (nelle quali erano perforati i comandi del JCL), caratterizzate dall'avere un primo carattere particolare come, per esempio, il carattere $, in modo tale da poterle facilmente riconoscere dalle schede contenenti le istruzioni e i dati del programma. 3. Fu definito un nuovo programma di sistema, detto monitor (il primo esempio di sistema operativo), il quale era residente in una porzione della memoria a esso riservata. Questo era un semplice programma ciclico che si limitava a leggere le schede e, per ogni scheda di controllo, ne interpretava il contenuto nel senso di caricare in memoria, prelevandolo dal nastro magnetico, il programma di sistema richiesto mediante quella scheda. Terminato il caricamento in memoria del programma richiesto, il monitor trasferiva il controllo della CPU alla sua prima istruzione tramite un 'istruzione di salto. Al termine della sua esecuzione il programma così attivato invece di eseguire l'istruzione di halt, che avrebbe fermato la macchina, restituiva il controllo al monitor ancora tramite un salto e questo continuava con l'esame della successiva scheda di controllo e così via fino alla particolare scheda di controllo che rappresentava la fine dell'esecuzione dell'intero job. Solo a questo punto era previsto un nuovo intervento manuale da parte dell'operatore per caricare un nuovo job sul lettore di schede.
~J fine ~i ridur:re ulteriormente l'intervento manuale dell'operatore fu inoltre deciso d1 orgamzzare il lavoro del sistema caricando sul lettore di schede invece di un solo pacco, c~rrispondente .a! job ~i un ~in~olo ~tente, un lotto di pacchi di schede, corrispondenti ad altrettanti JOb d1 utenti d1vers1 che l'operatore aveva raccolto preceden-
9
•
•
La prima, positiva, legata all'incremento dell'efficienza di uso delle risorse di macchina. Tale incremento fu ottenuto semplicemente limitando l'intervento manuale anche se ci~ implicò la necessità di dedicare al nuovo sistema operativo parte della mem_o_na e anche parte del tempo di CPU durante il quale non poteva~o essere eseguiti programmi applicativi (overhead di sistema). Il sistema operativo era fondamentalmente costituito dal monitor e da un insieme di semplici routine di gestione dei dispositivi d'ingresso/uscita chiamato BIOS (Basic Input Output System). La seconda, negativa, implicò un allontanamento dell'utente dalla macchina. Il programmatore che portava il proprio pacco di schede all'operatore riceveva i risultati (sotto forma di tabulato) dopo ore se non giorni. Ciò ebbe conseguenze molto negative sulla lunghezza e complessità della fase di debugging di un programma. Una terza caratteristica, ancora negativa, era legata al fatto che i programmi venivano eseguiti in modo completamente sequenziale e nello stesso ordine con cui comparivano i relativi pacchi di schede sul lettore. Poteva quindi accadere che un utente che aveva presentato un programma molto semplice, e quindi eseguibile molto rapidamente, dovesse aspettare anche per un lungo tempo la terminazione di un programma molto più complesso e richiedente molto tempo di esecuzione, solo per il fatto che il pacco di schede del secondo programma era stato posizionato sul lettore prima di quello relativo al programma semplice. In altri termini il sistema era caratterizzato dalla impossibilità di intervenire sull'ordine di esecuzione dei programmi (scheduling).
1.2.3 Sistemi batch multiprogrammati
Il principale motivo per cui l'efficienza rimaneva ancora molto bassa nei primi sistemi batch era legato alla notevole differenza fra la velocità della CPU e quella, molto più lenta, dei dispositivi periferici (soprattutto lettore di schede e stampante). Perciò, quando la CPU attivava un trasferimento di dati (per leggere le schede o stampare i risultati di un programma) doveva restare in attesa della fine del trasferimento, e questi tempi di attesa erano di alcuni ordini di grandezza superiori a quelli con cui la CPU era in grado di eseguire un intero programma. Fu con l'introduzione a livello hardware, da un lato delle memorie di massa ad accesso casuale (dischi) e dall'altro dei meccanismi di interruzione e di DMA (Direct Memory Access) che verranno richiamati nei successivi paragrafi, che fu pos ibile apportare significativi miglioramenti.
10
Capitolo 1 Concetti introduttivi
Sistema Operativo
lettore
di schede
CPU e
stampante
11
Sistema Operativo Programma appli cativo 1
memoria
Programma applicativo
Programma applicativo 2 Programma applicativo 3
Figura 1.2 Sistema di spooling . 1
Un primo miglioramento si ebbe con l'introduzione della tecnica dello spooling • Tutti i job di un batch venivano preventivamente caricati su disco in modo tale che durante le loro esecuzioni la CPU leggesse i dati e producesse i risultati operando solo col disco (molto più veloce dei lettori di schede e della stampante). Mentre il calcolatore eseguiva i programmi di un batch, operando in DMA venivano contemporaneamente caricati su disco i job del batch successivo e, in parallelo, venivano stampati i risultati del batch precedente prelevandoli ancora dal disco (vedi Figura 1.2). In questo modo si ottennero due vantaggi: •
Operando la CPU direttamente solo con periferiche veloci, si ridusse drasticamente il suo tempo di attesa aumentando quindi la sua efficienza di uso. • Avendo su disco l'insieme di programmi da eseguire (detto anche pool dijob) fu possibile implementare una politica di scheduling scegliendo, di volta in volta, quale eseguire per primo in base a una certa regola. Per esempio, una possibile regola dava la precedenza ai programmi con tempo di esecuzione più breve (shortest job first) eliminando così l'inconveniente visto precedentemente. Però, fu possibile ottenere un drastico miglioramento nell'efficienza di uso delle risorse di macchina soltanto quando, utilizzando il meccanismo fisico delle interruzioni, fu realizzata la tecnica della multiprogrammazione (multitasking). Questa tecnica costituisce la vera chiave di volta nello sviluppo dei sistemi operativi e si basa su un'osservazione molto semplice. Invece di caricare in memoria fisica un solo prograrruna ed eseguirlo fino al suo completamento prima di caricarne un successivo si caricano due o più programmi contemporaneamente in diverse aree di memoria (~edi Figura 1.3 ). In qu_est? mo~~· è possibil~ inizia_re l'esecuzione di uno dei programmi e, appena que~to _nch1~~e I mte':'~nto d1 un dispositivo d'ingresso/uscita e si pone in attesa che 1I d1spos1t1vo te~m1 l'opera~ione prima di poter continuare, è possibile dedicare !a C~U a un, altro dei pro~~mm1 prese~ti in memoria evitando così che questa resti mattiva. Cosi facendo, tutti I programmi presenti in memoria vengono fatti evolvere "con temporaneamente " , anc he se in ogni istante uno solo di essi è in reale esecu1
li termine spoo! è l'acronimo dell'inglese simu!taneous periphera/ operation on-fine.
Organizzazione della memoria in un sistema batch monoprogrammato
Organizzazione della memoria in un sistema batch multiprogrammato
Figura 1.3 Configurazione della memoria nei sistemi mono e multiprogrammati.
zione. Questo schema rispecchia, in parte, l'organizzazione del lavoro di un essere umano. Raramente il nostro cervello si limita a eseguire un solo compito alla volta dall'inizio fino alla fine. Molto più spesso, ciascuno di noi inizia varie attività e le porta avanti contemporaneamente, o meglio dedicando una frazione di tempo alternativamente a ciascuna attività. Un tipico esempio può essere quello di un maestro di scacchi che gioca contemporaneamente contro più avversari. Seguendo lo stesso criterio, un sistema di elaborazione può eseguire più programmi contemporaneamente anche se in ogni istante dedica le proprie risorse a uno solo di essi. Con la tecnica della multiprogrammazione è possibile ridurre drasticamente il tempo di attesa della CPU e quindi migliorare notevolmente la sua efficienza fino a ottenere valori che superano 1'80%. Per chiarire il concetto, supponiamo di dover eseguire tre programmi P 1, P 2 e P 3 con le seguenti caratteristiche: P 1 esegue per 1 unità di tempo (espressa, per esempio, in multipli di millisecondi) quindi attiva un trasferimento e resta in attesa per 4 unità. Successivamente esegue ancora per altre 2 unità prima di attivare un nuovo trasferimento e restare in attesa per ulteriori 3 unità di tempo. Infine, riprende l'esecuzione e termina dopo un'ultima unità di tempo. P2 esegue per 1 unità prima di bloccarsi per 6 unità. Quindi riprende l'esecuzione e termina dopo un'ultima unità di tempo. Infine, P 3 esegue per 1 unità, successivamente si blocca per 4 unità e poi riprende l'esecuzione e termina dopo ulteriori 3 unità di tempo. In Figura 1.4 viene riportato un diagramma temporale relativo ali' esecuzione sequenziale dei tre programmi, uno alla volta. Nella figura, i tratti pieni rappresentano periodi di esecuzione, mentre quelli tratteggiati periodi di attesa di un programma (e quindi anche della CPU). Inoltre, con il simbolo "l" viene rappresentata la fine di un periodo di attesa (corrispondente all'interruzione di fine trasferimento da parte del dispositivo) e con l'asterisco(*) la terminazione di un programma.
12
Capitolo 1 Concetti introduttivi 13
,I
;
,
I
,I
wI , , , I
I
I
'H-
O
:--+--+--+------.. : : :1 *
I , I, I ,I ,I ,I ,I
I""
l---~--t--t--+--t--
__ . 1 - - ~ - - . l - - ~ - - L - - L - 1
:
:
:
I
I
I
:
:
I
I
2
3
4
S
6
7
8
9
IO
11
:
:
I
I
I
I
:
12
13
14
IS
16
17
18 19
I I
I I
I
I I
I
20
21
22
23
24
25 26
I
----~----j__ ___ L___
:
27
P3
:
:
:
I ---- ~
I
:
I
I
i
:
:
:
:
~ I
: : : - - - - ~ - - - - - ' ____ I_
i
i
-1
i
i : :
i
--r----1----~-----~
I : 1
: :
I
:
*
*
: I
l
:
I
i ---;-----,---- ----t-----....i-----~ : : I : : : : :
----r---- ~ - ---~----~---- ~---
:
:
:
l
:
:
I
I
I
I
1
:
Figura 1.4 Esecuzione sequenziale.
Come si può notare, per completare l'esecuzione dei tre programmi sono necessarie 27 unità di tempo durante le quali, però, la CPU esegue programmi solo per 1Ounità di tempo. L'efficienza complessiva con cui viene usata la CPU è quindi pari a 10/27 e cioè pari al 37% del suo tempo. In Figura 1.5 viene riportato un analogo diagramma temporale nel caso in cui il sistema sia multiprogranunato, e cioè con i tre programmi presenti contemporaneamente in memoria e con la CPU che, quando non può proseguire l'esecuzione di un programma, viene commutata, se possibile, su un diverso programma in grado di essere eseguito. Come si può notare, con la multiprogrammazione si ha un notevole vantaggio per quanto riguarda la velocità di esecuzione dell'insieme complessivo dei programmi. In esecuzione sequenziale erano necessarie 27 unità di tempo, adesso l'esecuzione di tutti e tre i progranuni tennina dopo 12 unità. Questo è ovviamente una conseguenza della maggiore efficienza con cui la CPU viene usata. Come si può notare nell'esempio, la CPU resta inattiva per due sole unità di tempo (fra le unità 3 e 5). L'efficienza diventa quindi pari a 10/ 12 e cioè superiore a 83%. Aumentando il numero di programmi in esecuzione contemporanea (valore noto col termine di grado di multiprogrammazione) in teoria l'efficienza può essere ulteriormente aumentata. Infatti, nel precedente esempio, nelle due unità di tempo in cui la CPU è restata inattiva questa avrebbe potuto eseguire un eventuale quarto programma. Questo valore di efficienza è in realtà solo teorico poiché in un sistema multiprogrammato è necessario tener conto che la CPU deve dedicare una porzione del proprio tempo alla realizzazione del meccanismo necessario a trasferire il controllo della stessa CPU dal1'esecuzione di un programma a quella di un altro. Questo meccanismo è noto col termine di cambio di contesto e, come verrà illustrato in dettaglio nel Capitolo 2 , comporta un aumento dell 'overhead di sistema. Infatti, quando un programma non può proseguire poiché, avendo attivato un trasferimento di dati deve attendere il suo completamento, viene chiamata una funzione del sistema operativo che salva lo stato della CPU (e cioè i valori di tutti i suoi registri) in un'area di memoria da cui verrà successivamente recuperato quando il programma dovrà tornare in esecuzione. Inoltre, parte del tempo di CPU è necessario per eseguire le routine di risposta delle interruzioni provenienti dai dispositivi. È infatti all'arrivo di un'interruzione che il sistema operativo deve essere avvertito che è terminata un'operazione di trasferimento dati e che quindi il programma che l'aveva precedentemente attivata è da adesso, in grado di tornare in esecuzione. '
i
t
: :
!
i
:
:
:
:
*
IO
:
l
:
:
Il
12
13
Figura 1.5 Esecuzione in multi-tasking.
Con l~i~troduzione _della ~ultiprogrammazione, i sistemi operativi non sono più semphci programmi come 11 monitor dei primi sistemi batch, che si limitavano a sequenzializzare i programmi applicativi richiesti dai vari utenti. Adesso, avendo più programmi in esecuzione, è necessario che il sistema operativo si occupi anche della gestione di tutte le risorse per evitare interferenze tra programmi diversi. Infatti, se l'accesso alle risorse non fosse controllato e regolato dal sistema operativo, un programma in esecuzione potrebbe tentare di operare su un dispositivo quando lo stesso sta già lavorando a favore di un altro programma. Inoltre, è necessario che il sistema operativo implementi dei criteri in base ai quali assegnare le risorse ai vari programmi in esecuzione che ne facciano richiesta (algoritmi di scheduling). Per esempio, se non è possibile caricare in memoria contemporaneamente tutti i programmi appartenenti a un batch, e presenti su memoria di massa in attesa di essere eseguiti, il sistema deve sceglierne un sottoinsieme da eseguire in multiprogrammazione (job mix) mentre gli altri verranno eseguiti successivamente. Un criterio spesso adottato è stato quello di scegliere un mix di programmi con caratteristiche diverse, per esempio alcuni richiedenti molti calcoli e pochi trasferimenti di dati (CPU-bound) e altri richiedenti pochi calcoli ma molti trasferimenti e su periferiche diverse (l/0-bound) in modo tale da ottimizzare l' uso di tutte le risorse di macchina. Inoltre, quando un programma in esecuzione non può proseguire a causa del1' attivazione di un trasferimento dati ed è quindi necessario commutare la CPU su un altro programma, si pone il problema di scegliere a quale programma cedere il controllo. Per esempio in Figura 1.5, all'istante 10 la CPU termina l'esecuzione del programma p 3 e a quel punto sono già terminati anche i periodi di attesa dei programmi p 2 e p 1 , ciascuno dei quali può quindi riprendere la sua esecuzione. Si pone quindi il problema di quale fra questi eseguire per primo. Un crit~?o spess? adottato è quello di scegliere (come mostrato in fig~ra! qu~llo che. da pm tempo ~ pronto per essere eseguito, adottando quindi un cnte:10. Frrst-In-Frrst-Out. In ~ltn sistemi, all'epoca spesso utilizzati nell'ambito di centn d1_ca~colo, ~ote_v~ es~er~ implementato il criterio di scegliere per primi i programmi di utenti pnvilegiah, per . . , esempio in base a diversi livelli di tariffe. c l'introduzione della multiprogrammazione, e d1 conseguenza con l aumento plessità del sistema operativo, furono introdotti nuovi meccanismi hardwad e li a on com · d 11 funz. · d l · re necessari per garantire una corretta ed efficiente esecuzione e e 10m e si-
14 Capitolo 1
Concetti introduttivi stema. Come vedremo nel Paragrafo 1.3, sono stati introdotti meccanismi di protezione sia della memoria (per evitare che lo spazio dedicato a un programma sia erroneamente manomesso durante l'esecuzione di un altro programma), sia della CPU, con l'introduzione del doppio stato di esecuzione (privilegiato/non privilegiato) per garantire che le istruzioni macchina con cui è possibile modificare lo stato di una qualunque risorsa fisica siano eseguibili solo da parte di funzioni del sistema operativo. I sistemi batch multiprogrammati hanno costituito i primi complessi sistemi operativi funzionanti sui grossi mainframe. Un classico esempio è costituito dal sistema OS/360 funzionante sulle macchine IBM della serie 360 e, successivamente 370 [16]. 1.2.4 Sistemi time-sharing La multiprogrammazione da un lato e il controllo dell'esecuzione dei programmi secondo la filosofia batch dall'altro, ebbero un notevole successo e favorirono lo sviluppo dei sistemi operativi. I motivi del loro successo erano legati alle caratteristiche dei sistemi di elaborazione che, in quel periodo (fino alla metà degli anni '60), erano costituiti esclusivamente dai grossi sistemi (mainfiwne) presenti nei centri di calcolo, estremamente costosi e fondamentalmente dedicati all'esecuzione di programmi applicativi di tipo tecnico/scientifico che non avevano particolari necessità di interagire direttamente con il progranunatore. Le caratteristiche peculiari di questi sistemi erano: • •
l'alta efficienza raggiunta nell'uso delle costose risorse di calcolo; l'impossibilità da parte del progranunatore di interagire direttamente col sistema; il lungo tempo di completamento di ogni programma (inteso come l'intervallo temporale compreso fra l'istante in cui il programmatore consegnava il proprio pacco di schede all'operatore e l'istante in cui otteneva il tabulato con i risultati).
Con Io sviluppo dei primi programmi applicativi di tipo interattivo i sistemi batch iniziarono a mostrare il loro limite. Questa categoria di applicazioni prevede che il programma in esecuzione debba interagire con l'utente. Si pensi, per esempio a un sistema transazionale tipico di molte applicazioni gestionali (sistemi bancari, sistemi per la prenotazione di posti su aerei ecc.). In questi casi è necessario che l'utente, tramite un terminale collegato al sistema, e disponendo di un opportuno linguaggio di controllo analogo al JCL dei sistemi batch, ma con i singoli comandi battuti direttamente sul terminale, indichi al sistema quali operazioni sono richieste. Normalmente, il sistema resta in attesa che l'utente batta una comando, visualizzando sul video del terminale un particolare carattere (prompt) . Quando l'utente ha terminato di battere un co_m an~o _il sistema carica in memoria, ed esegue, un programma che svolge il compito nch1e_sto dall'utente, alla fine del quale visualizza di nuovo il segnale di pro~pt e resta m _attes~ del prossi?1o comando. Questo tipo di comportamento implica che I u_te?te open sul s_1stema all 'mtemo di sessioni di lavoro che iniziano quando l'u~ente _si si~de a uno dei terminali collegati al sistema e, specificando il proprio codice 1dentI~cat1vo ~user-ID) e la_ prop~a parola d'ordine (password), si collega col sistema operativo (lo!J!n). Una sess10ne d1 lavoro coincide, sostanzialmente, con l'invio di un co~a~d~ al sistema, ~?n !'esecuzione da parte del sistema del compito richiesto e qm~di, di nuov~, c~n l mv10 del comando successivo e così via fmo a quando, inviando Il comando d1 chmsura (logout), l'utente non decide di terminare la sessione.
15
. Anche in questo tipo di sistemi· 1a mu 1hprogramm · · . . b) a=a-b; else b=b-a;
dove a e b sono due variabili locali al programma. Evidentemente il programma termina quando i valori di a e b coincidono con il M.C.D. dix e y. Per schematizzare il processo svolto da un elaboratore C durante l'esecuzione del precedente programma, possiamo ricostruire la storia del processo evidenziando gli stati attraverso i quali passa l'elaboratore in termini di valori delle variabili coinvolte. Per esempio, il processo svolto quando il programma viene eseguito con i valori di ingresso x= 18 e y=2 4 è mostrato in Figura 2.1. .. . . . Owiamente il processo sarebbe stato diverso se diversi fossero _st~t, 1 valon d1 mgresso. Ciò mette in luce un'ulteriore distinzione tra i due concetti di programma (entitd statica) e processo (entitd dinamica). Possiamo cioè ~ir~ che un programma descrive in realtà non un processo, ma un insieme di processi (istanze del ~rogramma ), ognuno dei quali è relativo all'esecuzione del programma da parte dell elaboratore per un ben determinato insieme di dati di ingresso.
2.2 Stati di un processo M
, tt t ansizioni di stato definite in parte entre un processo è in esecuzione, e sog~e O a rd t'1 esterni asincroni con la dall'attività corrente del processo stesso e m parte a even
52
Capitolo 2
----------------- -
Gestione dei processi 53
sospensione
riattivazione Figura 2.2 Stati di un processo.
sua esecuzione. Da un punto di vista astratto, se esistessero tante unità di elaborazione fisiche quanti sono i processi, gli stati di un processo sarebbero attivo o bloccato, come descritto in Figura 2.2. Un processo attivo transita nello stato. di bloccato (sosp~nsione) qua_n_do attend~ il verificarsi di qualche evento. Per esempio un processo puo sospendersi m attesa di un'interruzione da parte di un dispositivo, oppure in attesa di ricevere un messaggio, oppure in attesa della sincronizzazione con un altro processo. Il significato dello scambio messaggi e della sincronizzazione sarà chiarito più avanti. Il processo può transitare allo stato di bloccato anche per una decisione presa autonomamente dal sistema operativo quando, per esempio, l'esecuzione di una istruzione genera un~ condizione d'eccezione (riferimento a un indirizzo di memoria virtuale che non si trova in memoria principale ecc.). Il processo è riattivato quando l'evento atteso si è verificato (riattivazione). Lo schema tipico è quello in cui un altro processo in esecuzione genera l'evento atteso (segnale di sincronizzazione, messaggio). L'interruzione da parte di un d_isp?sitivo esterno si può considerare, come si vedrà nel Capitolo 5, come un segnale mviato da un processo esterno. . . In generale il numero di unità di elaborazione è inferiore al numero dei processi. Nel seguito, per semplicità, supporremo di operare su un sistema dotato di una sola unità di elaborazione fisica (sistema monoprocessore). In questo caso, di tutti i processi attivi uno solo può utilizzare l'unità di elaborazione in ogni istante; tutti gli altri sono pronti per essere eseguiti ma, in realtà, in attesa essi stessi che venga loro assegnata l'unità di elaborazione. Gli stati di un processo possono quindi essere descritti come illustrato in Figura 2.3. Lo stato attivo viene suddiviso in due stati, pronto e in esecuzione. La transizione dallo stato di pronto a quello di esecuzione (assegnazione dell'unita' di elaborazione) avviene quando, in seguito al blocco del processo in esecuzione, il processo viene scelto per essere eseguito tra tutti i processi pronti. La transizione dallo stato di esecuzione a quello di pronto è chiamata revoca o prerilascio (preemption) e può avvenire per vari motivi. Per esempio, nei sistemi in cui la scelta del processo da mandare in esecuzione è fatta in base a una priorità fra i processi, può accadere che il processo in esecuzione (queJlo a priorità più alta rispetto a tutti i processi pronti) generi un segnale che sveglia un processo a priorità più alta della sua. In questo caso l' unità di elaborazione viene revocata al processo in esecuzione per essere assegnata al processo svegliato.
assegnazione unità di elaborazione
revoca unità di elaborazione
riattivazione
Figura 2.3 Stati di un processo in sistemi in cui il numero di processi supera il numero del-
le unità di elaborazione.
In altri sistemi in cui l'unità di elaborazione viene assegnata a divisione di tempo, quando un processo va in esecuzione viene inizializzato un dispositivo temporizzatore (timer) che lancia un'interruzione dopo un certo intervallo di tempo. Se durante tale intervallo il processo non si è bloccato, all' arrivo dell'interruzione l'unità di elaborazione viene revocata dal sistema operativo per essere assegnata a un altro processo pronto. Il processo precedentemente in esecuzione transita nello stato di pronto. Il passaggio dallo stato di pronto a quello in esecuzione comporta una scelta tra tutti i processi pronti. Questa scelta viene compiuta da una funzio~e ~i ge~tione ~el processore (sch eduling) che fa parte del nucleo del sistema operativo 11 cm comp~t~ è assicurare che tutti i processi pronti possano avanzare, controllandone la veloc1ta di avanzamento. . . . Per completare il grafo di Figura 2.3 occorre aggiungere due ultenon stati, nuovo e terminato. Lo stato nuovo corrisponde alla creazione di un nuo: 0 processo che . per esempio . per effetto de1co Il egamento al sistema di un uten. , nuovo . h puo, avvenire . ' ' . . d rt d · un processo g1a esistente c .e te m un sistema interattivo o per la nch1esta a pa e i L d ·tO he deve svolgere. a transi. i~tende delegare al nuovo processo pa~e e1 comp_i c uando il sistema operativo z10ne dallo stato di creato allo stato d1 pronto avv~ene q ·b·t· · tr tra quelli esegm 1 1. dec1·d e che il nuovo processo puo' nen are . · e normale in cui il pro. d O a una termmaz1on L o stato terminato puo, comspon . . d·care il completamento delle ere I cesso esegue una chiamata al sistema operativo per m ta per esempio da un uso . . , . . normale provoca ' ' on·a superamento del tempo sue att1v1ta, oppure a una termrnazione ~ . . . d' . t dei hmttl t mem ' . scorr~tto delle nsorse (superamen il rocesso ecc.) oppure dall 'esecuz10mass1ID0 di utilizzo della CPU consentito_per Il P sso transita, quindi, dallo stato ne di istruzioni non consentite o non vahde. proce di esecuzione allo stato terminato.
° .
54 Capitolo 2
- - - - - - - - - - - - - ---------~G~e:?.st~io~n~e~d~e~i~pr~o~ce~s~si~S~5
assegnazione unità di
riattivazione
Figura 2.4 Modello a cinque stati .
Si ottiene in questo modo il modello a cinque stati riportato in Figura 2.4. Si noti, per concludere, che in taluni sistemi è prevista la possibilità per un processo presente in memoria principale di essere temporaneamente spostato in memoria secondaria (swapping) in modo da liberare spazio per altri processi (vedi Capitolo 4). Le motivazioni di questa scelta sono generalmente legate a motivi di efficienza: i processi che vengono spostati in memoria secondaria sono generalmente bloccati in attesa del verificarsi di qualche evento e quindi impossibilitati a usare l'unità di elaborazione. Agli stati precedenti va quindi aggiunto un ulteriore stato corrispondente a un processo temporaneamente spostato in memoria secondaria.
2.3 Descrittore di un processo A ogni processo è associata una struttura dati, detta descrittore del processo (PCB Process C?ntrol Block). I descrittori dei processi sono a loro volta organizzati in una tabella, chiamata comunemente tabella dei processi. I dati util!zzati per descrivere i processi dipendono dalle scelte di progetto del si~tema op~ra~ivo e d.alla struttura della macchina fisica. In linea del tutto generale le mfonnazwm da registrare nel descrittore possono essere così classificate: a) Nome ~e! P_rocesso. ~a ~celta più comune è quella di identificare ogni processo con .un mdice, .che com_c1de con quello della sua posizione nella tabella dei proc~ss1. Quando .1processi sono organizzati in gruppi, oltre al nome è necessario registrare anche Il gruppo . . . di appartenenza, come s1· vedra' parlando del sistema operativo UNIX (vedi Capitolo 8).
b) ~tato .del pro~esso. Q~est~ i~formazione può essere registrata esplicitamente nel e~cnttor~ odnsultare implicitamente dall'appartenenza del descrittore a una delle co e gestite al nucleo del sistema operativo (Paragrafo 2.4).
e) Modalita' di servizio dei processi L · ' d i' e Ia b orazione · scelta a quale processo pronto assegnare l'umta può essere ·effiattu ' 11 FIFO (F' e · · Il p1u ·, semplice e que o zrst-In-First-0 t) ata h secondo div ersi· cnten. elaborazione al processo pronto in autt ' c de P~~vede l'assegnazione dell 'unità di esa a pm tempo D' , cesso puo essere assegnata una prio ·r fi . ·. 1versamente a ogni pro1 scrittore che indica la sua importan n a, s~a O v~nablie, contenuta nel suo de. fì . , za re 1ativa nei confr0 f1 d l' 1 • • Tale m orm~z10ne puo essere espressa anche . . . ~ . eg I a t~ proces~1. cui l'esecuzione del processo deve es m termmi d1 mtervallo d1 tempo m sere portata a term· (d di' scrittore del processo, in questo caso è t me ea me). Nel destante della richiesta di servizio da pa,rtecdonl enuto un valore che, sommato all'ie processo d t · ·1 · mo entro il quale la richiesta deve essere s0 dd' f: ' . e e~ma I tempo massi1 t modalità di servizio del tipo a sudd' · . . s atta (szS emz zn tempo reale). Per 1v1s10ne d1 tempo nei de ·tt . , un valore che rappresenta il quant 0 d'1 ' . scn on e contenuto tempo consecutivo che l' . , . d' l b z10ne puo dedicare allo stesso processo. um a 1 e a ora-
·r
d) Informazioni sulla gestione della memoria Conti'en l · e1 · . . · · 'd l' d' · . · e e m ormaz1om necessane a md1v1 uare area i memona pnncipale nella quale so · · ·1 d' · . . . . no cancah I co ice e 1 dati· del processo. Queste mformaz1om s1 possono espnm· ere . . . . attraverso I· va1on· de1· regzstrz base e lzmzte, le tabelle delle pagine o le tabelle de· · . . . z segmen n·, secon d o 1·1 sistema di gest10ne della memona ~sato dal sistema operativo (vedi Capitolo 4). e) Co,ntesto del process.o. Tutte le mformazioni contenute nei registri di macchina all atto dell'esecuzione di un processo vengono salvate ne 1 suo . della sospensione . . d es~n~ore. ~ah ~fo:°1-azioni .(contesto) riguardano il contatore di programma e un msieme d1 registn che vanano a seconda del tipo di architettura dell ' elaboratore. Essi comprendono registri contenenti informazioni relative ai codici di condizione ~PS - Program Status word), di cui un esempio è il registro EFLAGS del. Pent~um [112], puntatore allo stack (stack pointer), registri indice, accumulaton, reg~stri di uso generale. Il contesto viene ricopiato dal descrittore ai registri quando 11 processo torna in esecuzione. t) "U_tilizzo delle risorse. Queste informazioni comprendono la lista dei dispositivi di I/O assegnati al processo, i file aperti, il tempo di uso della CPU ecc. g) ldentifzcazione del processo successivo. Come si è detto, a seconda del loro stato (pronto o bloccato), i processi vengono inseriti in apposite code. Ogni descrittore contiene pertanto il nome del processo successivo nella stessa coda.
Le informazioni contenute nei descrittori sono vitali per il sistema operativo e devono essere opportunamente protette. I descrittori devono quindi essere memorizzati in un'area di memoria accessibile solo dal nucleo del sistema operativo.
2.4 Code di processi Come si è visto, nell'ipotesi di una sola unità di elabor~io.ne, a ogni istant.e un s?l~ processo è in esecuzione mentre gli altri sono o bloccati, m attesa del venficarsi d1 un determinato evento, o'pronti per essere eseguiti. In generale, _l' in?icazion~ di quale processo è in esecuzione viene mantenuta dal sistema operativo m un registro d 1 processore il cui contenuto è il puntatore al descrittore del processo (registro del processo in esecuzione).
----
------------=-::------.. liQf 56
Capitolo 2
primo
primo
ultimo
------ ,
ultimo
I I I
o
.
Figura 2.5 Inserimento e pre Iievo
o
di un descrittore.
. ·ncipale che sono pronti e nell'attesa di essere . t' nella memona pn . ') A . processi prcsen 1 . . . ( . , ) code (code dei processi pronfl . ogni coda 0 1 e eguiti_sono orgam~att ~ . un~ ~:enente una coppia di valori che rappresentano è_as 0~1ato un de.~cn~or~e/ ~~~oc e ultimo descrittore di processo in coda; ciascun nspctt1vainente .1 rnd 1~ed . 1. e del proces O uccessivo contenuto nella coda dei descrittore contiene 1 tn icazion . una co d a reg1s · t ra 1a trans1z1one · · · Processi pronti. d' · · ento di un proce so m m · L'operazione I msenm . , . . . · d' cesso ospeso o in esecuz10ne; 1 operazione d1 prelievo corstato dt pronto I un pro . . ,. . . d · • ·n tato di e ecuz1one d1 un processo pronto. Nell 1potes1 d1 un nspon e a1 passaggio 1 • • • • . to FIFO delle code , le due operaz1om sono illustrate nella Figura .2.5, ord111amcn · . . . do-, ve il tratteggio indica la situazione prima delle operaz10m. ~ella_ figura, a s1mstra e rappresentata l'operazione di inserimento e a destra quella d1 P~~hevo. Tra i proces i pronti ne esiste uno, chiamato processo flttlzw (dummy P_rocess), che va in esecuzione quando tutti i processi sono temporaneamente bloccat1. ~l proces o fittizio ha la prio1ità più bassa ed è sempre nello stato di pronto. Esso nman.e in esecuzione fino a quando qualche altro processo diventa pronto, eseguendo un. c~clo senza fine oppure una funzione di servizio di bassa priorità che non deve mai nsultare bloccante per il processo. Come si vedrà nel seguito (vedi Paragrafo 2.9), è compito di un particolare componente del sistema operativo, lo short term scheduler, la scelta di quale processo mette~e in es~cuzione tra quelli pronti sulla base di prefissati criteri. . . Es1.s~ono mol~e code per i processi bloccati, una per ogni evento o condtz~on_e per ~~ 1 1 pr?cess_t pos_sono attendere. A titolo di esempio, esistono code per ogni dtspoSittvo ~1I/O ~n ~u, ven.gono inseriti i descrittori dei processi in attesa del completamento dt una di J/0 su quel partico1are d'1spos1tivo. .. . . nch1esta . In aIcu111 s1stem1 può essere .. . . . .. presente una coda nella quale sono concatenat'1 1· desc11tton d1spo111bzh per la creazione di nuov· . L' . d' creazione estrae da questa coda il desc . l process1. operaz,10ne 1 . te concatenato nella d d . nttore ~el processo da creare che verra success1vam~n . ~o _a e, proces si pronti. Viceversa l'operazione di eliminazwne d1 un processo restituisce nella cod ·i d . l na1 tiva l'operazione di creazio , a escnttore del processo eliminato. In a t~r e e l'operazione di termina · ne pluo co~portare la definizione di un nuovo descnttor z10ne a sua distruzione. I
Gestione dei processi
57
2.5 Cambio di contesto Il cambio del processo correntemente · . dei process i pronti comporta l'es . m e~ecu~io?e con un altro scelto dalla coda . . . ecuz1one d1 un insieme d.1 . . I to il nome dt cambw di contesto T 11. operazioni c 1e vanno sot. . . a operazioni sono: 1. Salvataggio del contesto del processo in · . · d Id · esecuzione nel suo descnttore 2. Insenmento e escnttore nella coda dei · bi · . · . · I · d· I processi occatt o dei processi pronti 3. Se ez1one 1 un a tro processo tra quelli conte t'1 11 d · caricamento del nome di t I ?u ne a co a dei processi pronti e a e processo nel registro processo in esecuzione . · tn· de1processore. · 4. Cancamento del contesto del nuovo processo ne·1reg1s il nome stat o e npns · · t·mo sa t to, Le operazioni·1 1 e fì4, ·che prendono .. . . di salvataggio . comportano_ 1 tras enmento dt mforrnaz10111 da1 registri di macchina alla memoria centrale e viceversa. La complessità della loro realizzazione (numero dei· · tn· ·· · · · d' · · . . reg1s su cui mtervemre, tipi 1 1struz1om disponibili) è strettamente dipendente dal tipo di architettura del sistema. L'operazione 2 prevede l'inserimento del descrittore nella coda associata all' evento atteso ~se il ca°:bio di _cont~sto è dovuto alla sopensione del processo) oppure nella coda de, processi pronti (se ti cambio di contesto è dovuto a una revoca). L'operazione 3 (short term scheduling) può operare sulla base di un algoritmo di tipo FIFO nel caso esista una sola coda per tutti i processi pronti o utilizzando l'informazione relativa alla priorità dei processi nel caso di più code di processi (una per livello di priorità). Come si è detto all'inizio, in questo capitolo l'accento è posto unicamente sulle operazioni che il nucleo del sistema operativo deve compiere per consentire l'assegnazione della CPU ai processi (astrazione CPU virtuale). Occorre ricordare, tuttavia, che il cambio di contesto comporta l'aggiornamento di tutte le strutture dati che rappresentano le risorse utilizzate dai processi: memoria, dispositivi di I/0, file aperti ecc. Questi aspetti verranno esaminati nei capitoli successivi. Va fin da ora precisato, comunque, che (in particolare per quanto riguarda la memoria) si tratta di operazioni che possono fortemente influenzare l'efficienza dell'intero meccanismo.
2.6 Creazione e terminazione dei processi Si possono avere applicazioni nelle quali il numero dei processi è definito inizialmente e non viene più modificato durante il tempo di ~ita ?el)'~pplicazione. Situazioni di questo tipo si possono trovare in alcune appl_1caz10111 _m tempo reale,. per esempio per il controllo di impianti fisici, in cui tutti 1 processi vengono creati all'avvio dell'applicazione (creazione statica). . , . In generale, tuttavia, durante la sua esecuzione un processo puo creare altn processi utilizzando un ' apposita primitiva fornita dal nucl~o. Il processo _crea~te prend~ il nome di processo padre e il processo creato qu~llo d1 pr~cesso figlw. Ciascuno d~ questi nuovi processi può creare a sua volta altn processi, formando un albero d1 processi, come mostrato in Figura 2.6.
58 Capitolo 2
- - - --------------------~G~es~t~io~n!e~d~ei~p~r~oc~e~s~si~5~9 . . cesso possiede una propria unità di elaborazion ( ssi condividono la stessa unità di elaboraz· e (?verlapp'. ng) e 11 caso in cui i proe e . . . ione mterleaving) Una defimz1one generale d1 concorrenza eh · he due processi si dicono concorrenti quand ~ con:iprende ent_rambi i casi stabilisce 0 ~a dell'ultima dell ' altro. a pnma operazione di uno inizia pri-
1 processi concorrenti possono comportarsi com · d" . . . ti Un insieme di processi si dice indipendente quan~ m zpendend~10 c_om~ i_nteragen-
Figura 2.6 Gerarchia di processi .
Le politiche di scelta di quale programma il processo creato eseguirà, di condivisione di dati e risorse tra processi padri e figli e della loro sincronizzazione possono variare da sistema a sistema. Anche nel caso di terminazione di un processo, questa può avvenire secondo diverse politiche di segnalazione al processo padre o più in generale a un processo antenato. Rinviando alla soluzione adottata dal sistema operativo UNIX per la definizione di un esempio di politiche sia per la creazione che per la terminazione dei processi (vedi Capitolo 8), si sottolinea qui come il nucleo debba offrire i meccanismi per la realizzazione delle politiche. Tali meccanismi consistono in due primitive di creazione e terminazione dei processi. La primitiva di creazione dovrà, in base ai parametri ricevuti, inizializzare il descrittore del processo da creare e inserirlo nella coda dei processi pronti. Analogamente, la primitiva di terminazione provocherà la restituzione del descrittore alla coda dei descrittori liberi o la segnalazione che l'area di memoria può essere recuperata dal sistema operativo.
2. 7 Interazione tra i processi Con il tennine processi concorrenti viene indicato un insieme di processi la cui esecuzione si sovrappone nel tempo. La Figura 2. 7 rappresenta il caso in cui ogni pro-
0 nessuno 1essi puo mfluenza. · d 1· lt · p · re l'esecuz10ne eg i a n. rocess1 che non condivido d t· h . . . . . . . . no a 1e c e non s1 scambiano infonnaziom sono processi indipendenti. Come esempi·o d"1 . . d" d . . · d" 1 b · processi m 1pen enti si i e a orazione al quale utenti diversi· sotto . d ., Pensi a un· sistema ·1 l · 1 . pongono m mo a11ta time-sh~~g. oro pr?gramm1._ processi corrispondenti competono per l'utilizzo ma 11. nucleo del sistema operati·vo provvede a creare per della umta .d1 elaboraz10ne, . ciascuno di essi un proc_essor_e _v~ale. Lo stesso succede per la competizione per altre risorse (memona, dispositivi di I/0) che viene risolta da altre parti del sistema operativo. Car~tt~ristica ~o~d~i:nenta;e di ~n. processo indipendente è che il suo comportamento e rzproduc1bzle, m altn termm1 lo stesso processo eseguito in momenti diversi, contemporaneamente a insiemi diversi di altri processi indipendenti, produce sempre lo stesso risultato, se i dati di ingresso rimangono gli stessi. Caratteristica dei processi interagenti è la possibilità di influenzarsi vicendevolmente durante l'esecuzione. Questo può avvenire in modo esplicito mediante scambio di messaggi o segnali temporali (cooperazione) , oppure in modo implicito tramite competizione per la stessa risorsa (vedi Capitolo 3). Gli effetti delle interazioni dipendono dalle velocità relative di avanzamento dei processi. Poiché in generale tali velocità non sono predicibili, essendo funzione di eventi (per esempio le interruzioni) non dipendenti dal programmatore, il comportamento dei processi non e' riproducibile. Se si ripete l'esecuzione di un processo con gli stessi dati non si può garantire che le velocità relative siano le stesse e che quindi le interazioni avvengano nello stesso ordine. . . . .. Come esempio del primo tipo di interazione (cooperazione) s1 c?ns1de1:1 11 ~aso in cui un processo p 1 (produttore) produce ciclicamente un messaggio e l? mse~sc_e in un buffer B con capacità unitaria e un processo P 2 (consumatore) , anch esso c1chco, preleva il messaggio da B e lo consuma (Figura 2.8). . . . . Appare evidente che esiste una sola sequenza dell~ ~perazi~m de~ due ~rocessi che porta a un corretto funzionamento del sistema e c1oe (nel_! ipotesi eh~ il buffer · mizia · · · 1mente vuoto) inserimento-pre1·1evo- 1·nser1·mento-prelzevo sia , . . . . Ogm altra se· . d gia depositato ' ma non ancora quenza porterebbe o alla cancellaz10ne e1 messaggi 0
buffer
P,
overlapping Figura 2.7 Processi concorrenti.
interleaving Figura 2.8 Produttore e consumatore.
60
Capitolo 2
----------------
prelevato (inserimento-inserimento-prelievo), o al prelievo e utilizzo dello stesso messaggio più volte (inserimento-prelievo-prelievo). Come esempio del secondo tipo di interazione (competizione), si consideri il cao di due processi P 1 e P 2 che condividono una variabile contatore che devono incrementare ogniqualvolta effettuano una determinata azione. Al completamento dell'esecuzione dei processi, la variabile contatore deve contenere un valore pa1i al numero complessivo delle azioni effettuate dai due processi. In termini di istruzioni assembler, l'istruzione: contatore= contatore+ 1
può essere espressa nel seguente modo: LD contatore AD 1 STO contatore
Ogni processo, cioè, carica il valore corrente della variabile su un proprio registro, lo modifica incrementandolo di 1 e memorizza il nuovo valore così ottenuto in contatore. Se al termine di un'azione i processi eseguono concorrentemente la modifica di contatore, è possibile una sequenza del tipo : to t1 t2 t3 t4 t5
LD contatore LD contatore AD 1 STO contatore AD 1 STO contatore
(P1) (P2) (P2) ( P2) (P1) (P1)
in corrispondenza della quale il valore della variabile c ontatore viene erroneamente incrementato di una sola unità. Il risultato sarebbe corretto se il processo P 1 (P 2) avesse potuto eseguire tutte e tre le istruzioni senza essere interrotto dal processo P 2 (P 1 ). Nel caso di processi interagenti è pertanto fondamentale, per un corretto funzionamento del sistema, imporre dei vincoli, diversi a seconda del tipo di interazione, nell'esecuzione di alcune operazioni (sincronizzazione). Nel caso della cooperazione tra processi i vincoli riguardano l'ordine con cui le operazioni dei processi possono essere compiute (sincronizzazione diretta o esplicit~). Nel caso del!~ competizione occorre garantire che un solo processo alla volta abbi~ accesso _alla nso:~a co~u_ne (sin~r~nizz~zione indiretta o implicita). Come si ve~a ~el C~p1tolo 3, l Impos1z10ne dei vmcoh avviene mediante l'uso di apposite funz10m realizzate dal nucleo (primitive di sincronizzazione e comunicazione).
2.8 Nucleo di un sistema a processi Le strutture dati e le funzioni illustrate nei paragrafi precedenti sono parte integrante del nu~l~o (kerne~ o p~ocess manager) di un sistema operativo il cui scopo è quello, come s1 e detto, d1 realizzare l'astrazione di CPU virtuale.
Gestione dei processi
61
Il cambio di contesto tra due processi 1 . · ll . , a scelta del p esecuzione, 1a nsposta a e mterruzioni . . ~ocesso pronto da mettere in . . . d' . provenienti da d' ... zazione d e 11 e pnmitive i smcronizzaz· d . i ispositivi esterni la realizione ei proc . 1 . ' . . creazione e termmazione rappresentano 1 fu . . essi e e pnmitive per la loro . . d ' 1· e nz1om fond 1 · Nella rea11zzaz1one i ta i funzioni il nu 1 .. amenta 1 svolte dal nucleo · · c eo utthzza struttu d · . · e le code d ~1 pro~essi e, per quanto riguarda li . . r~ .ah co~e 1 descrittori st mafori (vedi Capitolo 3). g rumentt di smcroruzzazione, i sePer quanto riguarda la gestione delle int . . · nucleo e' 1·1 so lo mo du lo d el sistema operativ erruziom h , esterne . , occorre notare che .11 me si vedrà nel Capitolo 5, i processi che colol c e_e consci? ~ella loro esistenza. Cooqmano con 1 d ·t· · ·i· ortune primitive realizzate dal nucleo che d . ispos1 1v1 uh 12zano op' provve ono (mg l) . P in attesa del completamento dell'azione richiest Q d , e?era ~ a sospenderli ·· · a. uan o l azione e co l tata 1·1 relativo segnale d1 mterruzione inviato dal dispositivo all'unità d' ~p e . ' , elaborazione viene catturato dal nucleo che provvede a risvegliare il proc . . . . , . .. .. esso sospeso. La. gest10ne delle mterruz10m e qumd1 mvisibile a·1 processi· e ha come umco . ef. . della loro esecuzione sui rispettivi· proc · · fetto il rallentamento . , esson v1rtua11. Una nella di un si·stema a processi· e, 1a se. propneta fondamentale . . . . strutturazione . . paraz10ne e politiche d1 gestione delle risorse . Il nuc Ieo deve, per , tra ·meccamsm1 quanto e poss1bi1e, contenere solo meccanismi consentendo così a livell d' _ · · ·1· 1· · . . . , o 1 proces s1, d1 ~ti 1zzare ta 1 meccamsm1 per _la. ~e~hzzazione di opportune politiche di gestione. Cio consente una notevole flessibihta potendosi realizzare politiche diverse a seconda del tipo di applicazione. Una proprietà molto importante del nucleo è l'efficienza con cui devono essere eseguite le sue operazioni. E evidente che essa condiziona l'intera struttura a processi. Per questo motivo esistono sistemi in cui alcune o tutte le operazioni del nucleo sono realizzate in hardware o mediante microprogrammi. Laddove realizzato in software, il nucleo deve essere programmato, almeno in parte, in linguaggio assembler in quanto è necessario operare direttamente sui registri dell'unità centrale. Il meccanismo di passaggio tra i due ambienti di nucleo e dei processi è costituito dal meccanismo di interruzione. Più precisamente, nel caso di funzioni chiamate da processi esterni, il passaggio all'ambiente di nucleo è ottenuto tramite il meccanismo di risposta al segnale di interruzione (interruzioni esterne o asincrone); nel caso di funzioni chiamate da processi interni, il passaggio è ottenuto tramite l'esecuzione di apposite istruzioni di tipo chiamata al supervisore, il cui effetto è del tutto ~-alog? all'arrivo di un segnale esterno (interruzioni interne o sincrone). ~ entrambi 1 ca_s1, al completamento della funzione richiesta, il trasferimento all'ambiente utente avviene utilizzando l'istruzione di ritorno da interruzione (~ret). , . . , . . · 0 di· trascenmento tra l ambiente dei pro. 11 N e 1 segmto verra illustrato i1 meccamsm • • • · · · f: d ·&: rirnento a una ipotetica arch1cesSi e l'ambiente del nucleo e viceversa, acen nie , . . . · pporra che a 0ITT11 processo sia t ettura del sistema di elaborazione. In partico 1are si su ~ . . . ·1 (stack) e gestita tramite 11 re. . . · b·1· associata un'area di memona pnvata organizzata a pi a · . . d l processo e contiene 1e vana 1 1 gistro SP. La pila rappresenta l'area di 1avoro e . · · m· PC e d e chiamate. 01tre a1 reg1s t . . emporanee e i record di attivaz10ne delle proce ur d . · · di· reoistri oenerali PS · , . , . · ossegga ue msierru =i =i s1 supporra che l'umta d1 elaborazwne P. . SP SP' ssociati rispettivamente R1,_R2, ... ,RneR'i,R;, ... , R~edueregistn e a agh ambienti dei processi e del nucleo.
°
62 Capitolo 2 Gestione dei processi
descrittore di P
pila del nucleo
pila di P
descrittore di P
63
descrittore di p•
~I
pila del nucleo
: I
o 13
SI'
al I
R,
SP'
a n
CXn'
B
B'
'V
"( I
8
o'
'V'
o'
pila di P'
I I I I
Un
SP'
Rn
processo in esecuzione E
PC
ç
PS
B'
SP
al'
R,
i an'
y valore del PC relativo al processo che ha eseguito la SVC 8 valore del PS relativo al processo che ha eseguito la SVC e indirizzo della procedura di risposta all'interruzione ç parola di stato dell 'ambiente del nucleo Figura 2.9 Situazione dei registri di macchina dopo l'esecuzione della SVC.
L'esecuzione di una primitiva da parte di un processo P corrisponde all_'esecu~i~ne di un'istruzione di tipo SVC (Super Visor Cali) che genera un'interruz10ne d1 tr~o sincrono, con salvataggio dei valori dei registri PC e PS relativi a P in cima alla ptla del nucleo e con caricamento in PC e PS rispettivamente dell'indirizzo della procedura di risposta alle interruzioni e della parola di stato propria dell'ambiente nucleo (Figura 2.9). . La procedura di risposta ali 'interruzione opera ora utilizzando l'insieme dei registri dell'ambiente del nucleo e, sulla base dei parametri passati, provvede a chiamare la relativa funzione richiesta. Nell'ipotesi che la funzione richiesta non risulti bloccante per il processo, il nucleo provvede a rimettere in esecuzione il processo P mediante l'istruzione iret che ripristina nei registri PC e PS i corrispondenti valori ì e 8 contenuti nella sua pila. Se invece l'esecuzione della funzione comporta il blocco del processo, viene eseguita innanzitutto la procedura per il salvataggio dello stato del processo che provvede a inserire nel suo descrittore i valori dei registri di macchina dell'ambiente processi, nonché i valori I e 8.
Rn
processo in esecuzione
n
PC
11 indirizzo dell'istruzione RTI (ritorno da interruzione) ç parola di stato dell'ambiente nucleo Figura 2.10 Situazione dei registri di macchina prima dell'esecuzione della iret.
. . . · ita la procedura per il ripristiAl completamento della funzione _nchteSì~, vi~n~e;~~acchina dell'ambiente procesno dello stato che provvede a cancare nei regis P' e · valori ~1 1 ' ·r si i corrispondenti valori contenuti. ne1descn_·tt0 re del nuovo processo e 8' in cima alla pila dell'ambiente nucleo_ (Figura ~.l0).- processo P' eseguendo l' i. fime a nme . ttere m esecuzione 11 Il nucleo provvede m struzione iret.
2.9 Scheduling
..
. t rmine short term scheduler s1 mtend~ 11 Abbiamo visto precedentemente eh~ con it~ di gestire l'allocazione della CPU a1 quella funzione del nucleo che ha 11 comp
64
Capitolo 2
-----------processi pronti. Già nel capitolo introduttivo (vedi Paragrafi 1.2.3, 1.2.4 e 1.2.5) è tato mes o in evidenza come questa funzione assolva a un compito fondamentale di ogni sistema multiprogrammato e come le strategie in base alle quali lo scheduler alloca la CPU siano determinanti per caratterizzare l'intero sistema operativo dal punto di vista delle diverse tipologie di servizi offerti (sistemi batch, time-sharing, rea/time). Compito di questo paragrafo è quello di passare brevemente in rassegna le principali strategie di schedulazione dei processi. Prima di esaminare tali strategie è però opportuno ricordare che in un sistema operativo esistono altri due livelli di scheduling: scheduling a lungo termine (long term scheduling) e scheduling a medio tem1ine (medium term scheduling). Con scheduling a lungo termine si intende quella funzione del sistema operativo che, in un sistema di tipo batch, sceglie tra tutti i programmi caricati in memoria di massa per essere eseguiti, quelli da trasferire in memoria centrale e da inserire nella coda dei processi pronti. La scelta viene fatta, in generale, in modo da equilibrare la presenza in memoria principale di processi caratterizzati da prevalenza di operazioni di elaborazione (CPU-bound) e di processi caratterizzati da prevalenza di operazioni di ingresso e uscita (!IO bound). È intuibile come uno sbilanciamento del carico verso uno qualunque dei due tipi di processi porterebbe a un uso non efficiente dell'intero sistema. Se fossero prevalenti i processi del secondo tipo (I/O bound) la coda dei processi pronti sarebbe quasi sempre vuota e la CPU non sarebbe utilizzata in modo efficiente. Se fossero prevalenti i processi del primo tipo (CPU-bound) i dispositivi di I/O sarebbero poco utilizzati e il sistema sarebbe nuovamente sbilanciato. Compito dello scheduling a lungo termine è anche quello di controllare il numero dei processi già creati e non ancora terminati (grado di multiprogrammazione). Più processi sono stati creati minore è il tempo a disposizione di ogni processo per l'esecuzione. Perciò lo scheduler a lungo termine può limitare il grado di multiprogrammazione per fornire un servizio soddisfacente all'insieme di processi che deve gestire. Lo scheduling a medio · termine (medium term scheduling) rappresenta invece quella funzione del sistema operativo che ha il compito di trasferire temporaneamente processi dalla memoria centrale alla memoria di massa (swap-out) e viceversa (swap-in). La funzione viene utilizzata per liberare parte della memoria centrale necessaria ad altri processi già presenti o per rendere possibile il caricamento di altri processi così da migliorare, per esempio, la combinazione dei processi presenti (vedi Capitolo 4). Entrambe le funzioni di long tenn scheduling e medium tenn scheduling vengono eseguite dal sistema operativo con una frequenza nettamente inferiore a quella dello short tenn scheduling e quindi possono risultare più costose in termini di tempo senza influire in maniera significativa sulle prestazioni del sistema. La Figura 2.11 riassume le funzioni svolte dai tre livelli di scheduling. Tornando allo short term scheduler, premesso che questo interviene molto frequentemente in quanto legato, come si è visto, al cambio di contesto tra processi e che pertanto deve essere realizzato in modo molto efficiente, nel seguito verranno descritte alcune tra le principali strategie utilizzate per gestire l'allocazione della CPU, rimandando alla bibliografia per una trattazione più completa dell'argomento.
----
Gestione dei processi
65
swap-in swap-out
long term scheduling job-batch
terminazione
interattivi processi sospesi
sospensione
Figura 2.11 Livelli di scheduling.
Una di scheduling è relat·1va all a sce1ta d.1quah· . prima . classificazione .. . fra . gli algoritmi . siano gh eventi m segmto ai quah lo scheduler deve intervenire: •
•
si iJ:dican~ come algoritmi ~~ scheduling senza diritto di revoca (non preemptive) tutti quell_i che pre~edon? 1 mtervento dello scheduler esclusivamente quando il pr?cesso m_ esecuz10ne h?er~ spontaneamente la CPU, o perché termina la propna esecuzione o, come mdicato nel Paragrafo 2.2, perché si sospende in attesa del verificarsi di un dato evento; viceversa, vengono indicati come algoritmi di scheduling con diritto di revoca (preemptive) quelli che prevedono l'intervento dello scheduler anche per decidere di revocare la CPU al processo in esecuzione al fine di allocarla a un altro fra i processi pronti, per esempio a causa dell'arrivo di un'interruzione che indica lo scadere del quanto di tempo assegnato al processo, oppure perché entra in coda pronti un processo ritenuto più urgente o "più importante" di quello in esecuzione. In entrambi i casi il processo in esecuzione viene forzato ad abbandonare l'uso della CPU e inserito in coda pronti (vedi Figura 2.3).
Gli algoritmi appartenenti alla prima classe sono sicur~mente ?iù sem?li~i _e, poiché riducono il numero delle volte che lo scheduler deve mtervemre e qumd~ il numero dei cambi di contesto fra processi, sono anche quelli che richie~ono un mmore ~ver. . . , nche quelli che offrono rrunore head di sistema. Per lo stesso motivo, pero, sono a , . d. · d.1 1 flessibilità intesa come possibilità di definire una piu ampia gamn:ia . . Sìrat~egie 1 . ' . . . . . ptive sono stati utl izza I prevaschedulmg. Per questi motivi gh algontmi non preem d consentono di rao-0 lentemente nell'ambito dei sistemi batch ma, come ve. r~mo, ? n f e ro . . . . . . . . . . . . sharing O di sistemi rea 1- rrn · . . per persona! computer han. gmngere gh obiettivi tipici di sistemi 1im~· · · d · ·' oti s1stem1 opera1ivi An e h e 1e pnme vers10m ei pm n . 1 aso di Windows, solo con la no utilizzato algoritmi senza revoca. Per esemp~o/~ \on revoca. Analogamente, i versione Windows 95 è stato introdotto uno _se _e u er voca soltanto a partire dalla calcolatori Macintosh hanno utilizzato algontmi coCn re . . tt forma PowerP . d' h versione MacOS 8 realizzata su pia a I bontà di un aJaoritmo I se eMolti sono i criteri in base ai quali viene valutata a ro
66 Capitolo 2
dulino. La diversità fra tali criteri deriva dalla diversità dei parametri che vengono presi in considerazione i quali, di volta in volta, vengono scelti fra quelli più rilevanti per la specifica tipologia del sistema operativo. Sono infatti diversi i parametri in base ai quali viene giudicata la bontà di un algoritmo di scheduling per un sistema batch rispetto a quelli relativi a un sistema time-sharing o a un sistema in tempo reale. Per esempio, per sistemi batch, fra i parametti più spesso utilizzati citiamo quelli di: utilizzazione della CPU: l'obiettivo è quello di massimizzare la percentuale di uso della CPU nell'unità di tempo; tempo medio di completamento (turnaround time): inteso come valor medio degli intervalli temporali che intercorrono tra quando i singoli processi entrano per la prima volta in coda pronti e quando gli stessi temùnano le loro esecuzioni. L'obiettivo, in questo caso, è quello di nùnimizzare tale valore, indicativo del tempo che un generico utente deve mediamente attendere per avere i risultati finali una volta che il suo programma sia stato sottomesso al sistema per l'esecuzione; produttivitd (throughput rate): espressa come numero medio di processi completati nell'unità di tempo (coincidente, praticamente, con l'inverso del turnaround time e che, come tale, è da massimizzare).
Nel caso di sistemi time-sharing, un processo ha in genere un comportamento di tipo interattivo. Per esempio, nell'ambito di una sessione di lavoro, un utente invia un comando al sistema e, prima di inviare il successivo, attende la risposta a quel comando da parte del sistema. In questi casi si prendono in esame parametri diversi quali: -
tempo di risposta: inteso come intervallo temporale intercorso tra l'istante in cui il processo entra in coda "pronti" e l'istante in cui fornisce la prima risposta. Questo parametro caratterizza un processo interattivo meglio del turnaround time visto precedentemente. Anche in questo caso si tratta di minimizzare tale parametro; tempo di attesa: inteso come il tempo totale che un processo passa nella coda dei processi pronti in attesa di avere a propria disposizione la CPU. Anche questo parametro deve essere ovviamente minimizzato in quanto a un maggiore tempo trascorso in coda pronti corrisponde un più alto valore del tempo di risposta.
Per quanto riguarda i sistemi real-time, i criteri in base ai quali viene valutata la bontà di un algoritmo di scheduling sono ancora diversi. In questi casi, come già indicato nel P~ra?1"afo l .2.5, ogni processo applicativo è caratterizzato da un parametro temporale,_ m~1cato c_o~e de~dline, eh~ rappresenta il tempo entro il quale il processo deve fo~mre 1 pr?pn nsultat1. In questi casi l'obiettivo è quello di minimizzare il numero dei rrocessi e~~ non ris~e~ano !a propria deadline (sistemi "soft real-time") O di garanttre_ che tutti 1 processi nspettmo la propria deadline (sistemi "hard real-time"). Chiaramente, non s~mpre è possibile rispettare tutti i precedenti criteri contemporane_a~ente._ Per es~mpio, al fine di ottimizzare l'utilizzazione della CPU è opportu~? limitare 1 cambi di contesto fra processi, ognuno dei quali richiede ovviamente 1 mterve?to d~Ua CP~ (over~ead di_ sistema) che va a detrimento del tempo che la CPU puo dedicare all esecuzione dei processi. In questo senso, per garantire la mas-
----------------
Gestione dei processi 67
sirna utilizzazione della CPU dovremm . o optare per str t . d. voca. Ma, come ve dremo, tah strategie non a eg1e l scheduling senza re. · · consento d. · . . risposta o d1 garantire 11i:spetto delle deadline. no 1 mm1m1zzare il tempo di Anche la struttura dei processi può · fl .. . p . . m uenzare note 1 . vo mente le prestazioni dei vari algontmt. er esempio, m linea di m . ' l d. . ass1ma possiamo . come un a temanza 1 mtervalli durante i .. un processo 11 11 processoca_rattenzzare · (CPU d. · · · · qua un · . del sistema e 1spostt1V1 di I/0) 1· · pegna nsorse diverse . · 1p1camente do · uale il processo esegue istruzioni ( detto an h CP ' po un mtervallo durante il q . I · s · h. d menti di. mgresso uscita, segue un intervalloe de U burst) . enza ne 1e ere trasferìurante 11 qual 1·1 . . . attivato un trasfenmento d1 dati, si sospende .1 . e processo, dopo aver . . ,. . n asciando la CPU t·t· d d. . ma u 1 tzzan o 1spositivi d mgresso1uscita (detto anche I/O bu t d. nuovo un CPU burst e così via. La frequenz:~' ve ~ C~p~tolo 5); ~ ~uesto segue di dimensioni dei singoli intervalli sono caratteris~:hcui ta \~t~r.:all_i st alternano e le dipendono dal tipo di programma che viene esegu~tepcu ian d1 ~1asc,un pro~esso ~ . · · ·fi , · er esempio l esecuzione d1 un programma d t tipo scienti tco puo essere caratterizzata d .' . · 1 l ·d · a un pnmo mtervallo durante il qua e vengono etti ah da elaborare seguito da u I · · d · ' n ungo mterva 11 o d1. elaborazione e mfine a un terzo mtervallo relativo alla stampa dei· n·sultat·1. e ome gia .. an· · l · d. . ticipato, , .un ta e. tipo i processo. viene . anche , . indicato come CPU-boun d. y·1ceversa, l esecuz10ne di un programma mteratttvo e m genere caratterizzata da freq t· tt·_ · , d. · ; · d. d · · uen t a 1 vita t id)ngresso uscita i atl, mtervallate da brevi periodi di esecuzione (processo Il 0-boun . Passeremo adesso in rassegna le caratteristiche di alcuni fra i più noti algoritmi di scheduling. 2.9.1 Algoritmo First-Come-First-Served (FCFS)
È sicuramente l'algoritmo di scheduling più semplice. È di tipo senza revoca e prevede di assegnare la CPU al processo che è nella coda dei processi pronti da più tempo. In pratica consiste nell'organizzare la coda secondo la modalità First-InFirst-Out. Come tutti gli algoritmi non preemptive può essere adatto solo per sistemi batch. A fronte, però, della sua semplicità offre prestazioni generalmente molto limitate. Ciò è dovuto al fatto che la strategia con cui questo algoritmo opera ignora i tempi di servizio richiesti dai singoli processi e tutti gli altri aspetti che influenzano parametri quali il tumaround time o il tempo di attesa. Per chiarire con un esempio, supponiamo che al tempo zero sia pronto il solo processo_ P0 che ri~hiede 10 millise~ condi di tempo di CPU e che, mentre questo è in esecuzione, entnno nella coda dei processi pronti tre processi negli istanti indicati n~lla second~ c~lonna della Tabella 2.1 e che gli stessi richiedano un tempo di esecuz10ne come md1c~to_nel_l~ te~a _colonna della tabella dove, per esempio, tutti i tempi si suppongono mdicatl m m1lhsecondi: Processo
Po
Istante di arrivo
o 2 4
Tabella 2.1
Durata del CPU burst 10 100 24 16
6 . d' . t mpi di arrivo e diverse durate. Un esempio con 4 processi con iversi e
Capitolo 2
68
---------------------~G~e~st~io~n~e_.:d~e~ip~r~oc~e~ss~i~69
1. 1.
100
(
24
Po
::lH =\ ___ __ I .
P3
•
I
1•
I
i
····1········ \··········+················· O 2 4 6
)
I (
.7,. ., :,,..______--;-;;-;;------~- :.· !"I 00
:ttt!=~~:::i- ----1 Po
I. ,!
,
16
O 2 4 6
.
1
24
:in
IO
't
.
J.. I.. . . . . .
't
P 2 ...........\.... , ...... . 150
= a tn + (1 - a)s
+ (1
- a)a
fn - 1
+ ... + (1
- a/ a
tn-i
+ ... + (1
- aY7+ 1So
2.9.3 Shortest-Remaining-Time-First (SRTF} Questo algoritmo rappresenta la versione con revoca del precedente algoritmo SJF. La revocabilità della CPU implica la seguente variazione rispetto all'algoritmo SJF: se durante l'esecuzione di un processo P entra nella coda dei processi pronti un nuovo processo Q che richiede un tempo di esecuzione inferiore al tempo di cui P ha ancora bisogno per terminare il suo intervallo di esecuzione, allora P viene revocato e riportato in coda pronti e la CPU viene immediatamente allocata al processo Q. Per chiarire la differenza tra gli algoritmi SJF e SRTF esaminiamo i diagrammi relativi alle due schedulazioni dei processi caratterizzati dai parametri temporali indicati in Tabella 2.2.
Tabella 2.2
Istante di arrivo
l' l',E 16
50
"i.L 7
:: fl:: O
Se il fattore a fosse uguale a zero si avrebbe s 11 + 1 = s 0 cioè tutte le stime sarebbero uguali alla stima iniziale. Se, al contrario, il fattore a fosse uguale a uno si avrebbe s 11 + 1 = t11 cioè la stima coinciderebbe col valore dell'ultimo intervallo. In genere si assume un valore di a pari a 1/2. Passiamo adesso a esaminare alcuni fra i più noti algoritmi di tipo con revoca.
Processo
4 6
+-
66
90
4 6
'
+,-! _
22
22
" 7 l
:"'~-4-6-..:,,>1
----.l·
......._......._., .. . , : -
44
90
11
Espandendo questa relazione si può notare come i valori dei singoli intervalli abbiano un peso tanto minore quanto più sono vecchi: tn
O
:,- -t.
Figura 2.15 Schedulazione SJF.
noscenza dei tempi di esecuzione dei processi, dati questi che non sono noti a priori e per i quali si può ricorrere a una stima. Per esempio, il CPU burst di un processo viene stimato come media esponenziale dei valori misurati nei precedenti intervalli di esecuzione e cioè in modo tale che il valore di un precedente intervallo pesi nella stima tanto meno quanto più è vecchio. Una regola che rispetta questo criterio è la seguente: indicando con tn la durata dell'intervallo nesimo, con sn la sua stima e con a un fattore compreso tra zero e uno:
=Q
·······:,
...........
i
50
S 11 + 1
Po
P 1 ........ . .
Figura 2.14 Esempio di schedulazione SJF.
Sn+I
Gestione dei processi 71
Durata del CPU burst
o
50
4 6
24 16
Un esempio con 3 processi con diversi tempi di arrivo e diverse durate.
Figura 2.16 Schedulazione SRTF.
Il diagramma temporale relativo alla schedulazione dei tre processi con algoritmo SJF è riportato in Figura 2.15. In Figura 2.16 è riportato il diagramma temporale degli stessi processi, ma secondo l'algoritmo SRTF. La revocabilità dei processi consente all'algoritmo SRTF di rispondere in maniera più efficace alle variate condizioni di carico e quindi consente di o~enere ~glio~ valori sia del turnaround time medio che del tempo medio di attesa nspetto a1 comspondenti valori ottenuti mediante l'algoritmo SJF. Come esempio, dalle due Figure 2.15 e 2.16 è facile ricavare il tumaround time medio nei due casi (48.6 con SRT~ rispetto a 65.3 con SJF) e analogamente, il tempo medio di attesa (18.6 con SRTF nspetto a 35.3 con SJF). · Tali valori sono però del tutto teorici in quanto non tengono cont~ del °:a~giore .. . t ndo il numero dei cambi d1 conoverhead che la revoca dei processi unp 11ca aumen a testo fra processi.
2.9.4 Round-Robin (RR)
. . , ·to a ositamente per i sisterru a partiL'algoritmo Round Robin(RR) e stato conce~! PP , condamentalmente costituì. . . d' · t · ogni processo e 1 z10ne d1 tempo. In questo tipo 1 s1s erru . d . uali seguito da un intervallo to da una sequenza di intervalli di attesa cias~uno ei q e' sospeso in attesa che l'u11 d' ttesa il processo . . . d 1. esecuzione. Durante un mterva O 1 a. tr nel successivo intervallo d1 st tente digiti un comando da inviare al si ema, _men de te al comando digitato. Co. ·1 mna comspon en . . . . d'1 sistemi l'obiettivo pnontano esecuzione il processo esegue 1 pro~a · · · , anticipato . . t n questo tipo m e g1a 1 precedentemen e, . d . essi O di massun1zzare l' effi n on e, tanto quello di ridurre 1·1 tumaroun d tune et proc 1
72
Capitolo 2
----------------
cienza di uso della CPU quanto quello di ridurre il tempo di attesa e quindi il tempo di risposta ai singoli comandi. Anzi, tanto minore è il tempo di esecuzione richiesto per rispondere a un comando, tanto minore dovrebbe essere il corrispondente tempo di risposta. Infatti, ogni utente si aspetta una risposta da parte del sistema tanto più veloce quanto più semplice è il comando digitato. Questo algoritmo rientra in uno schema di scheduling con diritto di revoca. La coda dei processi pronti, gestita con modalità FIFO, è realizzata come una coda circolare: ogni processo ottiene la CPU per un quanto di tempo la cui durata è dell'ordine di qualche decina di millisecondi (tipicamente da 1O a 100 millisecondi). Se l'intervallo di esecuzione richiesto dal processo è infe1iore al quanto di tempo assegnato, al termine del proprio intervallo di esecuzione il processo si sospende in attesa del prossimo comando (o completa l'intera esecuzione) e la CPU viene allocata al prossimo processo in coda. Viceversa, se durante il quanto assegnato il processo non riesce a completare il proprio intervallo di esecuzione, al termine del quanto il processo viene interrotto (mediante una interruzione da parte del timer), gli viene revocato il controllo della CPU, il suo descrittore viene reinserito in fondo alla coda dei processi pronti e la CPU viene allocata al prossimo processo in coda. L'algoritmo RR è particolarmente adatto per i sistemi interattivi in quanto, come vedremo, è in grado di assicurare tempi di risposta abbastanza brevi agli utenti, determinati esclusivamente dal valore del quanto di tempo e dal numero medio di processi pronti. Viceversa, non è adatto per sistemi batch anche perché, al termine di ~gni_ quanto di tempo abbiamo una conunutazione di contesto che, nel caso di algontm1 senza revoca non sarebbe necessaria e ciò limita il fattore di utilizzazione della CPU. In genere, per non aumentare eccessivamente l'overhead del sistema è opportuno che il tempo C, necessario per effettuare una commutazione di contesto, sia molto inferiore al quanto di tempo Q con cui la CPU viene allocata (C la sua traduIn . d ZO X - 11 cm se~mento s g abbia un descrittore nella tabella dei segmenti con bit P = O genera via hardware un'interruzione di segment-fault. Come è già stato indicato, un'interruzione di segment-fault vi~ne ge~tita i~ modo tale da caricare in memoria il segmento richiesto. Per questo motivo, viene ricercata una partizione disponibile, se esiste, altrimenti viene compattata la memoria se questa è frammentata. Ma se, anche compattando non c'è sufficiente memoria disponibile è necessario scaricare uno o più segmenti, appartenenti sia al processo in esecuzio~e sia ad altri processi, eventualmente sospesi, in modo tale da liberare una partizione sufficiente a contenere il nuovo segmento. La scelta dei segmenti da rimpiazzare costituisce uno dei parametri fondamentali agli effetti dell'efficienza complessiva del sistema. Infatti, una scelta sbagliata che rimpiazzasse un segmento ancora necessario al processo genererebbe una nuova interruzione di segment-fault creando un eccessivo overhead. Al fine di facilitare l'implementazione di algoritmi di rimpiazzamento efficienti, sono spesso disponibili ulteriori bit di controllo nel descrittore di un segmento. Per esempio i bit U e M indicati in Figura 4.22, e noti come bit di uso e di modifica. Questi bit possono essere letti e azzerati via software e vengono automaticamente posti al valore uno via hardware ogni volta che viene fatto un riferimento al segmento (bit U) e ogni volta che viene modificato il contenuto del segmento (bit M). L'importanza del bit di modifica deriva dal fatto che se viene scelto come segmento da rimpiazzare un segmento il cui bit M sia a zero (ammesso che tale bit fosse stato azzerato all'atto del caricamento del segmento stesso) ciò significa che tale segmento non è stato base
limite
indirizzo della dimensione della partizione partizione
Figura 4.22 Bit di presenza, di modifica e di uso.
controllo R W U M P
d"ficato dopo essere stato allocato in memoria e · d. ~o t può essere liberata senza la necessità di riscriv;um 111 1a partizione _che lo conuene . re su a swap-area 11 contenuto con un conseguente nspannio di temp Il b. . . deI segmento stesso, ·fi , 1t. U viene ·i·zzato per veri 1care se un segmento e stato usato dal o. . . invece . t u 11 , c ·, . momento m cui 11 relativo ·t di uso e stato azzerato. 10 consente di valutare la fr d. . . b1 . . d. . equenza 1 uso di ogrn seg. . to e qumd1 1 1mp1ementare algontrm di scelta del segme t d . . me n d · ·fì . . . . no a nmp1azzare sule1 n enrnenti a1 van segmenti presenti· · . U d Ia base della frequenza e d. d. 1- l . . m memona. na e.zione appro1on 1ta 1ta 1 a gontrm esula dagli scopi di quest t t p n se . · s1· nman · d a ali a b"b . o es o. er eventuali approfondimenti I hografia.
433 Memoria paginata L'allocazione della memoria fisica mediante partizioni, che è alla base di tutte le tee1.che viste precedentemente, soffre dell'inconveniente della frammentazione. Tale ? conveniente può essere limitato nei sistemi segmentati compattando le partizioni ~bere. Ma il compattamento richiede comunque un tempo di CPU non indifferente. Per eliminare alla radice il problema della frammentazione sarebbe necessario poter allocare in memoria, in locazioni fisiche non necessariamente contigue, infonnazioni i cui indirizzi virtuali sono contigui. Utilizzando ~ma funzione di rilocazione dinamica y = f (x) ciò è concettualmente possibile. E sufficiente implementare nella MMU una funzione che a ogni indirizzo virtuale faccia corrispondere una locazione fisica qualsiasi, senza vincoli di contiguità. Come si può facilmente intuire, però, tale funzione dovrebbe costituire una tabella di corrispondenza di dimensioni esattamente uguali a quelle dello spa~io virtuale e ciò vanificherebbe il tentativo di raggiungere il risultato desiderato. E possibile però raggiunge_re un compro~esso s~ I~ locazioni dello spazio virtuale, invece che essere allocate smgolannente m locaz_10~ fisiche indipendenti, vengono allocate a gruppi di locazioni virtuali _contigue di d1~ mensioni fisse, per esempio di dimensioni d, allocando ogni ~PP? m un gru_ppo d1 locazioni fisiche contigue anch'esso di dimensioni d, ma senza 11 vincolo che 1gruppi fra loro contigui in memoria virtuale debbano esser~ fra lo~o co?tigu! anch_e in memoria fisica. Per esempio, in Figura 4.23 è illustrato 11 caso m cm la ~1m~n 5ione d del gruppo di locazioni contigue (detto anche pagina) è 1024._L'.esem~io_nportato . figura rappresenta uno spaz10 . v1rtua . 1e d.1409 6 Iocaz ioni (costituito qumd1 da 4. pam . ) 1 d gine) mentre la memoria fisica contiene 7168 locazioni (corrispoo en~,ad?ttpagm~ · . (ognuna delle qua11e e a anc e Ne11 'esempio, la prima pagina dello spazio v a1e . fi · (detta anche . , . li . a della memona lSICa pagzna virtuale) e stata caricata ne a terza pagm d · a virtuale è cari. · , rvare la secon a pagm pagzna fisica o frame). Ma, come s1 puo osse .' ·n cui è stata caricata 11 1 . una pagma . . cat a m fisica, la sesta, che non è contigua a que a la precedente pagina virtuale. . . d. . . è quindi sufficiente una taPer realizzare la funzione di traduzione deg!t m ~nzzi . e le pagine fisiche che le beli a che reg1stn . . le comspon . d tr le pagine v1rtua1I • enze a . ("I rimo della seconda pagina 24 1 P co. ntengono. Per esempio, · a11'.md.ir~zzo · virtuale 10 · ) A . . della sesta pagina fisica : naVlftuale) corrisponde l'indirizzo fisico 5 l 20 (11 pnmo t alla stessa pagina virtuale lo . .. ;..t,,ale appartenen e . fi gamente, al successivo mdmzzo vu_l~ . artenente alla stessa pagma (1025) corrisponderà il successivo indmzzo fisic~ appl e' necessario sapere a quale s· ( . d. ·zzo vntua ex d. . Lea 5121 ). In pratica per tradurre un m m , d. ·dendo x per la unenSio· ' · , st· 0 ottenere ivi pagma virtuale questo appartiene e c10 pu utu·
158 Capìtolo 4
----------------
indirizzi virtuali
memoria virtuale
-
o .
memoria fisica
1023
2047 - - - - . ~ - - - - ~ 2048!
----r---1----''-----
3071; ~-----C>