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.
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.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
vuoi
o PayPal
tutte le volte che vuoi
Thread livello utente e thread livello Kernel
La prima distinzione che vogliamo fare nel caso in cui anche il Kernel venga ad essere diviso in più attività concorrenti è che possono esistere sia thread livello utente che thread livello Kernel. Consideriamo l'esempio più semplice, cioè il caso in cui il Kernel non conosce i thread e se ne disinteressa vedendo soltanto il processo. Applicazioni multi thread possono essere fatte in questo contesto e si possono fare andando ad utilizzare una libreria multi thread che permette di definire più thread e all'interno della quale è contenuto un piccolo scheduler che prende il nome di User-Level Thread Scheduler. Lo scheduling dei thread in questo caso viene ad essere svolto nella libreria ed il Kernel non se ne preoccupa proprio, andando solo a gestire i processi. I vantaggi di questa soluzione stanno nell'eliminare completamente l'overhead nello scheduling dei thread, diventando proprio la soluzione più efficiente.
non potrà eseguire, causando un blocco del sistema.avrà la CPU. Se quindi si ha un thread o che per un errore di programmazione oppure per una sorta di attacco, un'azione malevola per far bloccare il sistema l'unica soluzione è il killing del processo da parte del SO. Se il thread 2 non ha più niente da fare abbiamo che quando viene rilasciata la CPU si passa all'aggiornare i dati.
Nel modello in esame abbiamo che se uno dei thread fa un'operazione di I/O o invoca una system call accade che il SO non lo sa e quindi viene ad essere sprecato il tempo della CPU; lo scheduler infatti non sa chi sta seguendo cosa, sente solo arrivare un processo con delle istruzioni e non sa queste istruzioni che gli arrivano a quali thread appartengono e quindi quando vede arrivare un'istruzione di I/O il SO interromperà tutto il processo, in questo modo si vanno a perdere i vantaggi del multi thread.
Nel caso in esame infatti se supponiamo di avere un processo abbiamo che nei sistemi che fanno I/O
Il processo andrà a fare poca CPU e poi si blocca. In questo caso, invece, dovremmo avere le condizioni per utilizzare tutto il quanto di tempo della CPU. Però, se abbiamo uno scheduler solo ad User Level, questo non va bene perché appena un thread invoca la system call, tutto il processo viene ad essere bloccato. Questo perché lo scheduler vede che c'è una system call e la system call fa sì che avvenga il context switch tra i processi e questo processo viene in qualche modo salvato e viene ripristinato un altro processo.
Lo schema User Level ha quindi certamente dei vantaggi che sono importanti come un minor overhead di gestione, lo scheduler che è tipicamente quello cooperativo che è quello più efficiente che esiste, ma anche una certa portabilità delle applicazioni perché, data una libreria multithread a livello utente, la possiamo andare a portare su diversi SO. Lo svantaggio, come visto, è che se un thread si blocca...
verrà a bloccarsi tutto il processo, questa cosa è ancora più grave nelle architetture multi processore dove effettivamente si ha un'architettura multicore e si cerca ancora di massimizzare il parallelismo e la concorrenza per avere un'efficienza ancora maggiore. Per superare questi svantaggi bisogna far sì che il kernel abbia coscienza dei thread. Nel livello Kernel per cercare di sfruttare al massimo l'efficienza di utilizzo della CPU vengono ad essere visti i thread. Nel caso in esame abbiamo un processo che ha 3 thread, questi thread corrispondono a 3 thread Kernel e lo scheduler in questo caso non gestirà il processo ma gestirà i thread e quindi quando un thread invocherà una system call lo scheduler non lo interromperà ma semplicemente switcherà all'altro thread. Il vantaggio che ne deriva sta in un vantaggio di context switch in quanto quando eseguiamo un processo lo spazio di indirizzamento cambia.cambia tutta la cache, bisogna andare a caricare un'altra parte proprio di memoria, bisogna andare a svuotare i registri del processore ed andare a caricare tutto il PCB.
In questo caso invece abbiamo che l'unica cosa che si fa è andare a salvare lo stack del Kernel, il nuovo PC e si è pronti per l'esecuzione. È vero allora che il context switch di thread a livello Kernel è più pesante del context switch a livello utente, però non è paragonabile alla pesantezza del context switch dei processi.
La soluzione che prevede i thread a livello Kernel è una soluzione che presenta molti vantaggi e che cerca di andare incontro ad avere un sistema efficiente e per tale ragione è la soluzione che viene ad essere adoperata da quasi tutti i SO soprattutto se un thread del processo invoca una system call, soltanto quel thread verrà ad essere bloccato e non l'intero processo perché il SO schedulerà un
altro thread e quindinon vi è lo svantaggio del context switch tra i processi. 198Nella pratica, in tutti i sistemi contemporanei vengono ad essere adoperati approcci combinati con l'uso siadi thread a livello utente che thread a livello Kernel.Uno dei primi SO che utilizzò un approccio combinato fu Solaris. 199Il funzionamento di un approccio combinato come ad esempio avveniva in Solaris prevedeva la presenza diuno scheduler dei thread, in ogni processo vi era la possibilità di definire più thread ad esempio nel caso inesame ne consideriamo 5 e di questi thread vi era uno scheduler di livello utente, questo scheduler essendoa livello utente era molto efficiente. Lo scheduler schedulava thread di livello utente in processori virtualiche prendevano il nome di LWP (Light Weight Process) questi non erano altro che delle struct in C che daun lato mappavano i thread livello utente e dall'altro un thread livello Kernel, era inoltre possibile
perapplicazioni Real Time far corrispondere un thread utente con un LWP. Se ad esempio non si voleva passaresullo scheduler e si volvano avere più prestazioni, il thread lo si poteva andare a mappare direttamente sulLWP invece che sullo scheduler, lo scheduler a questo punto andava a mappare tutto il resto sugli altri LWPrimanenti. Per evitare fenomeni di saturazione e proteggere il Kernel da attacchi di Denaied of Serviceaccadeva che il Kernel aveva un pull di LWP e quindi si aveva un numero finito di LWP per il Kernel, ogniprocesso che veniva eseguito faceva una richiesta di LWP, se gli LWP erano disponibili il Kernel li davaaltrimenti il Kernel faceva permanere il processo in uno stato NEW e non lo passava in READY.Lo scheduler di Solaris andava allora a schedulare i LWP e alcuni LWP potevano addirittura essere delKernel e a questo punto si riuscivano ad avere tutti i vantaggi dello scheduler Kernel. Se in questi LWP erapresente una system call lo scheduler cercava diSchedulare sempre un LWP appartenente allo stesso processo, se tutti i LWP di uno stesso processo erano in uno stato BLOCKED lo scheduler decideva di cambiare processo. Era allora compito dello scheduler andare a decidere se fare context switch tra thread o context switch tra processi.
N.B LWP li possiamo pensare come un uncino che collega il thread utente ai thread Kernel. LWP è una struct in C dove la prima parte è la parte del PCB del thread Utente mentre la seconda parte è la parte del PCB del thread Kernel. LWP è quindi soltanto un meccanismo di collegamento per mantenere disaccoppiati i thread Utente a livello Kernel. È come se quando viene creato un thread a livello Utente, questo non venga mappato fisicamente sul thread a livello Kernel. Altrimenti, quello che potrebbe accadere se ad esempio facciamo un programma con 1000 thread ed uno con 1 solo è che il primo si può "fregare" tutto il Kernel. Invece, in questo modo
Si può creare un programma con p thread e poi è possibile specificare in alcuni sistemi quanti LWP si vogliono mentre in altri questi vengono ad essere assegnati direttamente. 200.NB Possono esistere thread Utente che non sono collegati a thread Kernel ma in questo caso il processo non può essere in stato READY (PRONTO) e quindi non può essere schedulato e non potrà essere assegnato un LWP a questo processo. Se il Kernel non ha LWP da assegnare al processo abbiamo che il processore risulterà essere bloccato in attesa che si liberino LWP. 201. Esistono anche alcuni SO in cui è possibile che un thread abbia M processi ma questi sono casi singolari che non saranno argomento di questo corso di studio. Linux supporta i thread a partire dalla versione 2.6, Linus Torbas non amava l'uso dei thread a livello Kernel e li chiamava tasks a livello Kernel però poi si dovette adeguare in quanto si ha un'efficienza maggiore con la struttura.
vista sopra.In Linux 2.6 c'era una libreria che prendeva il nome di Thread Native Library dopodiché è stata una PosixStandard che ha permesso a Linux di avere il concetto di thread.Poiché a Linus non piaceva questa cosa i thread a livello SO vengono creati con una chiamata di sistema chesi chiama clone() e sostanzialmente clone () fa una replica del PCB, ovviamente la replica che viene adessere fatta non è una replica fisica ma una replica che si porta con sé dei puntatori e fornisce un altro PCBche ha tutto uguale al processo tranne la parte dello stack e presenta poi un nuovo campo che si chiamathread ID.Linus quindi arrivò a riconoscere i thread ma li continuò a trattare come processi. 202Windows è molto simile allo schema disegnato sopra soltanto che il mapping non è fatto attraverso lestrutture viste ma attraverso delle strutture che per funzionalità sono del tutto equivalente alle LWP viste.203Nel
linguaggio Java abbiamo che la Virtual Machine non gestisce processi ma thread. Poi, a seconda di come è implementata la VM, tutto può essere visto come una serie di processi o thread. In Java è possibile fare solo programmi multi-threaded.