Programmi e Processi in Linguaggio C
In questa lezione vedremo la differenza tra programma e processo in linguaggio C e come un programma viene caricato in memoria per diventare un processo.
Distinzione tra Programma e Processo
In informatica, i termini programma e processo sono spesso usati come sinonimi, ma in realtà rappresentano due concetti differenti.
Quando si programma in C, è necessario conoscere la differenza tra questi due concetti per comprendere appieno il funzionamento di un programma. Il motivo sta nel fatto che, essendo il C un linguaggio di programmazione di basso livello, il programmatore ha il controllo totale sulle risorse del sistema, compresa la memoria.
Per questo motivo, abbiamo pensato di dedicare una lezione a questo argomento, prima di proseguire con le lezioni più avanzate.
Programma
Un programma è un insieme di istruzioni scritte in un linguaggio di programmazione, come il C, che vengono eseguite da un computer.
Quando noi scriviamo codice C, stiamo in effetti scrivendo istruzioni in un linguaggio comprensibile da un essere umano, ma non dal processore del computer. Per questo motivo, è necessario compilare il codice sorgente in un programma eseguibile, che il processore sarà in grado di eseguire.
In ogni caso, anche il programma eseguibile è comunque un insieme di istruzioni.
In altre parole, un programma è un'entità passiva, che risiede sul disco del computer e aspetta di essere eseguita. Un programma non ha uno stato.
Programma
Un programma è un insieme di istruzioni scritte in un linguaggio di programmazione, come il C, potenzialmente eseguibili da un computer.
Un programma non ha uno stato.
Processo
Un processo, invece, è un'istanza di un programma in esecuzione.
Analizziamo la frase di sopra:
-
Un'istanza di un programma:
Significa che un processo è una copia del programma, che viene caricata in memoria e viene eseguita dal sistema operativo.
Un computer, infatti, non può eseguire direttamente un programma che risiede sul disco. Prima, il programma deve essere caricato in memoria e poi eseguito dal processore.
Inoltre, possiamo eseguire un programma più volte, anche contemporaneamente. Per cui, di uno stesso programma possono esistere più processi.
Si pensi, ad esempio, a quando si apre più volte lo stesso programma sul computer. Ogni copia del programma è un processo.
-
In esecuzione:
Un processo è un'entità attiva, che sta eseguendo le istruzioni del programma.
Come abbiamo detto sopra, ogni processo ha una propria copia del programma in esecuzione e, pertanto, ogni processo potrebbe trovarsi ad un punto diverso del programma.
Detto in altre parole, un processo ha uno stato.
Lo stato è rappresentato dal contenuto attuale delle variabili del programma, quindi dal contenuto attuale in memoria, e dal punto in cui si trova l'esecuzione del programma.
La differenza sta proprio in questo: un programma è un'entità passiva, mentre un processo è un'entità attiva con uno stato.
Processo
Un processo è un'istanza di un programma in esecuzione.
Un processo è un'entità attiva con uno stato ossia con un contenuto attuale in memoria e un punto di esecuzione.
Processi e Memoria
Un programma è un insieme di istruzioni, ma per essere eseguito e diventare quindi un processo, deve essere caricato in memoria.
Il compito di caricare un programma in memoria per poter essere eseguito è svolto dal sistema operativo. Questa procedura è nota come caricamento del programma ed è svolta da un componente del sistema operativo che prende il nome di loader.
Per studiare il linguaggio C, non ci interessa tanto sapere come funziona il processo di caricamento. Piuttosto, è fondamentale sapere cosa accade dopo che il programma è stato caricato in memoria. Infatti, il loader non si limita a caricare semplicemente le istruzioni in memoria.
Dopo che un programma è stato caricato in memoria, il sistema operativo riserva delle aree di memoria al processo che prendono il nome di segmenti.
I segmenti sono delle porzioni di memoria che vengono riservate per contenere le varie parti di un programma. In particolare, un processo è composto da quattro segmenti principali:
- Testo (text segment o
.text
): contiene le istruzioni del programma; - Dati (data segment o
.data
): contiene le variabili globali e le variabili statiche; - Stack (stack segment o
.stack
): contiene le variabili locali e i dati relativi alle chiamate di funzione; - Heap (heap segment o
.brk
): contiene le variabili dinamiche allocate durante l'esecuzione del programma.
Schematicamente, possiamo rappresentare la memoria di un processo come in figura:
Il segmento testo contiene le istruzioni del programma, mentre il segmento dati contiene le variabili globali e le variabili statiche. Questi due segmenti sono gli unici segmenti la cui dimensione è nota a priori, in quanto dipende dal codice sorgente del programma.
Viceversa, la dimensione dei segmenti stack e heap è variabile e dipende dall'esecuzione del programma. In particolare, come vedremo, il segmento stack cresce verso il basso, mentre il segmento heap cresce verso l'alto. Questo significa che, durante l'esecuzione del programma, questi due segmenti possono crescere e diminuire di dimensione.
Lo scopo dello stack e dell'heap è fondamentale ma, adesso, è prematuro spiegarne il funzionamento.
Vedremo a cosa serve lo stack quando studieremo le funzioni. Mentre, per l'heap, vedremo a cosa serve quando parleremo di allocazione dinamica della memoria.
Per ora, è importante sapere che un programma, per essere eseguito, deve essere caricato in memoria e diventare un processo. E che un processo è composto da quattro segmenti principali: testo, dati, stack e heap.
In Sintesi
In questa lezione abbiamo visto la differenza tra programma e processo.
Un programma è un insieme di istruzioni scritte in un linguaggio di programmazione, mentre un processo è un'istanza di un programma in esecuzione.
Abbiamo visto che un programma, per essere eseguito, deve essere caricato in memoria e diventare un processo. E che un processo è composto da quattro segmenti principali: testo, dati, stack e heap.
Questi concetti sono fondamentali per comprendere il funzionamento di un programma in C e, in particolare, per capire come vengono gestite le variabili e la memoria.
Nelle prossime lezioni, vedremo come funzionano i segmenti di memoria di un processo e come vengono gestite le variabili locali e globali.