|
|
| << | < | > | >> |IndicePresentazione dell'edizione italiana xxi Prefazione xxiii Parte I - Panoramica 1 Capitolo 1 - Introduzione 3 1.1 Che cosa fanno i sistemi operativi? 3 1.1.1 Il punto di vista dell'utente 4 1.1.2 Il punto di vista del computer 5 1.1.3 Definizione di sistema operativo 6 1.1.4 Scopi di un sistema operativo 6 1.2 Sistemi mainframe 7 1.2.1 Sistemi a lotti 7 1.2.2 Sistemi multiprogrammati 8 1.2.3 Sistemi time-sharing 10 1.3 Sistemi desktop 11 1.4 Sistemi multiprocessore 12 1.5 Sistemi distribuiti 14 1.5.1 Reti di computer 14 1.5.2 Sistemi client-server 15 1.5.3 Sistemi punto-a-punto 16 1.5.4 Sistemi operativi distribuiti 16 1.6 Sistemi cluster 17 1.7 Sistemi in tempo reale 18 1.8 Sistemi palmari 19 1.9 Migrazione delle caratteristiche 20 1.10 Ambienti di elaborazione 21 1.10.1 Elaborazione tradizionale 21 1.10.2 Elaborazione basata sul Web 22 1.10.3 Elaborazione embedded 22 1.10.4 Elaborazione multimediale 23 1.11 Riassunto 23 Esercizi 24 Note bibliografiche 25 Capitolo 2 - Architettura del computer 27 2.1 Funzionamento del computer 27 2.2 Struttura dell'input/output 29 2.2.1 Interruzioni di input/output 30 2.2.2 Trasferimenti in DMA 32 2.3 Struttura della memoria 33 2.3.1 Memoria centrale 34 2.3.2 Dischi magnetici 35 2.3.3 Nastri magnetici 37 2.4 Gerarchia di memorizzazione 37 2.4.1 Caching 39 2.4.2 Coerenza/consistenza 40 2.5 Protezione hardware 41 2.5.1 Funzionamento in modalità differenziate 41 2.5.2 Protezione dell' I/O 43 2.5.3 Protezione della memoria 44 2.5.4 Protezione della CPU 45 2.6 Struttura di rete 47 2.6.1 Reti locali 47 2.6.2 Reti geografiche 48 2.7 Riassunto 50 Esercizi 51 Note bibliografiche 52 Capitolo 3 - Struttura dei sistemi operativi 53 3.1 Componenti del sistema operativo 53 3.1.1 La gestione dei processi 54 3.1.2 La gestione della memoria centrale 55 3.1.3 La gestione dei file 55 3.1.4 La gestione dell'input/output 56 3.1.5 La gestione delle unità di memorizzazione secondarie 56 3.1.6 Le reti informatiche 57 3.1.7 Il sistema di protezione 58 3.1.8 L'interprete dei comandi 58 3.2 Servizi del sistema operativo 59 3.3 Chiamate di sistema 60 3.3.1 Il controllo del processo 63 3.3.2 La gestione dei file 66 3.3.3 La gestione dei dispositivi 67 3.3.4 La gestione delle informazioni di sistema 67 3.3.5 Le comunicazioni 67 3.4 Programmi di sistema 68 3.5 Struttura del sistema 71 3.5.1 Una struttura semplice 71 3.5.2 La struttura stratificata 73 3.5.3 I microkernel 74 3.5.4 La struttura modulare 76 3.6 Macchine virtuali 77 3.6.1 Implementazione 78 3.6.2 Vantaggi 79 3.6.3 Esempi 80 3.7 Java 80 3.7.1 Il linguaggio di programmazione 81 3.7.2 L'interfaccia per i programmi applicativi 81 3.7.3 Java Virtual Machine 81 3.7.4 L'ambiente di sviluppo per Java 83 3.7.5 Sistemi operativi in linguaggio Java 83 3.8 Progettazione e implementazione di un sistema operativo 84 3.8.1 Obiettivi del progetto 84 3.8.2 Meccanismi e politiche 85 3.8.3 Implementazione 86 3.9 Generazione del sistema operativo 87 3.10 Avvio del sistema operativo 88 3.11 Riassunto 89 Esercizi 90 Note bibliografiche 91 Parte II - Gestione dei processi 93 Capitolo 4 - I processi 95 4.1 Il concetto di processo 95 4.1.1 I processi 96 4.1.2 Lo stato dei processi 96 4.1.3 Il blocco di controllo del processo 97 4.1.4 I thread 99 4.2 Schedulazione dei processi 99 4.2.1 Le code di schedulazione 99 4.2.2 Gli schedulatori 101 4.2.3 Il cambio di contesto 102 4.3 Operazioni sui processi 103 4.3.1 Creazione dei processi 103 4.3.2 Terminazione dei processi 106 4.4 Processi cooperanti 107 4.5 Comunicazione tra processi 109 4.5.1 Lo scambio di messaggi 110 4.5.2 La denominazione dei processi 110 4.5.3 La sincronizzazione 112 4.5.4 La bufferizzazione 113 4.5.5 Esempio di produttore-consumatore 113 4.5.6 Un esempio: Mach 115 4.5.7 Un esempio: Windows XP 116 4.6 La comunicazione in sistemi client-server 117 4.6.1 I socket 117 4.6.2 La chiamata di procedura remota 120 4.6.3 La chiamata di metodo remoto 123 4.7 Riassunto 128 Esercizi 129 Note bibliografiche 130 Capitolo 5 - I thread 131 5.1 Generalità 131 5.1.1 Motivazioni 131 5.1.2 Benefici 133 5.1.3 Thread nello spazio utente e nello spazio kernel 133 5.1.4 Le librerie di thread 133 5.2 Modelli multithread 134 5.2.1 Il modello molti-a-uno 134 5.2.2 Il modello uno-a-uno 135 5.2.3 Il modello molti-a-molti 135 5.3 Problematiche relative ai thread 136 5.3.1 Le chiamate di sistema fork() ed exec() 136 5.3.2 Cancellazione 137 5.3.3 La gestione dei segnali 137 5.3.4 Gruppi di thread 139 5.3.5 Dati specifici dei thread 139 5.3.6 Attivazione dello schedulatore 140 5.4 Pthread 141 5.5 I thread di Windows XP 143 5.6 I thread di Linux 144 5.7 I thread di Java 144 5.7.1 Creazione di un thread 145 5.7.2 Gli stati di un thread 147 5.7.3 Ricongiunzione di thread 147 5.7.4 Cancellazione dei thread 148 5.7.5 Dati specifici del thread 149 5.7.6 La JVM e il sistema operativo ospite 149 5.7.7 Esempio di soluzione multithread 151 5.8 Riassunto 151 Esercizi 153 Note bibliografiche 154 Capitolo 6 - Schedulazione della CPU 155 6.1 Concetti di base 155 6.1.1 Il ciclo di picco di CPU e di I/0 156 6.1.2 Lo schedulatore della CPU 157 6.1.3 Schedulazione con sospensione dell'esecuzione dei processi 157 6.1.4 Caricamento del processo sulla CPU 159 6.2 Criteri di schedulazione 159 6.3 Gli algoritmi di schedulazione 160 6.3.1 Schedulazione First-Come, First-Served 160 6.3.2 Schedulazione Shortest-Job-First 161 6.3.3 Schedulazione a priorità 164 6.3.4 Schedulazione Round-Robin 166 6.3.5 Schedulazione con coda a più livelli 168 6.3.6 Schedulazione con coda a più livelli con retroazione 170 6.4 Schedulazione per sistemi multiprocessore 171 6.5 Schedulazione per sistemi in tempo reale 172 6.6 Schedulazione dei thread 175 6.6.1 Visibilità della competizione 175 6.6.2 Schedulazione di Pthread 176 6.7 Esempi di sistemi operativi 177 6.7.1 Esempio: la schedulazione in Solaris 177 6.7.2 Esempio: la schedulazione in Windows XP 180 6.7.3 Esempio: la schedulazione in Linux 182 6.8 Schedulazione dei thread in Java 183 6.8.1 Priorità dei thread 184 6.9 Valutazione degli algoritmi di schedulazione 185 6.9.1 Modellazione deterministica 185 6.9.2 Modelli a reti di code 187 6.9.3 Simulazioni 188 6.9.4 Implementazione 189 6.10 Riassunto 190 Esercizi 191 Note bibliografiche 193 Capitolo 7 - Sincronizzazione dei processi 195 7.1 Il problema della sincronizzazione 195 7.2 Il problema della sezione critica 197 7.3 Soluzioni per due processi 198 7.3.1 Algoritmo 1 199 7.3.2 Algoritmo 2 200 7.3.3 Algoritmo 3 201 7.4 Hardware per la sincronizzazione 202 7.5 Semafori 205 7.5.1 Impiego 205 7.5.2 Implementazione 206 7.5.3 Stalli e starvation 208 7.6 Problemi classici di sincronizzazione 209 7.6.1 Il problema del buffer limitato 209 7.6.2 Il problema dei lettori-scrittori 212 7.6.3 Il problema del pranzo dei filosofi 215 7.7 Monitor 217 7.8 La sincronizzazione in Java 221 7.8.1 Buffer limitato 221 7.8.2 Notifiche multiple 226 7.8.3 Il problema dei lettori-scrittori 228 7.8.4 Sincronizzazione del blocco 230 7.8.5 Semafori Java 231 7.8.6 Regole di sincronizzazione 231 7.8.7 I monitor in Java 232 7.8.8 Gestione della InterruptedException 232 7.9 Esempi di sincronizzazione 234 7.9.1 La sincronizzazione in Solaris 234 7.9.2 La sincronizzazione in Windows XP 235 7.9.3 La sincronizzazione in Linux 236 7.9.4 La sincronizzazione in Pthread 236 7.10 Transazioni atomiche 237 7.10.1 Modello del sistema 237 7.10.2 Recupero basato sui log 238 7.10.3 Punti di verifica 239 7.10.4 Transazioni atomiche concorrenti 240 7.11 Riassunto 245 Esercizi 246 Note bibliografiche 250 Capitolo 8 - Lo stallo (deadlock) 253 8.1 Il modello delle risorse di sistema e dei processi 253 8.2 Caratterizzazione del deadlock 255 8.2.1 Condizioni per il verificarsi del deadlock 255 8.2.2 Grafo di allocazione delle risorse 255 8.3 Metodi di gestione dei deadlock 259 8.4 Prevenire il deadlock 263 8.4.1 Mutua esclusione 263 8.4.2 Possesso ed attesa 263 8.4.3 Nessun rilascio anticipato 264 8.4.4 Attesa circolare 265 8.5 Evitare il deadlock 266 8.5.1 Lo stato sicuro 267 8.5.2 Algoritmo del grafo di allocazione delle risorse 268 8.5.3 L'algoritmo del banchiere 269 8.6 Rilevazione del deadlock 272 8.6.1 Singola istanza di ogni tipo di risorsa 273 8.6.2 Istanze multiple di un tipo di risorsa 273 8.6.3 Uso dell'algoritmo di rilevazione 275 8.7 Ripristino dal deadlock 276 8.7.1 Termine del processo 276 8.7.2 Rilascio anticipato delle risorse 277 8.8 Riassunto 277 Esercizi 278 Note bibliografiche 282 Parte III - Gestione della memoria 283 Capitolo 9 - Gestione della memoria centrale 285 9.1 Concetti generali 285 9.1.1 Collegamento degli indirizzi 286 9.1.2 Spazio di indirizzamento logico e spazio di indirizzamento fisico 287 9.1.3 Caricamento dinamico 289 9.1.4 Collegamento dinamico e librerie condivise 289 9.1.5 Overlay 290 9.2 Swapping 292 9.3 Allocazione contigua di memoria 294 9.3.1 Protezione della memoria centrale 295 9.3.2 Allocazione della memoria centrale 296 9.3.3 Frammentazione 297 9.4 Paginazione 298 9.4.1 Metodo base 299 9.4.2 Supporto hardware 303 9.4.3 Protezione 306 9.4.4 Struttura della tabella delle pagine 307 9.4.5 Pagine condivise 312 9.5 Segmentazione 314 9.5.1 Metodo base 314 9.5.2 Hardware 315 9.5.3 Protezione e condivisione 316 9.5.4 Frammentazione 319 9.6 Segmentazione con paginazione 320 9.7 Riassunto 322 Esercizi 324 Note bibliografiche 326 Capitolo 10 - La memoria virtuale 327 10.1 Ambiente 327 10.2 Richiesta di paginazione 331 10.2.1 Concetti fondamentali 332 10.2.2 Prestazioni della richiesta di paginazione 335 10.3 Copia durante la scrittura 338 10.4 Sostituzione della pagina 339 10.4.1 Sostituzione di base della pagina 340 10.4.2 Sostituzione FIFO della pagina 343 10.4.3 Sostituzione ottimale della pagina 345 10.4.4 Sostituzione LRU della pagina 345 10.4.5 Sostituzione della pagina con approssimazione dell'algoritmo LRU 348 10.4.6 Sostituzione della pagina basata sul conteggio 350 10.4.7 Algoritmi per l'uso del buffer delle pagine 350 10.4.8 Le applicazioni e la sostituzione della pagina 351 10.5 Allocazione dei frame 352 10.5.1 Numero minimo di frame 352 10.5.2 Algoritmi di allocazione 353 10.5.3 Confronto tra le allocazioni con sostituzioni locale e globale 354 10.6 Thrashing 355 10.6.1 Cause del thrashing 355 10.6.2 Il modello working set 358 10.6.3 Frequenza delle mancanze di pagina 359 10.7 File mappati in memoria 360 10.7.1 File mappati in memoria in Java 361 10.8 Altre considerazioni 363 10.8.1 Prepaginazione 363 10.8.2 La dimensione della pagina 364 10.8.3 Estensione della TLB 365 10.8.4 Tabella delle pagine invertita 366 10.8.5 Struttura del programma 366 10.8.6 Blocco dei dispositivi di I/O 368 10.8.7 Elaborazione in tempo reale 369 10.9 Esempi di sistemi operativi 370 10.9.1 Windows XP 370 10.9.2 Solaris 371 10.10 Riassunto 372 Esercizi 373 Note bibliografiche 377 Capitolo 11 - L'interfaccia del file system 379 11.1 Il concetto di file 379 11.1.1 Attributi del file 380 11.1.2 Operazioni sui file 381 11.1.3 Tipi di file 385 11.1.4 Struttura del file 387 11.1.5 Struttura interna dei file 388 11.2 Metodi di accesso 389 11.2.1 Accesso sequenziale 389 11.2.2 Accesso diretto 389 11.2.3 Altri metodi di accesso 391 11.3 Struttura della directory 392 11.3.1 Directory a singolo livello 393 11.3.2 Directory a due livelli 394 11.3.3 Directory strutturata ad albero 396 11.3.4 Directory a grafo aciclico 398 11.3.5 Directory a grafo generale 400 11.4 Montaggio del file system 402 11.5 Condivisione dei file 403 11.5.1 Il caso di più utenti 404 11.5.2 File system remoti 405 11.5.3 Semantica della coerenza 408 11.5.4 Semantica UNIX 408 11.5.5 Semantica della sessione 409 11.5.6 Semantica dei file condivisi immutabili 409 11.6 Protezione 409 11.6.1 Tipi di accesso 410 11.6.2 Controllo dell'accesso 410 11.6.3 Altri metodi di protezione 412 11.6.4 Un esempio: UNIX 413 11.7 Riassunto 413 Esercizi 414 Note bibliografiche 416 Capitolo 12 - Implementazione del file system 417 12.1 Struttura del file system 417 12.2 Realizzazione del file system 419 12.2.1 Panoramica sulla realizzazione del file system 419 12.2.2 Partizioni e montaggio 422 12.2.3 File system virtuali 423 12.3 Realizzazione della directory 425 12.3.1 Lista 425 12.3.2 Tabella di hash 426 12.4 Metodi di allocazione 426 12.4.1 Allocazione contigua 426 12.4.2 Allocazione collegata 429 12.4.3 Allocazione indicizzata 431 12.4.4 Prestazioni 434 12.5 Gestione dello spazio libero 435 12.5.1 Vettore di bit 435 12.5.2 Lista collegata 436 12.5.3 Raggruppamento 437 12.5.4 Conteggio 437 12.6 Efficienza e prestazioni 437 12.6.1 Efficienza 437 12.6.2 Prestazioni 439 12.7 Recupero del file system 442 12.7.1 Controllo della coerenza 442 12.7.2 Backup e ripristino 443 12.8 File system basato sulla registrazione delle attività 443 12.9 NFS 445 12.9.1 Descrizione 445 12.9.2 Il protocollo di montaggio 447 12.9.3 Il protocollo NFS 448 12.9.4 Traduzione del nome del percorso 450 12.9.5 Operazioni remote 450 12.10 Riassunto 451 Esercizi 452 Note bibliografiche 454 Parte IV - Sistemi di ingresso/uscita 455 Capitolo 13 - Sottosistemi di ingresso/uscita 457 13.1 Panoramica 457 13.2 L'hardware di I/O 458 13.2.1 Attesa attiva 461 13.2.2 L'interrupt 462 13.2.3 Accesso diretto alla memoria 466 13.3 Le interfacce di I/O per le applicazioni 468 13.3.1 Dispositivi con trasferimento dei dati a caratteri e a blocchi 470 13.3.2 Le periferiche di rete 471 13.3.3 Orologi e temporizzatori 472 13.3.4 I/O bloccante e non bloccante 473 13.4 Il sottosistema di I/O del kernel 474 13.4.1 Schedulazione dell' I/O 474 13.4.2 Buffering 474 13.4.3 Caching 476 13.4.4 Spooling e prenotazione dei dispositivi 476 13.4.5 Gestione degli errori 477 13.4.6 Strutture dati del kernel 478 13.5 Trasformazione dell'I/O in operazioni hardware 479 13.6 STREAMS 482 13.7 Le prestazioni 484 13.8 Riassunto 487 Esercizi 488 Note bibliografiche 489 Capitolo 14 - Struttura delle memorie di massa 491 14.1 Struttura dei dischi 491 14.2 Schedulazione degli accessi al disco 492 14.2.1 Schedulazione FCFS 493 14.2.2 Schedulazione SSTF 494 14.2.3 Schedulazione SCAN 495 14.2.4 Schedulazione C-SCAN 495 14.2.5 Schedulazione LOOK 496 14.2.6 Selezione dell'algoritmo di schedulazione del disco 497 14.3 Amministrazione del disco 498 14.3.1 Configurazione del disco 498 14.3.2 Il blocco di avvio 499 14.3.3 Blocchi difettosi 500 14.4 Gestione dello spazio di swap 501 14.4.1 Uso dello spazio di swap 501 14.4.2 Locazione dello spazio di swap 502 14.4.3 Gestione dello spazio di swap: un esempio 502 14.5 La struttura RAID 504 14.5.1 Miglioramento dell'affidabilità mediante la ridondanza 504 14.5.2 Il miglioramento delle prestazioni con il parallelismo 505 14.5.3 Livelli di RAID 506 14.5.4 Scelta di un livello RAID 510 14.5.5 Le estensioni 510 14.6 Collegamento dei dischi 510 14.6.1 Memorizzazione con collegamento all'host 511 14.6.2 Memorizzazione con collegamento di rete 511 14.6.3 Rete della zona di memorizzazione 512 14.7 Implementazione dell'archiviazione stabile 513 14.8 Struttura di memorizzazione terziaria 514 14.8.1 Periferiche di archiviazione terziaria 514 14.8.2 Compiti del sistema operativo 517 14.8.3 Problematiche relative alle prestazioni 519 14.9 Riassunto 524 Esercizi 525 Note bibliografiche 531 Parte V - Sistemi distribuiti 533 Capitolo 15 - Strutture dei sistemi distribuiti 535 15.1 Concetti di base 535 15.1.1 Vantaggi dei sistemi distribuiti 536 15.1.2 Tipi di sistemi operativi distribuiti 537 15.1.3 Sintesi delle nozioni 541 15.2 Topologia 542 15.3 Comunicazione 543 15.3.1 Attribuzione e risoluzione dei nomi 544 15.3.2 Strategie di instradamento 546 15.3.3 Strategie di pacchetto 548 15.3.4 Strategie di connessione 548 15.3.5 Gestione dei conflitti 549 15.4 Protocolli di comunicazione 550 15.5 Robustezza 554 15.5.1 Individuazione dei guasti 554 15.5.2 Riconfigurazione del sistema 555 15.5.3 Recupero da un guasto 555 15.6 Problemi progettuali 555 15.7 Un esempio: il networking 558 15.8 Riassunto 560 Esercizi 560 Note bibliografiche 562 Capitolo 16 - File system distribuiti 563 16.1 L'ambiente distribuito 563 16.2 Attribuzione dei nomi e trasparenza 564 16.2.1 Le strutture di attribuzione dei nomi 565 16.2.2 Gli schemi di attribuzione dei nomi 567 16.2.3 Tecniche di implementazione 567 16.3 Accesso remoto ai file 568 16.3.1 Schema di base per l'uso della cache 569 16.3.2 Locazione della cache 569 16.3.3 Politica di aggiornamento della cache 570 16.3.4 Coerenza 571 16.3.5 Confronto tra i servizi con cache e quelli remoti 572 16.4 File server con e senza stato 573 16.5 Replica dei file 574 16.6 Un esempio: AFS 575 16.6.1 Panoramica 576 16.6.2 Lo spazio dei nomi condiviso 577 16.6.3 Operazioni sui file e coerenza 578 16.6.4 Implementazione 579 16.7 Riassunto 580 Esercizi 581 Note bibliografiche 581 Capitolo 17 - Coordinamento distribuito 583 17.1 Ordinamento degli eventi 583 17.1.1 La relazione accaduto prima 583 17.1.2 Implementazione 584 17.2 Mutua esclusione 586 17.2.1 Metodo centralizzato 586 17.2.2 Metodo completamente distribuito 586 17.2.3 Il metodo del passaggio di token 588 17.3 Atomicità 588 17.3.1 Il protocollo di commit a due fasi 589 17.3.2 Gestione dei guasti nel protocollo 2PC 590 17.4 Controllo della concorrenza 591 17.4.1 Protocolli bloccanti 592 17.4.2 Marca di tempo 594 17.5 Gestione delle situazioni di stallo 596 17.5.1 Prevenzione delle situazioni di stallo 596 17.5.2 Rilevamento delle situazioni di stallo 597 17.6 Algoritmi di elezione del coordinatore 603 17.6.1 Algoritmo del bullo 603 17.6.2 Algoritmo dell'anello 605 17.7 Raggiungimento dell' accordo 605 17.7.1 Comunicazioni inaffidabili 606 17.7.2 Processi difettosi 607 17.8 Riassunto 607 Esercizi 608 Note bibliografiche 609 Parte VI - Protezione e sicurezza 611 Capitolo 18 - Protezione 613 18.1 Obiettivi della protezione 613 18.2 Domini di protezione 614 18.2.1 Struttura del dominio di protezione 615 18.2.2 Le protezioni nel sistema operativo UNIX 616 18.2.3 Le protezioni nel sistema operativo MULTICS 617 18.3 Matrice di accesso 619 18.4 Implementazione della matrice di accesso 623 18.4.1 Tabella globale 623 18.4.2 Liste di controllo degli accessi 623 18.4.3 Liste di capacità dei domini 623 18.4.4 Il meccanismo lock-key 624 18.4.5 Confronto 624 18.5 Revoca dei diritti di accesso 625 18.6 Sistemi basati sulle capacità 627 18.6.1 Il sistema operativo Hydra 627 18.6.2 Il sistema operativo CAP System 629 18.7 Protezione basata sul linguaggio 629 18.7.1 Applicazione basata sui compilatori 630 18.7.2 Protezione in Java 2 633 18.8 Riassunto 635 Esercizi 636 Note bibliografiche 637 Capitolo 19 - Sicurezza 639 19.1 Il problema della sicurezza 639 19.2 Autenticazione dell'utente 641 19.2.1 Le password 641 19.2.2 Vulnerabilità della password 641 19.2.3 Password criptate 643 19.2.4 Password monouso 643 19.2.5 Biometria 644 19.3 Pericoli relativi ai programmi 645 19.3.1 Cavalli di Troia 645 19.3.2 Trap door 646 19.3.3 Stack overflow e buffer overflow 646 19.4 Pericoli relativi ai sistemi 647 19.4.1 Worm 647 19.4.2 Virus 650 19.4.3 Negazione del servizio 652 19.5 Garantire la sicurezza dei sistemi e delle funzioni 653 19.6 Rilevamento delle intrusioni 655 19.6.1 Che cosa costituisce un'intrusione? 655 19.6.2 Monitoraggio e analisi del registro degli eventi 657 19.6.3 Tripwire 658 19.6.4 Controllo delle chiamate di sistema 659 19.7 Crittografia 661 19.7.1 Autenticazione 662 19.7.2 Algoritmi di crittografia 663 19.7.3 Un esempio: SSL 664 19.7.4 Uso della crittografia 665 19.8 Classificazione della sicurezza dei computer 666 19.9 Un esempio: Windows NT 668 19.10 Riassunto 669 Esercizi 670 Note bibliografiche 671 Bibliografia 673 Indice analitico 697 Capitoli e appendici disponibili online: Il sistema operativo Linux Il sistema operativo Windows XP Il sistema operativo Windows 2000 Il sistema operativo FreeBSD Sistemi operativi storici Le comunicazioni in ambiente distribuito |
| << | < | > | >> |Pagina XXIIIPrefazioneIl sistema operativo è una parte essenziale del computer; un corso dedicato ai sistemi operativi è quindi parte essenziale della formazione in informatica. Questo campo sta subendo cambiamenti sempre più rapidi; i concetti fondamentali, tuttavia, sono abbastanza semplici, ed è su di essi che abbiamo basato la trattazione qui presentata. Questo libro è stato scritto come testo per un corso di carattere introduttivo sui sistemi operativi, a livello universitario o postuniversitario; speriamo che anche i professionisti lo trovino utile. Il libro fornisce una descrizione chiara dei concetti che sono alla base dei sistemi operativi moderni. A livello di prerequisiti, supporremo che il lettore abbia una conoscenza di base delle strutture dati, dei componenti di un computer e di un linguaggio ad alto livello, quale il C. Gli strumenti hardware richiesti per una comprensione adeguata dei sistemi operativi sono illustrati nel Capitolo 2. Per gli esempi di codice, useremo il linguaggio Java e qualche volta il C, ma il lettore dovrebbe essere in grado di capire le procedure illustrate anche senza una conoscenza completa di questi linguaggi. I concetti sono presentati usando descrizioni intuitive. Vengono trattati risultati teorici importanti, ma le dimostrazioni formali sono state omesse. Le note bibliografiche contengono riferimenti ai lavori di ricerca in cui sono stati presentati e dimostrati per la prima volta i risultati illustrati nel testo; vi sono pure riferimenti a materiale utile per ulteriori letture. Al posto delle dimostrazioni, come giustificazione dei risultati e guida alla comprensione, si è fatto ricorso a figure ed esempi.
Le idee e le procedure fondamentali trattate nel libro sono spesso basate su
soluzioni utilizzate nei sistemi operativi esistenti in commercio. Il nostro
scopo, tuttavia, è di illustrare queste idee e procedure in un modo del tutto
generale, senza collegamento a un particolare sistema operativo. In ogni caso,
presenteremo numerosi esempi relativi ai sistemi operativi più diffusi, tra i
quali Solaris della Sun Microsystems; Linux, Mach, Microsoft MS-DOS, Microsoft
Windows NT, Microsoft Windows 2000, Microsoft Windows XP, DEC VMS, DEC TOPS-20,
IBM OS/2, Apple Macintosh, e MacOS X. Nel libro, quando ci riferiremo a Windows
XP come esempio di sistema operativo, intenderemo sia Windows XP che Windows
2000; se vi è una caratteristica di Windows XP che non è disponibile in Windows
2000, lo diremo esplicitamente; analogamente, se una caratteristica è presente
in Windows 2000 ma non in Windows XP, faremo riferimento al sistema come Windows
2000.
Contenuto del libro Il testo è organizzato in sette parti. • Panoramica. I Capitoli da 1 a 3 spiegano che cosa sono i sistemi operativi, che cosa fanno e come sono progettati e realizzati, illustrando come si è sviluppato il concetto di sistema operativo, quali sono le caratteristiche comuni di un sistema operativo, che cosa fa un sistema operativo dal punto di vista dell'utente e dal punto di vista del sistema di calcolo. La presentazione è di tipo motivazionale, storico ed esplicativo. In questi capitoli abbiamo evitato la discussione sulla struttura interna; tali pagine sono quindi adatte a studenti di corsi introduttivi, che desiderano imparare che cos'è un sistema operativo, senza entrare nei particolari delle sue procedure interne. Il Capitolo 2 tratta argomenti relativi all'hardware che sono importanti per comprendere il funzionamento di un sistema operativo. I lettori che hanno già sufficienti conoscenze in materia, compresi i sistemi di ingresso/uscita (input/output, I/O), l'accesso diretto alla memoria (Direct Memory Access, DMA) e le operazioni sugli hard disk, possono scegliere di leggere rapidamente o in parte questo capitolo, oppure di saltarlo del tutto. • Gestione dei processi. I Capitoli da 4 a 8 descrivono il concetto di processo e di concorrenza, cioè il cuore dei moderni sistemi operativi. Un processo è l'unità di lavoro in un sistema operativo. In un sistema di elaborazione si ha un insieme di processi in esecuzione concorrente, alcuni dei quali sono processi propri del sistema operativo (quelli che eseguono il codice del sistema stesso), mentre i rimanenti sono processi utente (quelli che eseguono il codice dei programmi dell'utente). Questi capitoli riguardano la schedulazione e la sincronizzazione dei processi, la comunicazione tra processi e la gestione delle situazioni di stallo (deadlock). Vengono inoltre trattati i thread. • Gestione della memoria. I Capitoli da 9 a 12 esaminano i processi nella memoria principale durante la loro esecuzione. Per migliorare l'utilizzo della CPU e la velocità di risposta agli utenti, il computer deve mantenere parecchi processi in memoria. Ci sono molti schemi differenti per la gestione della memoria, che riflettono approcci diversi. L'efficacia dei vari algoritmi dipende dalla situazione. Poiché la memoria centrale è solitamente troppo piccola per accogliere tutti i dati e i programmi, e poiché non può memorizzare in modo permanente i dati, il computer deve essere dotato di una memoria secondaria che affianchi quella centrale. La maggior parte dei computer moderni usa i dischi come strumento primario di memorizzazione in linea per le informazioni sia sui programmi, sia sui dati. Il file system fornisce il meccanismo per la memorizzazione in linea e l'accesso ai dati e ai programmi che risiedono su disco. Questi capitoli descrivono le procedure e le strutture di gestione della memoria, offrendo una conoscenza pratica degli algoritmi usati, delle loro proprietà, dei relativi vantaggi e svantaggi. • Sistemi di ingresso/uscita. I Capitoli 13 e 14 descrivono i dispositivi di ingresso/uscita (input/output, I/O) che si collegano a un computer. Poiché questi dispositivi differiscono ampiamente tra loro, il sistema operativo deve fornire una vasta gamma di funzionalità alle applicazioni, per consentire di controllare tutti i loro aspetti. Questa Parte discute in profondità il sistema di I/O, compresa la progettazione e le interfacce di I/O, nonché le strutture e le funzioni interne del computer. Sotto molti aspetti, i dispositivi di I/O sono tra i componenti più lenti del computer; rappresentando dunque una sorta di "collo di bottiglia", viene esaminato il problema delle prestazioni. Vengono pure illustrati argomenti relativi alla memorizzazione secondaria e terziaria. • Sistemi distribuiti. I Capitoli da 15 a 17 si occupano di sistemi di elaborazione costituiti da un insieme di processori che non condividono la memoria o l'orologio, i cosiddetti sistemi distribuiti. Fornendo all'utente l'accesso alle varie risorse disponibili, un sistema distribuito può migliorare la velocità di calcolo, la disponibilità e l'affidabilità dei dati. Tale sistema, inoltre, fornisce all'utente un file system distribuito, cioè un servizio per l'accesso ai file in cui gli utenti, i computer e i dispositivi di memorizzazione sono disseminati nei vari luoghi in cui si trova il sistema distribuito. Un sistema distribuito deve fornire vari meccanismi di sincronizzazione e comunicazione per gestire lo stallo nonché la varietà di guasti che non si incontrano in un sistema centralizzato. • Protezione e sicurezza. I Capitoli 18 e 19 trattano le problematiche relative alla protezione e alla sicurezza in un sistema operativo. A scopo di protezione e sicurezza, appositi meccanismi assicurano che solo i processi che hanno ricevuto un'autorizzazione adeguata dal sistema operativo possano operare sui file, i segmenti di memoria, la CPU e le altre risorse. La protezione è un meccanismo per controllare l'accesso alle risorse di un computer da parte di programmi, processi o utenti. Questo meccanismo deve fornire la possibilità di specificare i controlli da imporre, così come gli strumenti per applicarli. Per "sicurezza" si intendono tutte quelle azioni intraprese per proteggere le informazioni memorizzate nel sistema (dati e codice) e le risorse fisiche del computer da accessi non autorizzati, da una distruzione volontaria o dall'introduzione accidentale di incoerenze. • Esempi di sistemi operativi. I Capitoli da 20 a 22 e le Appendici da A a C, scaricabili dal sito Web abbinato al libro, integrano i concetti presentati descrivendo sistemi operativi reali, tra cui Linux, Windows XP, Windows 2000, FreeBSD e Mach. Abbiamo scelto Linux e FreeBSD poiché questi sistemi di tipo UNIX sono abbastanza piccoli da risultare comprensibili, ma allo stesso tempo non sono sistemi operativi "giocattolo". La maggior parte delle loro procedure interne sono state selezionate per la semplicità, piuttosto che per la velocità o la sofisticazione. Sia FreeBSD che Linux sono usualmente disponibili nei dipartimenti universitari di informatica, cosicché molti allievi possono sperimentarli personalmente. Abbiamo scelto Windows XP e Windows 2000 perché ci offrono un'occasione per studiare un moderno sistema operativo con un progetto e un'implementazione drasticamente differenti da quelli di UNIX. Il Capitolo 22 descrive brevemente alcuni altri sistemi operativi che hanno avuto qualche influenza storica. | << | < | > | >> |Pagina 1284.7 Riassunto [I processi]Un processo è un programma in esecuzione. Mentre vengono eseguiti, i processi cambiano stato. Lo stato di un processo è definito dall'attività corrente del processo medesimo. Ciascun processo può essere in uno dei seguenti stati: nuovo, pronto, in esecuzione, in attesa o terminato, ed è rappresentato nel sistema operativo dal suo Process-Control Block (PCB). Un processo, quando non è in esecuzione, viene messo in una coda d'attesa. Vi sono due tipi principali di code in un sistema operativo: code per la richiesta di I/O e code per i processi pronti; queste ultime contengono tutti processi che sono pronti per essere eseguiti e attendono la CPU. Ciascun processo è rappresentato da un PCB, e i PCB possono essere riuniti per formare la coda dei processi pronti. La schedulazione dei processi a lungo termine è la selezione dei processi cui è permesso contendersi la CPU. Di solito, lo schedulatore a lungo termine è altamente influenzato da considerazioni sull'allocazione delle risorse, specialmente per la gestione della memoria. La schedulazione a breve termine è la selezione di un processo da mettere in esecuzione dalla coda dei processi pronti. I processi, in molti sistemi operativi, possono essere eseguiti concorrentemente. Ci sono svariate ragioni per consentire l'esecuzione concorrente: la condivisione di informazioni, la velocizzazione della computazione, la modularità e la convenienza. L'esecuzione concorrente richiede un meccanismo per la creazione e la terminazione dei processi. Il processo in esecuzione nel sistema operativo può essere indipendente o cooperante. I processi cooperanti devono avere i mezzi per comunicare l'un con l'altro. In sintesi, la comunicazione si ottiene attraverso due schemi complementari: la condivisione di memoria e lo scambio di messaggi. I metodi per la condivisione della memoria richiedono che i processi comunicanti condividano alcune variabili, e i processi scambiano informazioni attraverso l'uso di queste variabili condivise. Nel sistema a condivisione di memoria la responsabilità di attuare la comunicazione è dei programmatori dell'applicazione; il sistema operativo deve fornire solo la memoria condivisa. Il meccanismo di scambio dei messaggi permette di trasferire informazioni attraverso i messaggi. La responsabilità di garantire la comunicazione è del sistema operativo. Questi due schemi non sono mutuamente esclusivi e possono essere usati simultaneamente in un singolo sistema operativo. La comunicazione nei sistemi client-server può usare (1) i socket, (2) le chiamate di procedure remote (RPC) o (3) l'invocazione di metodi remoti di Java (RMI). Un socket è definito come un estremo di un canale di comunicazione: una connessione fra due applicazioni è composta da una coppia di socket, uno a ciascuno degli estremi del canale di comunicazione. Un'altra forma di comunicazione distribuita sono le RPC. Una RPC avviene quando un processo (o thread) chiama una procedura in un'applicazione remota. La RMI è la versione Java della RPC: essa consente a un thread di invocare un metodo su un oggetto remoto come se lo invocasse su un oggetto locale. La differenza principale fra RPC e RMI consiste nel fatto che nella RPC i dati sono passati a una procedura remota attraverso un'ordinaria struttura dati, mentre la RMI permette che siano passati oggetti come parametri. | << | < | > | >> |Pagina 37210.10 Riassunto [La memoria virtuale]È desiderabile poter eseguire un processo il cui spazio logico degli indirizzi è più grande dello spazio degli indirizzi della memoria fisica disponibile. Il programmatore può rendere tale processo eseguibile ristrutturandolo mediante overlay (sovrapposizione), ma ciò rappresenta generalmente un'attività di programmazione difficile. La memoria virtuale è una tecnica per permettere a un grande spazio di indirizzi logici di essere mappato in una memoria fisica più piccola. La memoria virtuale permette a processi notevolmente grandi di funzionare, e consente di elevare il livello di multiprogrammazione, aumentando l'utilizzo della CPU. Inoltre, libera i programmatori dalle preoccupazioni relative alla disponibilità di memoria. La memoria virtuale è comunemente implementata con la richiesta di paginazione. La richiesta di paginazione pura non porta mai a una pagina fino a quando quella pagina non è referenziata. Il primo referenziamento causa una mancanza di pagina nel monitor residente del sistema operativo. Il sistema operativo consulta una tabella interna per determinare, nella memoria ausiliaria, dove si trova la pagina; trova poi un frame libero e carica la pagina dalla memoria ausiliaria. La tabella delle pagine è aggiornata per riflettere questo cambiamento e l'istruzione che ha causato la mancanza di pagina viene fatta ripartire. Questo metodo permette a un processo di funzionare anche se l'intera immagine della memoria non è immediatamente nella memoria centrale. Finché il tasso di mancanze di pagina è ragionevolmente basso, le prestazioni sono accettabili. Si può usare la richiesta di paginazione per ridurre il numero di frame allocati a un processo. Questa modalità può aumentare il livello di multiprogrammazione (permettendo a più processi di essere disponibili contemporaneamente per l'esecuzione) e, almeno in teoria, l'utilizzo della CPU del sistema. La paginazione permette, inoltre, ai processi di andare in esecuzione anche se le loro richieste di memoria eccedono la memoria fisica totale disponibile, funzionando nella memoria virtuale. Se le richieste totali di memoria eccedono la memoria fisica, può poi essere necessario sostituire le pagine prese dalla memoria con dei frame liberi per ottenere nuove pagine. Allo scopo si usano vari algoritmi di sostituzione. La sostituzione FIFO della pagina è facile da programmare ma è affetta dall'anomalia di Belady. La sostituzione ottimale della pagina richiede di conoscere il comportamento futuro. La sostituzione LRU è un'approssimazione della sostituzione ottimale della pagina, ma può anche essere difficile da implementare. La maggior parte degli algoritmi di sostituzione delle pagine, quale l'algoritmo della seconda possibilità, sono approssimazioni della sostituzione LRU. In aggiunta all'algoritmo di sostituzione della pagina, è necessaria una politica di allocazione dei frame. L'allocazione può essere statica, con la sostituzione locale delle pagine, o dinamica, con la sostituzione globale. Il modello working set assume che i processi siano eseguiti in località; il working set consiste nell'insieme delle pagine nella località corrente. In base a tale modello, a ogni processo dovrebbero essere allocati abbastanza frame per il proprio working set. Se un processo non ha abbastanza memoria per il proprio working set, avverrà un thrashing. Fornire abbastanza frame a ogni processo per evitare il thrashing può richiedere di commutare e schedulare i processi; oltre a richiedere di risolvere i principali problemi di sostituzione della pagina e di allocazione di frame, un'adeguata progettazione di un sistema di paginazione richiede di considerare la dimensione della pagina, l'I/O, il blocco, la prepaginazione, la creazione del processo, la struttura del programma ecc. Molti sistemi operativi forniscono funzionalità per mappare i file in memoria, permettendo quindi che le chiamate di I/O ai file siano trattate come procedure di accesso alla memoria. Java fornisce un'API per la mappatura della memoria. Ci sono parecchie altre questioni riguardanti la memoria virtuale, tra cui la prepaginazione di un file in memoria, la dimensione di una pagina e la quantità di memoria che può essere referenziata nel buffer look-aside.
La memoria virtuale può essere considerata come un livello in una gerarchia
di livelli di memorizzazione in un computer. Ogni livello ha un proprio tempo di
accesso, una propria dimensione e propri parametri di costo. Un esempio completo
di sistema ibrido e funzionale di memoria virtuale è presentato nel capitolo
dedicato al Mach (Appendice B).
|