Processi Linux spiegati semplice: cosa succede quando avvii un programma

30 giugno 2026 14 min di lettura

Scopri cosa sono i processi Linux, qual è la differenza tra programma e processo, cosa significa PID, come funzionano fork, exec, scheduler, multitasking, foreground e background.

Processi Linux spiegati semplice: cosa succede quando avvii un programma

Quando usiamo Linux, spesso diciamo frasi come:

“Ho aperto un programma” “Ho lanciato un comando” “Ho avviato un’applicazione”

Dal punto di vista dell’utente è corretto. Scriviamo un comando nel terminale, premiamo Invio e otteniamo un risultato. Oppure facciamo clic su un’icona e si apre un’applicazione.

Ma dal punto di vista del sistema operativo sta succedendo qualcosa di più preciso: Linux sta creando e gestendo un processo.

Capire cosa sono i processi Linux è fondamentale perché molti concetti del sistema operativo passano da qui: kernel, shell, permessi, file, memoria, CPU, segnali, multitasking e servizi.

In questo articolo vediamo in modo semplice:

  • la differenza tra programma e processo;
  • cosa significa PID;
  • cosa sono processo padre e processo figlio;
  • cosa fanno fork() ed exec();
  • a cosa serve lo scheduler;
  • cosa significa context switching;
  • cosa sono foreground e background;
  • cosa sono i segnali;
  • perché Linux riesce a gestire tanti processi contemporaneamente.

L’obiettivo non è imparare subito tutti i comandi, ma costruire una mappa mentale chiara.


Programma e processo: qual è la differenza?

La prima distinzione importante è questa:

un programma non è la stessa cosa di un processo.

Un programma è un file, o un insieme di file, presente sul disco. Può essere un comando, un browser, un editor, uno script, un server web o un database.

Finché quel programma è fermo sul filesystem, è codice pronto per essere eseguito.

Un processo, invece, è un programma mentre è in esecuzione.

Possiamo usare un’analogia semplice:

  • il programma è una ricetta scritta su un foglio;
  • il processo è il cuoco che sta cucinando seguendo quella ricetta.

La ricetta può esistere anche se nessuno cucina. Il processo esiste solo mentre qualcosa sta davvero girando.

Quindi, quando avvii un programma su Linux, il sistema non si limita ad “aprire un file”: crea un processo, gli assegna risorse, lo identifica e lo gestisce.


Cosa succede quando lanci un comando

Immaginiamo di aprire il terminale e lanciare un comando.

La sequenza, semplificata, è questa:

  1. la shell legge il comando;
  2. cerca il programma corrispondente;
  3. chiede al kernel di avviarlo;
  4. il kernel crea un processo;
  5. il processo usa CPU, memoria, file e altre risorse;
  6. quando termina, il risultato torna alla shell.

Questo collega molti concetti già visti nella serie Capire Linux.

Nel primo episodio abbiamo visto che Linux è organizzato a livelli: applicazioni, shell, librerie, system call, kernel e hardware.

Nel secondo episodio abbiamo visto il filesystem: i programmi stanno nel filesystem, così come file, configurazioni, dispositivi e informazioni di sistema.

Nel terzo episodio abbiamo visto i permessi: un utente può eseguire un file solo se ha i permessi corretti.

Il processo nasce proprio dall’incontro di questi elementi: un file eseguibile, un utente, dei permessi, una richiesta della shell e il controllo del kernel.


Cos’è un PID in Linux

Ogni processo Linux ha un PID.

PID significa Process ID, cioè identificativo del processo.

È un numero che Linux usa per distinguere un processo da tutti gli altri.

Questo è essenziale perché su un sistema possono esserci moltissimi processi attivi contemporaneamente:

  • comandi lanciati dall’utente;
  • shell;
  • browser;
  • editor;
  • ambiente grafico;
  • servizi di rete;
  • servizi di sistema;
  • database;
  • processi di login;
  • processi di logging;
  • processi in background.

Senza un identificativo univoco, il kernel non potrebbe gestirli in modo ordinato.

