giovedì 29 novembre 2007

I Processi

Questo è un argomento che non riguarda solamente Unix, e derivati, ma l'informatica in generale. Ormai tutti, o quasi, i sistemi operativi sono multitasking, e quindi gestiscono i processi.
Cercherò di essere il più possibile chiaro per chiunque, a costo anche di commettere qualche imprecisione.

Programma:
Prima di addentrarci oltre ci viene utile, per poi capirci meglio, darci una "definizione" di cos'è un programma. Possiamo considerare un programma come: una sequenza, logicamente ordinata, di semplici operazioni, che un calcolatore è in grado di eseguire, che descrive un modo per ottenere un dato output partendo da un dato input.
Ad un informatico questa definizione balorda farebbe venire la pelle d'oca per la sua imprecisione. In realtà a noi non serve, per il momento, una definizione "assoluta" e rigorosa di programma. Ci basta arrivare ad un punto di partenza comune per poi continuare il nostro discorso. A questo punto ci viene in aiuto il famoso discorso della ricetta, che poi ci porteremo dietro per continuare a capirci. Consideriamo il programma come una ricetta di cucina. La ricetta/programma è un'entità statica, se ne stà lì, sul suo foglio che potremmo paragonare al file o alla scheda perforata, ad aspettare che qualcuno la esegua. A questo punto noi che seguiamo/eseguiamo la ricetta potremmo essere paragonati al sistema/calcolatore. Se la ricetta comprendesse delle uova, una frittata ad esempio, noi potremmo pensare queste uova come dei dati. Notiamo che le uova non stanno sul foglio, infatti la ricetta ci dice che ci servono dei dati del tipo uovo, i dati veri sono le uova che noi estraiamo dal frigo. Notiamo anche che noi, per fare la frittata, non mettiamo le uova (uova dato effettivo intento, quelle fisiche) nel foglio della ricetta e, come per magia, ne esce una frittata. Noi, che siamo il sistema, prendiamo le uova e seguiamo le istruzioni della ricetta. La ricetta è una serie di istruzioni, logicamente ordinate, che noi seguiamo per produrre, a partire dal nostro input uova, il nostro output frittata.
Il programma è come una ricetta di cucina.

Il Time Sharing:
Letteralmente la "condivisione del tempo". A livello umano sembra una cosa tanto ovvia da sembrare assurda e insensata.
Un calcolatore (o computer, come preferite) è composto da diverse parti:
  • Processore (ALU)
  • Memoria (RAM)
  • Dispositivi esterni o periferiche
Nei dispositivi esterni vanno a cadere anche: dischi rigidi, schermi, floppy, lettori ottici, schede audio, ecc... Insomma non solo la "roba" che stà al di fuori del case. Tutti i computer sono infatti basati su uno stesso schema: La macchina di Von Neumann. Anche se in questa astrazione si elencano a volte anche le unità di Input/Output, la macchina è costituita nel suo intimo solo da processore e memoria. La forza di questa macchina è proprio nella sua semplicità!

Non perdiamoci e vediamo di focalizzare il problema dei tempi. Non tutte le parti del calcolatore sono veloci allo stesso modo: il primato spetta al processore, poi viene la memoria (solo RAM intendiamo) e infine tutte le periferiche. Anche se fra le varie periferiche ci possono essere notevoli differenze di velocità per il processore questo non conta. Qualsiasi periferica, anche la più veloce, è talmente lenta rispetto al cuore della macchina che non differenza.

Vediamo ora cosa un programma quando gira:
  • dei calcoli sui dati che ha a disposizione
  • Acquisisce dati (Input).
  • Emette dei dati (Output).
  • Scrive e legge dalla Memoria (RAM).
Fare dei calcoli massivi vuol dire fruttare bene la macchina. Leggere e scrivere dalla memoria "rallenta" un poco le operazioni ma è ancora accettabile e comunque indispensabile (gli informatici potrebbero avere da ridire; avete ragione ma certo non scrivo ste robe per voi!). Le operazioni di Input/Output sono talmente lente da costringere il processore a tempi morti scandalosi. Queste pause forzate sono talmente lunghe che il processore potrebbe tranquillamente eseguire la parte di calcolo di un'altro programma o più. Ed ecco l'ideona. Sospendere l'esecuzione di un programma in attesa di I/O e cominciare, o continuare, l'esecuzione di uno che invece deve sfruttare a pieno la CPU.

