Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
vuoi
o PayPal
tutte le volte che vuoi
CLOSE.
Si può chiudere un singolo lato della pipe (scrittura o lettura) un estremo si chiude quando tutti i
processi che conoscevano la file tramite fd0 o fd1 hanno compiuto una close. In questo caso si può
chiudere il lato della pipe e poi si può eliminare la pipe
A cura di stefano Silvani UTIU – È fatto divieto di qualsiasi forma di riproduzione vendita e divulgazione del presente materiale senza previa
174
autorizzazione dell’autore.
Sotto vediamo che il processo padre usa fd0 e quindi legge mentre il figlio usa fd1 ciò è un processo
mittente. Quindi il padre chiude il lato fd1 perchè non gli serve e il figlio chiude fd0 perchè non gli
serve.
Nella parte sinistra vediamo che il padre crea la pipe, poi crea il figlio tramite fork e poi il figlio chiude
il lato della lettura mentre il padre chiude il lato di scrittura e fa la read del lato di lettura fd0.
Quando tutti i lati sono chiusi la pipe scompare
Quindi le due caratteristiche fondamentali della pipe sono che:
- non è persistente: si distrugge quando terminano tutti i procesis che la usano
- funziona solo tra processi della stessa gerarchia
A cura di stefano Silvani UTIU – È fatto divieto di qualsiasi forma di riproduzione vendita e divulgazione del presente materiale senza previa
175
autorizzazione dell’autore.
Per realizzare comunicazione tra processi non della stessa gerarchia si usa il costrutto FIFO che è una
pipe con nome che è un file tradizionale che esiste nel file system. E rappresenta un canale
unidirezionale del tipo first in first out che a differenza della pipe è persistente e quindii è visibile a
tutti gli altri processi e quindi è usato per far comunicare i processi che non appartengono alla stessa
gerarchia
Esiste la chiamata mkfifo (make fifo) e che una volta aperta si accede alla struttura con le stesse
chiamate classiche dei file (la fifo stessa è un file)
Per creare la fifo si usa la system call fifo e come parametro si specifica il nome del file,
pathname è il nome della fifo e mode rappresenta i permessi di accesso per cui ad ogni file sono
associati diritti di accesso (azioni possibili e impossibili sui file, permessi vanno esplicitati quando viene
creato il file)
questa chiamata restituisce 0 quando ha success e valore negativo in caso contrario
A cura di stefano Silvani UTIU – È fatto divieto di qualsiasi forma di riproduzione vendita e divulgazione del presente materiale senza previa
176
autorizzazione dell’autore.
Per aprire e chiudere la FIFO:
una volta creata può essere aperta con una primitiva di OPEN
sotto si vede come uso la open, do nome del file e specifico i diritti di accesso
Per chiudere la fifo si usa la primitiva closefd indicandone quindi nome del descrittore
Per eliminare la fifo si usa la primitiva unlink dandogli come parametro il nome del particolare file di
fifo
Una volta che ho aperto la fifo posso accedervi mediante le normali di read e write.
Come si vede dal frammento di codice in basso si vede che si usa la chiamata open per aprire il file
myfifo che è la fifo che deve essere usata per lo scambio di messaggi e si vede che si usa la primitiva
read fatta sul descrittore della notra fifo
A cura di stefano Silvani UTIU – È fatto divieto di qualsiasi forma di riproduzione vendita e divulgazione del presente materiale senza previa
177
autorizzazione dell’autore.
Con questa lezione abbiamo concluso il discorso relativo alla comunicazione tra processi in unix
(sincronizzazione e communicazione)
Si parla ora dell’argomento più specifico della sincronizzazione tra processi unix che affronta la
tematica di interazione tra threads.
Si richiamano quindi le proprietà fondamentali dei thread:
- è sturmento definito all’intern di un processo
- dentro stesso processo si possono definire più thread (processo leggero) che operano in
ambiente globale e accedono alle risorse del processo e devono quindi essere sincronizzati
tramite meccanismi quali semafori, wait e signal che servono per sincronizzare attività
concorrenti in memoria comune
noi avevamo introdotto il thread perchè la maggiornaza di applicaizoni sono facilmente decomponibili
in parti eseguibili parallelamente, anche i procesis hanno questa proprietà ma il cambio di contesto tra
un process e l’altro è pesante perchè ongi processo ha oltre al contesto tutta la sua memoria e per
questo è pesante mentre il cambio di contesto tra thread è semplice perchè questi condividono la
stessa memoria e variabili globali e per questo viene usato molto da tutte le applicazione (anche in
linguaggio java)
Lez. 14 - Threads nel S.O. Linux
Definizione e proprietà dei threads nel SO Linux
Nella lezione passata abbiamo introdotto il motivo della introduzione dei threads quindi ora parliamo
direttamente della gestione dei thread in linux
I threads sono processi leggeri contrapposti al processo pesante che insieme ad altri thread condivide
uno spazio di indirizzi (variabili globali condivise col processo padre che genera i threads)
In linux, una delle caratteristiche fondamentali che lo differenzia da unix è la presenza dei thread a
livello di kernel. La libreria usata dai processi per operare sui thread è dentro al SO linux > i thread sono
gestiti direttamente a livello kernel
Si ricorda che ci sono 2 modi di gestione dei threads:
- livello utente (librearia in utente e funzioni di questa libreria implementate fuori dal kernel)
- livello kernel: unità di scheduling è il thread realizzato all0interno del SO e tutte le funzioni
della libreria sono realizzate dentro il kernel
A cura di stefano Silvani UTIU – È fatto divieto di qualsiasi forma di riproduzione vendita e divulgazione del presente materiale senza previa
178
autorizzazione dell’autore.
Esiste una chiamata CLONE che serve per la generazione dei threads. Noi non parleremo di questa
primitiva. Tramite questa primmitiva si può specificare lo spazio di indirizzamento condivisa tra padre
e figlio (tra chi esegue la CLONE e chi nasce per effetto di quest’ultima chiamata) c’è quindi
condivisione di spazio e indirizzamento ma la caratteristicha di questa system call è che è tipica di linux
e non facilmente portabile (usabile in ambienti diversi)
A suo tempo fu definita la libreria “pthreads” definitia dall’organizzazione di standardizzazione POSIX.
Questa libreria mette a disposizione una serie di funzioni ed abbiamo varie versioni di questa libreria..
Quella di ns interesse è la “linux pthreads” che serve per gestione sincronizzazione etc dei threads che
è implementata nel kernel di linux
A cura di stefano Silvani UTIU – È fatto divieto di qualsiasi forma di riproduzione vendita e divulgazione del presente materiale senza previa
179
autorizzazione dell’autore.
In caso di linux “tutto è threads” anche il processo stesso è un threads. Il processo È un threads che
non condivide memoria con altri.
Il main è un thread (processo) che può generarne altri
Ogni thread ha un identificatore che è un numero intero TID (thread identifier) e esiste nella libreria
un tipo che è il tpo pthread-t che è definito dentro la libreria insieme alle altre funzioni che è il tipo da
cui si possono ricavare i singoli thread come derivazioni da questo tipo.
L’
Primitive di gestione dio thread
In linux esecuziuone di programma determina creazione di thread iniziale con codice specificato dal
main
Questo thread può generare altri thread figli e quindi si ricrea il concetto di gerarchia di thread che
condivisono stesse variabili definite all’interno del main.
A cura di stefano Silvani UTIU – È fatto divieto di qualsiasi forma di riproduzione vendita e divulgazione del presente materiale senza previa
180
autorizzazione dell’autore.
Le funzioni:
Per creare un thread viene usata la primitive pthread_create, che ha una serie di parametri:
- T: rappresenta in C il puntatore alla vairabile che contiene il TID del nuovo thread
- A: rappresenta attributi del thread, come la priorità, la struttura dati etc.. ed è del tipo
pthread_attr_T
- Cod: è il codice del nuovo thread
- Arg: è il puntatore al vettore che ha i parametri della funzione
Si ricorda che si può sempre fare un parallelismo con unix con la fork, exect, etc...
A cura di stefano Silvani UTIU – È fatto divieto di qualsiasi forma di riproduzione vendita e divulgazione del presente materiale senza previa
181
autorizzazione dell’autore.
La primitive torna 0 se ha successo senno da un codice di errore
Il SO deve far si che il thread esegua concorrentemente al padre e condivida le variabili globali del
padre.
Ad sesempio:
Sotto vediamo che il main dichiara due thread t.1 e t.2 appartenenti al tipo pthread
Poi tramite create genera il thread di nome t1 e t2, gli da il codice (che è lo stesso per entrambi quindi
i due thread eseguono lo stesso codice
Il fatto che ci sia NULL significa che i paramentri non ci sono come non ci sono attributi
La primitive per la temrinazione del thread:
pthread_exit: è il nome della funzione che ritorna un valore. Il valore di ritorno è la modalità di
terminazione che il thread vuole consegnare al processo padre. (“*retval”)
A cura di stefano Silvani UTIU – È fatto divieto di qualsiasi forma di riproduzione vendita e divulgazione del presente materiale senza previa
182
autorizzazione dell’autore.
Esiste la possibilità che il processo padre che genera il thread si metta in attesa di temrinazione del
thread figlio.
Se il thread figlio è già temrrinato il padre non ha bisogno di mettersi in attesa
- Th: è il nome del thread che io sto aspettando che temrini (identificativo)
- Retval: è la condizione passata al padre dal thread terminato
Una delle caratteristiche della JOIN è che il thread padre ha preso atto della terrminazione del thread
figlio allora il figlio scompare dal sistema e tutta la sua area di memoria viene liberata.
L’area di memoria occupata dal thread: un thread ha la sua area di memoria: ha il suo descrittore, sua
area dati privata, suo stack etc.. e quindi quando temrina la sua area di memoria viene liberata.
Sotto vediamo che dichiariamo un codice che verrà eseguito dal thread che comporta la stampa del
messaggio con indicazione del numero del thread che eseguirà questo codice e al termine della stampa
c’è una operazione di slep per sospendere il thread per un secondo e poi abbiamo condizione di
temrinazione. Vediamo che retval=0 significa che tutto è temrinato correttamente
A cura di stefano Silvani UTIU – È fatto d