Il PID è quindi come un numero di pratica. Non spiega tutto sul processo, ma permette al sistema di dire: “sto parlando proprio di quel processo”.


Un processo non è solo codice in esecuzione

Quando pensiamo a un processo, non dobbiamo immaginare soltanto il codice del programma.

Un processo Linux ha molte informazioni associate:

  • un PID;
  • un processo padre;
  • uno stato;
  • memoria assegnata;
  • file aperti;
  • eventuali connessioni di rete;
  • variabili d’ambiente;
  • utente proprietario;
  • permessi;
  • segnali ricevuti;
  • risorse utilizzate.

Questo è importante perché il processo non vive isolato.

Se deve leggere un file, entra in gioco il filesystem. Se deve modificare un file, entrano in gioco i permessi. Se deve usare la CPU, entra in gioco lo scheduler. Se deve comunicare con un dispositivo, passa attraverso il kernel.

Il processo è quindi uno dei punti centrali in cui si incontrano le varie parti di Linux.


Processo padre e processo figlio

In Linux i processi possono creare altri processi.

Il processo che crea viene chiamato processo padre. Il processo creato viene chiamato processo figlio.

Un esempio semplice è la shell.

Quando apri un terminale, hai una shell in esecuzione. Se da quella shell lanci un comando, spesso la shell crea un processo figlio per eseguire quel comando.

La shell resta attiva. Il comando viene eseguito come processo separato.

Questa relazione padre-figlio è fondamentale perché i processi Linux non sono entità casuali. Formano una struttura ordinata.

Un processo può avere figli. Quei figli possono avere altri figli. Il risultato è un vero e proprio albero dei processi.


L’albero dei processi

Possiamo immaginare i processi Linux come un albero.

Alla base ci sono i processi iniziali del sistema. Da questi possono nascere servizi, shell, sessioni utente e applicazioni. Ogni processo può generare nuovi processi.

Questa struttura è utile per capire molte situazioni.

Per esempio:

  • una shell può avviare un comando;
  • uno script può avviare più comandi;
  • un servizio può generare processi di lavoro;
  • un ambiente grafico può avviare applicazioni;
  • un server web può creare processi per gestire richieste.

Linux mantiene traccia di queste relazioni.

Non gestisce solo “programmi aperti”, ma una gerarchia di processi con stati, risorse e rapporti precisi.


fork() spiegata semplice

Uno dei concetti più importanti nel mondo Unix e Linux è fork().

fork() è una system call, cioè una chiamata di sistema, usata per creare un nuovo processo.

Detto in modo semplice: quando un processo chiama fork(), chiede al kernel di creare un processo figlio.

Questo processo figlio nasce come una sorta di copia del processo padre.

A livello pratico Linux usa meccanismi efficienti, quindi non dobbiamo immaginare per forza una duplicazione pesante e ingenua di tutto. Ma dal punto di vista concettuale l’idea è questa:

  • esiste un processo padre;
  • il padre chiama fork();
  • nasce un processo figlio;
  • da quel momento padre e figlio possono prendere strade diverse.

L’immagine mentale più semplice è quella di un ramo che si divide in due.

Prima c’è un solo percorso. Dopo fork() ci sono due percorsi.


exec() spiegata semplice

Dopo fork() spesso entra in gioco exec().

exec() serve a sostituire il programma eseguito da un processo con un altro programma.

Il processo resta, ma cambia ciò che sta eseguendo.

Una sequenza molto semplificata può essere questa:

  1. la shell riceve un comando;
  2. la shell crea un processo figlio con fork();
  3. il processo figlio usa exec() per eseguire il programma richiesto;
  4. la shell può attendere il risultato oppure continuare.

Quindi fork() crea un nuovo processo. exec() fa eseguire a quel processo un nuovo programma.

È come creare prima uno spazio di lavoro e poi riempirlo con l’attività corretta.

Questa combinazione è uno dei meccanismi fondamentali con cui Linux avvia programmi.


Il ruolo del kernel nella gestione dei processi

Il kernel è il componente centrale nella gestione dei processi.

Quando un processo nasce, il kernel deve tenerne traccia. Deve sapere:

  • qual è il suo PID;
  • chi è il processo padre;
  • quale utente lo ha avviato;
  • quanta memoria usa;
  • quali file ha aperto;
  • in che stato si trova;
  • se sta usando CPU;
  • se sta aspettando input/output;
  • se deve ricevere segnali;
  • quando termina.

Il kernel non si limita quindi ad avviare programmi. Coordina il modo in cui tutti i processi convivono.

Questo è uno dei motivi per cui Linux è stabile: i programmi girano in user space, ma le operazioni critiche passano attraverso il kernel.


Cos’è lo scheduler Linux

Lo scheduler è la parte del kernel che decide quale processo può usare la CPU e per quanto tempo.

Questa funzione è essenziale perché su un sistema moderno ci sono spesso molti più processi attivi rispetto ai core disponibili.

Anche se un computer ha più core, i processi da gestire sono tanti:

  • alcuni sono pronti a usare la CPU;
  • alcuni aspettano dati da disco;
  • alcuni aspettano la rete;
  • alcuni sono sospesi;
  • alcuni sono in background;
  • alcuni devono rispondere rapidamente all’utente.

Lo scheduler decide chi deve avanzare in un certo momento.

Possiamo immaginarlo come un direttore d’orchestra: non suona ogni strumento, ma coordina l’ingresso dei vari strumenti nel momento giusto.


Multitasking: cosa significa davvero

Linux è un sistema multitasking.

Questo significa che può gestire molte attività contemporaneamente.

Ma “contemporaneamente” non significa sempre che tutte stiano usando la CPU nello stesso identico istante.

Su un sistema con un solo core, la CPU esegue un processo per un brevissimo intervallo, poi passa a un altro, poi a un altro ancora.

Questo avviene così rapidamente che per l’utente sembra che tutto proceda nello stesso momento.

Su sistemi con più core, più processi possono essere realmente eseguiti in parallelo. Ma anche in quel caso serve uno scheduler che coordini il lavoro.

Il multitasking non è magia. È organizzazione.


Context switching: il cambio di contesto

Il context switching è il passaggio da un processo all’altro.

Quando il kernel decide che la CPU deve smettere di eseguire un processo e passare a un altro, deve salvare lo stato del primo processo e caricare lo stato del secondo.

L’analogia più semplice è quella del segnalibro.

Stai leggendo un libro. Ti fermi, metti un segnalibro e passi a un altro libro. Poi più tardi puoi tornare esattamente al punto in cui eri rimasto.

Il kernel fa qualcosa di simile con i processi.

Salva abbastanza informazioni per poterli riprendere correttamente più avanti.

Questo cambio avviene in modo molto rapido ed è una delle basi del multitasking.


Processi pronti, in attesa e terminati

Non tutti i processi attivi stanno usando la CPU.

Questo è un punto importante.

Molti processi passano gran parte del tempo in attesa.

Un editor di testo può aspettare che tu prema un tasto. Un browser può aspettare una risposta dalla rete. Un servizio può restare in ascolto finché non arriva una richiesta. Un comando può aspettare la lettura da disco.

Per questo un processo può trovarsi in stati diversi:

  • pronto per essere eseguito;
  • in esecuzione;
  • in attesa;
  • sospeso;
  • terminato.

Lo scheduler tiene conto di questi stati.

Non ha senso dare CPU a un processo che sta aspettando dati dalla rete. È più utile far avanzare un processo pronto a lavorare.


Processi in foreground

Un processo in foreground è un processo collegato direttamente all’interazione corrente del terminale.

Quando lanci un comando e il terminale resta impegnato finché quel comando non finisce, quel comando sta lavorando in foreground.

In questo caso:

  • la shell aspetta;
  • l’output appare direttamente nel terminale;
  • il processo può ricevere input dalla tastiera;
  • l’utente resta concentrato su quel comando.

È il comportamento più normale e immediato.

Scrivi un comando, aspetti il risultato, poi torni al prompt.


Processi in background

Un processo in background continua a lavorare senza bloccare completamente la shell.

Questo significa che il processo continua la sua attività, ma il terminale torna disponibile per altri comandi.

È utile per attività lunghe o per operazioni che devono continuare mentre fai altro.

La distinzione mentale è semplice:

  • foreground: il processo è davanti a te;
  • background: il processo continua dietro le quinte.

Questa logica è molto importante nel lavoro da terminale e ancora di più nei sistemi server, dove molti processi devono funzionare senza interazione diretta dell’utente.


Processi e terminale

Non tutti i processi sono collegati a un terminale.

Alcuni processi vengono avviati direttamente dall’utente. Altri partono automaticamente quando il sistema si avvia. Altri ancora sono servizi che restano attivi in background.

Su un sistema Linux possono essere in esecuzione processi che gestiscono:

  • rete;
  • audio;
  • login;
  • logging;
  • aggiornamenti;
  • ambiente grafico;
  • database;
  • server web;
  • attività pianificate;
  • strumenti di sistema.

Solo perché non vedi un processo sullo schermo, non significa che non esista.

Molti processi importanti lavorano senza farsi notare.


Cosa sono i segnali in Linux

I segnali sono messaggi inviati ai processi per chiedere o imporre una certa azione.

Un segnale può dire a un processo:

  • interrompiti;
  • termina;
  • sospenditi;
  • riprendi;
  • ricarica la configurazione;
  • gestisci un evento.

Un esempio comune è Ctrl+C nel terminale.

Quando premi Ctrl+C, normalmente invii un segnale al processo in foreground per interromperlo.

Non serve imparare subito tutti i segnali. Il concetto importante è questo: Linux ha un meccanismo standard per comunicare con i processi e modificarne il comportamento.


Terminare un processo

Un processo può terminare in modi diversi.

Può finire normalmente perché ha completato il suo lavoro.

Può terminare perché riceve una richiesta di chiusura.

Può essere interrotto dall’utente.

Può andare in errore.

Quando un processo termina, il kernel deve liberare le risorse associate:

  • memoria;
  • file aperti;
  • riferimenti interni;
  • eventuali strutture collegate;
  • informazioni di stato.

Questo è fondamentale per mantenere stabile il sistema.

Se i processi lasciassero risorse occupate per sempre, il sistema diventerebbe progressivamente più lento e instabile.


Permessi e processi

I permessi non valgono solo per i file fermi sul disco.

Contano anche mentre un processo è in esecuzione.

Quando avvii un processo, quel processo normalmente agisce con l’identità dell’utente che lo ha avviato.

Se sei un utente normale, il processo non può modificare liberamente tutto il sistema.

Per esempio, un editor avviato da un utente normale può modificare i file nella home dell’utente, ma non dovrebbe poter modificare file critici in directory di sistema come /etc, a meno che non venga avviato con privilegi amministrativi.

Questo è un collegamento diretto con il tema della sicurezza.

Un processo non è potente solo perché il programma è complesso. Conta anche con quali privilegi viene eseguito.

Per questo lavorare sempre come root è rischioso.


Processi e /proc

Nel filesystem Linux esiste una directory molto particolare: /proc.

/proc non è una normale cartella piena di documenti salvati su disco. È un filesystem virtuale che espone informazioni dinamiche sul sistema.

Tra queste informazioni ci sono anche quelle sui processi.

Ogni processo può avere una rappresentazione dentro /proc, spesso identificata proprio dal suo PID.

Questo è un ottimo esempio della filosofia Linux: molte informazioni del sistema vengono esposte attraverso un’interfaccia simile a quella dei file.

Quindi /proc collega direttamente due concetti importanti:

  • il filesystem;
  • i processi in esecuzione.

Perché Linux riesce a gestire tanti processi

Linux riesce a gestire tanti processi contemporaneamente grazie a una combinazione di elementi.

Prima di tutto, i processi sono isolati. Un processo non può modificare liberamente la memoria di un altro.

Poi c’è lo scheduler, che decide come assegnare il tempo di CPU.

Poi ci sono gli stati dei processi: Linux sa distinguere chi è pronto, chi sta lavorando, chi è in attesa e chi ha terminato.

Poi ci sono le system call, che permettono ai programmi di chiedere servizi al kernel in modo controllato.

Infine c’è la gestione efficiente di risorse come memoria, file, input/output, rete e segnali.

Il risultato è un sistema capace di far convivere molte attività mantenendo ordine.


Non tutti i processi consumano allo stesso modo

Il numero di processi attivi da solo non dice tutto.

Alcuni processi usano molta CPU, per esempio durante una compilazione, una compressione o un’elaborazione video.

Altri usano molta memoria, come un browser con molte schede aperte o un database.

Altri usano pochissima CPU perché aspettano eventi.

Altri ancora restano quasi sempre fermi e si attivano solo quando serve.

Quindi, quando osservi i processi Linux, devi chiederti:

  • stanno usando CPU?
  • stanno usando memoria?
  • stanno aspettando disco?
  • stanno aspettando rete?
  • sono necessari?
  • sono collegati a un servizio?
  • sono stati avviati dall’utente?

Questa mentalità è fondamentale per fare troubleshooting.


Comandi utili per osservare i processi

Anche se l’obiettivo di questo articolo è spiegare i concetti, vale la pena citare alcuni comandi utili.

Tra i più comuni troviamo:

ps

Mostra un elenco dei processi.

top

Mostra una vista dinamica dei processi e delle risorse.

htop

È una versione più comoda e interattiva di top, se installata.

kill

Invia segnali ai processi. Il nome può trarre in inganno: non significa sempre “uccidere brutalmente”, ma più in generale inviare un segnale.

jobs

Mostra i job collegati alla shell corrente, utile per foreground e background.

Questi comandi diventano più comprensibili se prima hai chiaro cosa sia davvero un processo.


Errori comuni dei principianti

Quando si inizia a usare Linux, sui processi ci sono alcuni errori frequenti.

Il primo è confondere programma e processo. Un programma installato non è necessariamente in esecuzione.

Il secondo è pensare che tutti i processi consumino sempre CPU. In realtà molti processi passano gran parte del tempo in attesa.

Il terzo è terminare processi senza sapere cosa fanno. Alcuni processi sono componenti importanti del sistema.

Il quarto è ignorare i processi in background. Solo perché non occupano il terminale, non significa che non siano attivi.

Il quinto è usare privilegi amministrativi senza motivo. Un processo avviato come root può fare molti più danni di un processo avviato da un utente normale.


I processi sono uno dei concetti centrali di Linux.

Un programma è codice pronto per essere eseguito. Un processo è un programma mentre è in esecuzione.

Ogni processo ha un PID, cioè un identificativo numerico.

I processi possono avere relazioni padre-figlio e formare un albero.

fork() crea un nuovo processo. exec() sostituisce il programma eseguito da un processo.

Lo scheduler decide quale processo usa la CPU e per quanto tempo.

Il context switching permette al kernel di passare rapidamente da un processo all’altro.

Foreground e background descrivono il rapporto tra un processo e l’interazione corrente dell’utente.

I segnali permettono al sistema e all’utente di comunicare con i processi.


Conclusione

Linux non si limita ad aprire programmi.

Linux gestisce processi.

Ogni processo ha una vita: nasce, usa risorse, viene pianificato, può attendere, può ricevere segnali e alla fine termina.

Capire i processi significa capire meglio come lavora il kernel, come si collega la shell al sistema, perché i permessi sono importanti anche durante l’esecuzione e perché Linux riesce a gestire tante attività contemporaneamente.

Nel prossimo episodio della serie Capire Linux faremo il passo successivo: parleremo di servizi e systemd.

Vedremo cosa parte quando accendi Linux, come vengono avviati i servizi di sistema e perché systemd è così importante nelle distribuzioni moderne.