X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=prochand.tex;h=4bb15c65003e9fa563cdb18c427f77ad092e6efa;hp=48af070bd1e6a7980b68b773fb3737c5ddfbd424;hb=32564231c62ef917086f71a223a1847c859edf0e;hpb=65a5b6a82bdcfeefa6ebc270fe759f3a38560d33 diff --git a/prochand.tex b/prochand.tex index 48af070..4bb15c6 100644 --- a/prochand.tex +++ b/prochand.tex @@ -132,21 +132,22 @@ riprese), \end{figure} -Come accennato in \secref{sec:intro_unix_struct} è lo \textit{scheduler} che -decide quale processo mettere in esecuzione; esso viene eseguito ad ogni -system call ed ad ogni interrupt,\footnote{più in una serie di altre - occasioni. NDT completare questa parte.} (ma può essere anche attivato -esplicitamente). Il timer di sistema provvede comunque a che esso sia invocato -periodicamente, generando un interrupt periodico secondo la frequenza -specificata dalla costante \macro{HZ}, definita in \file{asm/param.h}, ed il -cui valore è espresso in Hertz.\footnote{Il valore usuale di questa costante è - 100, per tutte le architetture eccetto l'alpha, per la quale è 1000. Occorre - fare attenzione a non confondere questo valore con quello dei clock tick - (vedi \secref{sec:sys_unix_time}).} +Come accennato in \secref{sec:intro_unix_struct} è lo +\textit{scheduler}\index{scheduler} che decide quale processo mettere in +esecuzione; esso viene eseguito ad ogni system call ed ad ogni +interrupt,\footnote{più in una serie di altre occasioni. NDT completare questa + parte.} (ma può essere anche attivato esplicitamente). Il timer di sistema +provvede comunque a che esso sia invocato periodicamente, generando un +interrupt periodico secondo la frequenza specificata dalla costante +\macro{HZ}, definita in \file{asm/param.h}, ed il cui valore è espresso in +Hertz.\footnote{Il valore usuale di questa costante è 100, per tutte le + architetture eccetto l'alpha, per la quale è 1000. Occorre fare attenzione a + non confondere questo valore con quello dei clock tick (vedi + \secref{sec:sys_unix_time}).} %Si ha cioè un interrupt dal timer ogni centesimo di secondo. -Ogni volta che viene eseguito, lo \textit{scheduler} effettua il calcolo delle -priorità dei vari processi attivi (torneremo su questo in +Ogni volta che viene eseguito, lo \textit{scheduler}\index{scheduler} effettua +il calcolo delle priorità dei vari processi attivi (torneremo su questo in \secref{sec:proc_priority}) e stabilisce quale di essi debba essere posto in esecuzione fino alla successiva invocazione. @@ -459,15 +460,15 @@ Go to next child Esaminiamo questo risultato: una prima conclusione che si può trarre è che non si può dire quale processo fra il padre ed il figlio venga eseguito per primo\footnote{a partire dal kernel 2.5.2-pre10 è stato introdotto il nuovo - scheduler di Ingo Molnar che esegue sempre per primo il figlio; per - mantenere la portabilità è opportuno non fare comunque affidamento su questo - comportamento.} dopo la chiamata a \func{fork}; dall'esempio si può notare -infatti come nei primi due cicli sia stato eseguito per primo il padre (con la -stampa del \acr{pid} del nuovo processo) per poi passare all'esecuzione del -figlio (completata con i due avvisi di esecuzione ed uscita), e tornare -all'esecuzione del padre (con la stampa del passaggio al ciclo successivo), -mentre la terza volta è stato prima eseguito il figlio (fino alla conclusione) -e poi il padre. + scheduler\index{scheduler} di Ingo Molnar che esegue sempre per primo il + figlio; per mantenere la portabilità è opportuno non fare comunque + affidamento su questo comportamento.} dopo la chiamata a \func{fork}; +dall'esempio si può notare infatti come nei primi due cicli sia stato eseguito +per primo il padre (con la stampa del \acr{pid} del nuovo processo) per poi +passare all'esecuzione del figlio (completata con i due avvisi di esecuzione +ed uscita), e tornare all'esecuzione del padre (con la stampa del passaggio al +ciclo successivo), mentre la terza volta è stato prima eseguito il figlio +(fino alla conclusione) e poi il padre. In generale l'ordine di esecuzione dipenderà, oltre che dall'algoritmo di scheduling usato dal kernel, dalla particolare situazione in si trova la @@ -1837,9 +1838,10 @@ quando si definisce \macro{\_POSIX\_SOURCE} o si compila con il flag \label{sec:proc_priority} In questa sezione tratteremo più approfonditamente i meccanismi con il quale -lo \textit{scheduler} assegna la CPU ai vari processi attivi. In particolare -prenderemo in esame i vari meccanismi con cui viene gestita l'assegnazione del -tempo di CPU, ed illustreremo le varie funzioni di gestione. +lo \textit{scheduler}\index{scheduler} assegna la CPU ai vari processi attivi. +In particolare prenderemo in esame i vari meccanismi con cui viene gestita +l'assegnazione del tempo di CPU, ed illustreremo le varie funzioni di +gestione. \subsection{I meccanismi di \textit{scheduling}} @@ -1857,8 +1859,8 @@ contrario di altri sistemi (che usano invece il cosiddetto \textit{cooperative multitasking}) non sono i singoli processi, ma il kernel stesso a decidere quando la CPU deve essere passata ad un altro processo. Come accennato in \secref{sec:proc_hierarchy} questa scelta viene eseguita da una sezione -apposita del kernel, lo \textit{scheduler}, il cui scopo è quello di -distribuire al meglio il tempo di CPU fra i vari processi. +apposita del kernel, lo \textit{scheduler}\index{scheduler}, il cui scopo è +quello di distribuire al meglio il tempo di CPU fra i vari processi. La cosa è resa ancora più complicata dal fatto che con le architetture multi-processore si deve anche scegliere quale sia la CPU più opportuna da @@ -1986,16 +1988,17 @@ viene assegnato ad un altro campo della struttura (\var{counter}) quando il processo viene eseguito per la prima volta e diminuito progressivamente ad ogni interruzione del timer. -Quando lo scheduler viene eseguito scandisce la coda dei processi in stato -\textit{runnable} associando, sulla base del valore di \var{counter}, un peso -a ciascun processo in attesa di esecuzione,\footnote{il calcolo del peso in - realtà è un po' più complicato, ad esempio nei sistemi multiprocessore viene - favorito un processo che è eseguito sulla stessa CPU, e a parità del valore - di \var{counter} viene favorito chi ha una priorità più elevata.} chi ha il -peso più alto verrà posto in esecuzione, ed il precedente processo sarà -spostato in fondo alla coda. Dato che ad ogni interruzione del timer il -valore di \var{counter} del processo corrente viene diminuito, questo assicura -che anche i processi con priorità più bassa verranno messi in esecuzione. +Quando lo scheduler\index{scheduler} viene eseguito scandisce la coda dei +processi in stato \textit{runnable} associando, sulla base del valore di +\var{counter}, un peso a ciascun processo in attesa di esecuzione,\footnote{il + calcolo del peso in realtà è un po' più complicato, ad esempio nei sistemi + multiprocessore viene favorito un processo che è eseguito sulla stessa CPU, + e a parità del valore di \var{counter} viene favorito chi ha una priorità + più elevata.} chi ha il peso più alto verrà posto in esecuzione, ed il +precedente processo sarà spostato in fondo alla coda. Dato che ad ogni +interruzione del timer il valore di \var{counter} del processo corrente viene +diminuito, questo assicura che anche i processi con priorità più bassa +verranno messi in esecuzione. La priorità di un processo è così controllata attraverso il valore di \var{nice}, che stabilisce la durata della \textit{time-slice}; per il @@ -2138,11 +2141,11 @@ quando si lavora con processi che usano priorit shell cui si sia assegnata la massima priorità assoluta, in modo da poter essere comunque in grado di rientrare nel sistema. -Quando c'è un processo con priorità assoluta lo scheduler lo metterà in -esecuzione prima di ogni processo normale. In caso di più processi sarà -eseguito per primo quello con priorità assoluta più alta. Quando ci sono più -processi con la stessa priorità assoluta questi vengono tenuti in una coda -tocca al kernel decidere quale deve essere eseguito. +Quando c'è un processo con priorità assoluta lo scheduler\index{scheduler} lo +metterà in esecuzione prima di ogni processo normale. In caso di più processi +sarà eseguito per primo quello con priorità assoluta più alta. Quando ci sono +più processi con la stessa priorità assoluta questi vengono tenuti in una coda +tocca al kernel decidere quale deve essere eseguito. Il meccanismo con cui vengono gestiti questi processi dipende dalla politica di scheduling che si è scelto; lo standard ne prevede due: