Estratto del documento

SISTEMI OPERATIVI

Il sistema operativo serve come interfaccia tra livello applicativo ed hardware, non compie

operazioni apparentemente utili ma fornisce un ambiente per il corretto funzionamento dei

programmi.

Funzioni e servizi base

- Controllo flusso ed esecuzione dei programmi

- Allocazione risorse e gestione

memoria

- Accesso a dispositivi I/O

- Comunicazione tra processi

- Gestione errori e malfunzionamenti

- Protezione

- Gestione statistiche e raccolta dati

Componenti base SO

- Gestore dei processi

- Gestore della memoria

- Gestore della memoria secondaria

- Gestore dei sistemi di I/O

- Gestore dei file

- Gestore della comunicazione di rete

- Gestore della sicurezza

- Interprete dei comandi

Tipi di sistema

- sistemi paralleli => massimizzano throughput (multiprocessore / multicore / distribuiti)

1

si può simulare con sistemi time-sharing 2

- Sistemi real-time => forniscono risultati entro il tempo prestabilito, possono essere

HARD real time o SOFT real time (embedded / sistemi di controllo)

SISTEMI MULTIPROCESSORE SISTEMI MULTICORE

Nel caso di processori con multithread fisico si ha un unico chip con una sola ALU ma 2

set di registri separati che permettono l'esecuzione quasi simultanea.

throughput = (produttività) capacità elaborativa in un tempo determinato

1 time-sharing = possiedono scheduler che assegna quanti di tempo limitati ad ogni processo

2 1

SISTEMI CLOUSTER Tipi di connessione

- Client-server => ruoli dispositivi

ben definiti, un server ed n clients

che si connettono ad esso

- Peer-to-peer => ogni dispositivo

è sia server che client

Architetture di base

- Architettura a strati => ogni strato fornisce funzionalità allo strato superiore

nascondendo quelle del livello inferiore

- Architettura microkernel => kernel comprende solo funzioni essenziali (scheduling /

gestione interruzioni / gestione memoria / comunicazione tra processi), tutte le altre

funzionalità sono trattate come processi

OSS Sia UNIX che windows NT usano architetture intermedie incentrate su un kernel 3

monolitico che implementa gli altri moduli dinamicamente.

Unix ha architettura base a strati.

Windows ha architettura base microkernel, inoltre è multithread nativo.

Standards

- Standard di linguaggio (API ) => insieme delle funzioni di libreria che rimangono

4

invariate al variare del sistema, permettono portabilità su piattaforme differenti

(ex. ANSI-C)

- Standard di sistema (ABI ) => insieme di servizi per la programmazione su una

5

determinata famiglia di sistemi (POSIX per UNIX-LIKE , WINAPI per WINDOWS)

6

Essendo POSIX gestito da open-group, che vende le licenze, linux usa uno

standard simile chiamato LSB (linux standard base)

Gli standard forniscono anche le funzioni preambolo per le System call.

kernel = nucleo del sistema operativo contente tutte le funzioni essenziali

3 API = application programming interface, librerie tra app e OS

4 ABI = application binary interface, convenzioni di sistema, interazione tra OS e Hardware

5 Certificazione POSIX appartiene a OPEN-GROUP, linux non è certificato posix

6 2

Flusso di controllo eccezionale

Il flusso normale di un programma può essere alterato da:

- Interrupt (asincrone)=> eventi generati all’esterno della cpu (I/O / segnali )

- Exception (sincrone)=> eventi generati dalla cpu (trap / fault / abort )

7 8 9

Al verificarsi di uno di questi si utilizza il codice del sistema operativo, quindi cambia

modalità utente modalità

anche il modo di esecuzione, si passa da (mode bit = 1) a

kernel (mode bit = 0) che permette di usare tutte le istruzioni di cui è dotato il sistema.

Per sapere quale programma del kernel bisogna utilizzare il sistema operativo fa

vector”,

riferimento al suo “interrupt un array contenuto nel kernel con tutti i descriptor