Ecco cosa si intende per Time Sharing: lo sfruttamento intelligente e massimizzato del tempo della CPU. Questo rendimento alto lo si ottiene facendo eseguire ad un processore un certo numero di programmi contemporaneamente. Ovviamente una singola CPU esegue il codice di un programma alla volta, ma cambia programma ogni volta che quello che stà eseguendo richiede un lento I/O. Più programmi condividono la stessa CPU.
e.g.: in questo momento 109 programmi si stanno dividendo il tempo della mia CPU. Stò fruttando le capacità del processore ad un 15% scarso. Non ho un supercomputer, anzi!
Torniamo al nostro esempio della ricetta culinaria:
Stiamo eseguendo la ricetta/programma "pastasciutta". Ad un certo punto ci troviamo ad eseguire l'operazione "fare bollire l'acqua". Se non adottassimo il Time Sharing staremmo li a girarci i pollici davanti alla pentola sul fuoco per buoni 20 minuti. Tempo sprecato visto che noi dopo dobbiamo eseguire la ricetta "frittata". Allora decidiamo di puntare il timer del forno e di dedicarci alle nostre uova. Tanto in 20 minuti ci portiamo bene avanti con la frittata. Poi, al suonare del timer, buttiamo la pasta e mescoliamo e ci tocca "aspettare" ancora, allora andremo avanti con la frittata. Oggi vanno tanto di moda i programmi televisivi dedicati alla cucina, osservate uno chef dei tanti che appaiono in TV e vedrete che realizza un Time Sharing molto spinto.

Processo:
Adesso però ci serve fare una distinzione fra programma e "programma in esecuzione". Se prima davamo in pasto alla CPU un programma alla volta questa distinzione non aveva senso. Adesso invece dobbiamo distinguere tra la sequenza di istruzioni presente sul disco (o su un supporto qualsiasi) e quell'entità, attiva e vitale, che gira sul sistema di cui il programma è una parte. Sia ben chiaro che la distinzione non è mera filosofia informatica, ci sono delle precise necessità tecniche che ci portano a farla:
  • Il "set" di dati che un "programma in esecuzione" si porta appresso.
  • Il "punto" dell'esecuzione al quale siamo arrivati.
  • Quale input e quale output ci ha costretti a cambiare programma.
Questa è una lista volutamente semplicistica, ma già rende l'idea.
Ed ecco che con il Time Sharing compare una nuova entità: il processo. Da ora in poi non parleremo più di "programma che gira" su un sistema, ma di processo che, girando sul sistema, esegue un programma. Ad ogni processo è associato un programma da eseguire. Il sistema gestisce i processi. Un processo è composto da molte altre cose oltre che dal programma. Per fare un esempio i dati. Vi sarà capitato sicuramente di eseguire due processi che usano lo stesso programma. Capita spesso con i browser web. Se vi trovate con una marea di finestre aperte dello stesso programma avete davanti agli occhi un esempio di molti processi, uno per finestra, che eseguono lo stesso programma. Infatti sul disco avete un solo file eseguibile del vostro browser preferito. Allora cosa cambia? Cambia l'indirizzo web che avete specificato (input) e la pagina che il browser vi mostra (output). A questo punto è legittimo, e giusto, pensare che i vari processi eseguano lo stesso programma trattando però un set di dati diversi. Ed è importante che il sistema operativo si ricordi quale processo a chiesto la tale pagina, sarebbe fastidioso digitare su una finestra e vedere che la pagina si apre su un'altra a caso. Eppure se ci si riferisse al programma non si avrebbe modo di distinguere le sue varie istanze in esecuzione. Ma questa è già un visione paradossalmente ottimistica. In realtà le cose sono ben più complesse. Ogni processo è ad un punto diverso dell'esecuzione del programma, anche se il programma è lo stesso. Bisogna anche che un processo si ricordi dove è arrivato ad eseguire il programma.

Ritorniamo in cucina:
Quando il timer del forno suona dobbiamo ricordarci che eravamo arrivati al punto "butare la pasta nell'acqua", ad esempio, e non a quello "aggiungere sale".
Se stiamo anche cucinando due frittate diverse, una con gli spinaci e una con piselli e tonno (che vada giù na roba del genere?), dobbiamo ricordarci quali sono gli ingredienti che associamo ad una esecuzione e quali all'altra della stessa ricetta, onde evitare di fare macelli all'istruzione comune: "aggiungere gli ingredienti a vostra scelta".

Scendere nei particolari di cosa , e come, un processo richiederebbe molto tempo e molte parole. Per arrivare fin nell'intimo di come si realizza il Time Sharing bisognerebbe partire da lontano ed affrontare un sacco di problemi. Basti sapere che ancora oggi si cercano vie nuove e sempre più efficaci. Non tutti i sistemi usano la stessa identica filosofia/metodologia. Non mi sembra il caso ora. Spero comunque che siamo riusciti a farci un'idea generale.

Nessun commento:

Posta un commento