(linux) o handle (Windows) alle routine di sistema.

Implicano un context switch che utilizza una IRET per il ritorno. (vedere più avanti)

System call

Sono chiamate ad una routine di sistema operativo tramite il supporto delle trap.

Possono essere utilizzate direttamente tramite programmazione con Assembly mediante

$0x80”

l'istruzione “int che permette di accedere al "interrupt vector”, verrà eseguita la

routine corrispondente al numero contenuto nel registro %?a? utilizzando come parametri

le informazioni contenute nei registri subito dopo.

Altrimenti possono essere implementate in c (o altro linguaggi di alto livello) tramite uno o

wrapper

più (involucri), ovvero funzioni che avvolgono a loro volta altre funzioni fino ad

arrivare al codice Assembly per la syscall. (ex. printf())

I wrapper fanno sembrare le System call normali funzioni di libreria e combinati con

l'utilizzo dell'ambiente di esecuzione permettono la portabilità del codice, la syscall in se

è però machine dependent.

Ambiente di esecuzione

Insieme dei moduli aggiuntivi (import librerie e simili) inseriti nel codice dal linker in fase di

compilazione del programma, cambia da un sistema operativo all’altro.

Serve come raccordo tra il kernel ed il main del programma, permette la portabilità del

codice ricompilando sul nuovo sistema compatibile.

Ex: nei sistemi linux il main richiama la funzione “_start()” che effettua il setup e ne

permette l’esecuzione.

trap = istruzione macchina per il passaggio del controllo al kernel (usato per system call)

7 fault = evento generato in condizione di errore, recuperabile (ex. Page fault)

8 abort = evento raro non recuperabile, provoca terminazione del processo (ex. Prob hardware)

9 3

I processi

Entità attiva che rappresenta il programma in esecuzione, 2 o più processi possono

condividere lo steso programma.

I processi vengono creati da altri processi come loro copie, il processo che crea il nuovo

processo viene detto padre, il processo creato figlio.

Si crea quindi una struttura ad albero dei processi (in linux il primo processo è init).

Stati di un processo

New

1. => fase di creazione del processo

Ready

2. => il processo è pronto ed aspetta di essere assegnato alla CPU dallo

scheduler per entrare in esecuzione

Running

3. (USER / KERNEL) => il processo è in esecuzione nella CPU

OSS il numero massimo dei processi in stato running è dato dal numero delle CPU

Waiting

4. => il processo rimane in attesa di un evento di I/O

Terminated

5. => il processo termina e rilascia le risorse utilizzate (funzione exit())

OSS Quando un processo termina, se lo stato di terminazione (dato dalla funzione exit())

non può essere raccolto dal padre, entra

Zombie,

nello stato di il suo stato di

terminazione verrà quindi salvato in un

record del kernel finché un altro

programma lo raccoglierà e chiuderà. <- sp (stack pointer)

Immagine in memoria

Ad ogni nuovo processo che entra in

esecuzione viene associata una immagine

di memoria virtuale corrispondente al suo <- brk

spazio di indirizzamento.

Lo spazio di memoria si divide in:

- text => codice del programma

(execute and read only)

- Data => variabili globali, static e

stringhe (stringhe read only)

- Heap => memoria allocata

dinamicamente

- Stack => dati delle funzioni, … 4

PCB (process control block)

Contiene tutte le informazioni per la gestione del processo contenuta nel kernel, differente

dall'immagine di memoria ma contiene riferimenti ad essa.

È composto da:

- PID (process ID) e PPID (parent process ID)

- Puntatori ad immagine di memoria

- Privilegi del processo

- Stato del programma

- PC (program counter)

- priorità ed informazioni sullo scheduling

- Tabella file processo ed I/O

- Area salvataggio registri

Creazione ed esecuzione processo in unix (versione base)

#include <unistd.h >

10

#include <stdio.h>

int main() {

pid_t pid = fork() ;

11

if (pid < 0) { /* -1 => error occurred */

printf("Fork Failed");

exit(1);

}

else if (pid == 0) { /* child process */

execlp("/bin/ls", "ls", NULL) ; /* execute program “ls" */

12

_exit(0) ;

13

}

else { /* parent process */

wait (NULL) ;

14

printf ("Child Complete");

}

return 0; /* in main equivalente a exit()*/ pid_t getpid() => restituisce pid processo

} vfork() => figlio usa stesso Address space del padre

WARNING se si inserisce fork() in ciclo

per generare più processi è essenziale status);”

terminare il codice figlio con “break;” o “_exit( per evitare generazione infinita di

processi (data dal “goto” alla fine del ciclo)

<unistd.h> => libreria contente funzioni fork(), wait(), exec()…

10 pid_t fork( ) => permette di creare nuovo processo come copia del padre ma con pid e

11 immagine di memoria differenti, tutte le operazioni effettuate da adesso in avanti nella

sezione del figlio non influenzeranno il padre (e viceversa)

int exec => famiglia di funzioni che permettono al processo di eseguire un nuovo programma

12 passato come argomento, possibile consultare famiglia exec su OPEN-GROUP

void _exit( int status) => versione con trattino permette di mantenere canali I/O aperti siccome

13 processo padre e figlio usano gli stessi, status = stato di ritorno

pid_t wait( int *stat_loc) => costringe processo padre ad aspettare terminazione figlio evitando

14 generazione processi zombie. Possibile salvare stato di ritorno del figlio su una variabile

passandola come argomento stat_loc.

Se processo ha più figli si usa funzione “waitpid()“ per selezionare processo desiderato 5

Threads process).

Un thread è definito come un processo leggero (lightweight

I thread appartenenti allo stesso processo, pur eseguendo operazioni differenti, utilizzano

lo stesso spazio di memoria.

Rendono quindi possibile:

- Condivisione della memoria dentro lo stesso task

15

- Multiprogrammazione e scalabilità

16

- Esecuzione indipendente dei singoli thread, un thread può non essere bloccante per

altro thread (Ex. grafica separata da elaborazione dati / richieste multiple su server)

Programmazione singolcore vs multicore

La programmazione multithread permette quindi di sfruttare la concorrenza nei

programmi, si può implementare in due modi a seconda del tipo di architettura :

- Esecuzione concorrente => si utilizza in sistemi singolo core, illusione di parallelismo

data dall’esecuzione alternata dei thread in quanti di tempo (interleaved)

- Esecuzione parallela => utilizzabile in sistemi multicore, permette di assegnare ad

ogni core uno o più threads ed eseguirli contemporaneamente

2 tipi di parallelismo

- Data parallelism =>

suddivisione sottoinsiemi dei

dati su più core per eseguire

più velocemente stesse

operazioni

- Task parallelism =>

suddivisione dei threads su

ogni core, ognuno esegue le

sue operazioni

task = insieme di threads appartenenti allo stesso processo

15 scalabilità = esecuzione parallela su più processori (o core)

16 6

Strategie creazione threads

- Threading sincrono => (fork-join) genitore dopo aver creato uno o più figli aspetta la

loro terminazione e conseguente join prima di continuare la sua esecuzione.

(Ex. somma vettore)

- Threading asincrono => dopo aver creato thread figlio, genitore riprende la sua

normale esecuzione e non ha bisogno di conoscere quando termina il figlio.

(Ex. sever)

Categorie di thread

- kernel level thread (KLT) => implementazione a livello kernel, scheduling più lento a

causa del passaggio per il kernel ma i threads sono completamente indipendenti ed il

blocco di uno non implica in blocco degli altri.

- User level thread (ULT) => implementazione a livello di applicazione, il kernel non è a

conoscenza della loro esistenza, quindi scheduling più veloce ma nel caso di syscall

bloccante su un thread si bloccano tutti.

Modelli di multithreading

da uno a molti

1. => più user threads mappati su un solo kernel thread, gestione

efficiente risorse, non è però possibile usare parallelismo ed il blocco di uno provoca

provoca il blocco di tutti. Usato su pochi sistemi.

Da uno ad uno

2. => ogni user thread è mappato su un kernel thread, permette

parallelismo e chiamate non sono bloccanti su altri threads, ha lo svantaggio di dover

creare un kernel thread per ogni user thread (threads limitati per evitare overhead ).

17

Usato in linux e windows.

Da molti a molti

3. => più user threads vengono mappati su un numero minore o uguale

di kernel threads, permette di creare un numero maggiore di user threads rispetto al

modello uno ad uno potendo rimappare gli ULT (necessita di LWP)

1 3

2

overhead = richiesta risorse maggiore di quella realmente necessaria

17 7

Pthreads POSIX I sistemi unix non fanno

#include <stdio.h>

#include <stdlib.h> distinzione tra processi e threads.

#include <pthread.h> Infatti posso anche usare syscall

clone() invece di pthread_create()

void *print_message_function( void *ptr ) {

char *message;

message = (char *) ptr;

printf("%s \n", message);

}

main() {

pthread_t thread1, thread2;

const char *message1 = "Thread 1";

const char *message2 = "Thread 2";

int iret1, iret2; /*permettono di controllare risultato, 0 in caso di successo*/

iret1 = pthread_create( &thread1, NULL, print_message_function, (void*) message1) ;

18

if(iret1)

{ fprintf(stderr,"Error - pthread_create() return code: %d\n",iret1);

exit(EXIT_FAILURE);

}

iret2 = pthread_create( &thread2, NULL, print_message_function, (void*) message2);

if(iret2)

{ fprintf(stderr,"Error - pthread_create() return code: %d\n",iret2);

exit(EXIT_FAILURE);

}

printf("pthread_create() for thread 1 returns: %d\n",iret1);

printf("pthread_create() for thread 2 returns: %d\n”,iret2);

pthread_join( thread1, NULL) ;

19

pthread_join( thread2, NULL);

exit(EXIT_SUCCESS);

} int pthread_detach( phtread_t thread) => utilizzabile al posto

di join, notifica che non verranno eseguite

funzioni ritornano come operazioni di join sul thread

valore 0 in caso di

successo, altrimenti la void pthread_exit (void* value_ptr) => termina thread corrente

causa di errore.

OSS se uso funzione famiglia fork in processo multithread in molti sistemi unix posso

scegliere se replicare tutti i thread nel nuovo processore oppure no, se uso exec elimina

tutti i thread già presenti. DA EVITARE ENTRAMBE

int pthread_create( * ,

18 phtread_t* const pthread_attr_t void* (* )(void*) void*

thread, attr, start_routine arg);

- thread => puntatore variabile pthread_t dove memorizzare id

- Attr => attributo di creazione (spesso NULL)

- start_routine => funzione da eseguire (deve essere void)

- Arg => puntatore ad argomenti della funzione, spesso vettore allocato dinamicamente

int pthread_join(phtread_t thread, void** value_ptr) => attende terminazione esplicita

19 thread con id passato come argomento 8

Extra threads

Threading implicito

Consiste nel delegare creazione e gestione dei thread a compilatori e librerie di routine.

- thread pools (gruppi) => Si crea un gruppo di threads durante la creazione del

processo che attendono di eseguire un determinato servizio.

Finito il lavoro il thread torna in attesa, se non ci sono threads disponibili il servizio

aspetta.

Non bisogna attendere creazione threads durante esecuzione processo e si evita

overhead dato dalla creazione di troppi threads

OSS numero threads potrebbe cambiare durante esecuzione

- OpenMP => insieme di direttive per il compilatore che si inseriscono nel codice e

permettono esecuzione parallela tramite librerie runtime openMP

(Ex. #pragma omp parallel => crea più thread possibili su architettura ed esegue)

- grand central dispatch => versione proprietaria per sistemi Apple simile a openMP e

basata su pthread POSIX…

Thread-local storage (TLS)

Permette di allocare variabili visibili solo al thread, uniche per ogni thread.

Differiscono da variabili locali poiché visibili in tutto il thread e non solo nella funzione in

cui sono invocate.

Processori virtuali (LWP) e scheduling threads

Necessari per implementazione da molti a molti dinamica, il sistema operativo crea

processori virtuali intermedi che dialogano tra kernel threads e user threads.

Ad ogni LWP sono associati vari threads, al blocco di uno si bloccano anche gli altri .

Sono essenziali per lo scheduling in sistemi multithread che può avvenire in 2 modi:

- process-contention scope (PCS) => ambito della cortesia rispetto al processo,

ovvero la mappatura su LWP libero viene fatta in ambito utente tra i threads dello

stesso processo.

- System-contention scope (SCS) => ambito della cortesia allargato al sistema, ovvero

la mappatura su LWP viene fatta dal kernel e comprende tutti i threads presenti nel

sistema

OSS È possibile personalizzare le priorità di scheduling a livello utente

OSS linux e mac OS X permettono solo SCS 9

Lo scheduler

Si occupa della commutazione della CPU da un processo all’altro, funzione alla base dei

sistemi operativi multiprogrammati, questi permettono infatti di mantenere in memoria più

processi rispetto al numero di core disponibili.

Quando un processo entra in stato di wait (I/O) lo scheduler gli sottrae il controllo della

CPU e la assegna ad un altro processo in stato ready.

Fasi cicliche di un processo

- CPU burst => fasi di elaborazione della CPU

- I/O burst => fasi di attesa dell’I/O

I programmi si possono dividere un due tipologie a secondo del

tempo impiegato in ogni burst, è importante osservare la durata

dei cic

Anteprima
Vedrai una selezione di 10 pagine su 43
Appunti per l'esame di Sistemi operativi Pag. 1 Appunti per l'esame di Sistemi operativi Pag. 2
Anteprima di 10 pagg. su 43.
Scarica il documento per vederlo tutto.
Appunti per l'esame di Sistemi operativi Pag. 6
Anteprima di 10 pagg. su 43.
Scarica il documento per vederlo tutto.
Appunti per l'esame di Sistemi operativi Pag. 11
Anteprima di 10 pagg. su 43.
Scarica il documento per vederlo tutto.
Appunti per l'esame di Sistemi operativi Pag. 16
Anteprima di 10 pagg. su 43.
Scarica il documento per vederlo tutto.
Appunti per l'esame di Sistemi operativi Pag. 21
Anteprima di 10 pagg. su 43.
Scarica il documento per vederlo tutto.
Appunti per l'esame di Sistemi operativi Pag. 26
Anteprima di 10 pagg. su 43.
Scarica il documento per vederlo tutto.
Appunti per l'esame di Sistemi operativi Pag. 31
Anteprima di 10 pagg. su 43.
Scarica il documento per vederlo tutto.
Appunti per l'esame di Sistemi operativi Pag. 36
Anteprima di 10 pagg. su 43.
Scarica il documento per vederlo tutto.
Appunti per l'esame di Sistemi operativi Pag. 41
1 su 43
D/illustrazione/soddisfatti o rimborsati
Acquista con carta o PayPal
Scarica i documenti tutte le volte che vuoi
Dettagli
SSD
Ingegneria industriale e dell'informazione ING-INF/05 Sistemi di elaborazione delle informazioni

I contenuti di questa pagina costituiscono rielaborazioni personali del Publisher duke0000 di informazioni apprese con la frequenza delle lezioni di Sistemi operativi e studio autonomo di eventuali libri di riferimento in preparazione dell'esame finale o della tesi. Non devono intendersi come materiale ufficiale dell'università Università degli Studi di Roma La Sapienza o del prof Grisetti Giorgio.
Appunti correlati Invia appunti e guadagna

Domande e risposte

Hai bisogno di aiuto?
Chiedi alla community