Unix – Processi #1

Unix Logo

Unix Logo

Ultimamente passo decisamente troppi problemi. Troppi casini tutti insieme mi hanno e mi stanno mettendo alla prova i nervi.

Comunque, nei momenti di lucidità le mie deformazioni professionali prendono il sopravvento. Quindi festeggio questo momento di distensione mentale con un altro tassello al muro di slashcode.

Cominciamo quindi a parlare della programmazione di sistema. In questa sede ci occuperemo della programmzaione in ambito Unix. Il motivo è semplice: è quella che conosco meglio e di cui (grazie alle numerose implementazioni aperte) è possibile studiare più in dettaglio il funzionamento. Citerò solamente il nome della funzione analoga per Windows in modo che chi sia interessato possa evere un punto di partenza per ricerche autonome.

Il nostro percorso inizia dai processi.

Come penso tutti sanno, su la quasi totalità dei calcolatori i programmi vengono lanciati dal sistema operativo. Il sistemo operativ, oltre ad avviare il programma, si occupa di alternare fra loro i programmi per dare l’illusione di più programmi in esecuzione contemporanea.

Per fare ciò il SO all’avvio del processo alloca nella sua memoria una struttura dati per memorizzare le informazioni salienti di ogni programma in esecuzione.

Per il SO un programma in esecuzione prende il nome processo. Un processo è in linea di massima composto dal testo del programma e dal suo spazio di memoria.

Fra le informazioni più importanti dal punto di vista del programmatore memorizzate dal SO c’è sicuramente il PID (Process ID). Il PID è un numero intero che identifica univocamente il processo nel SO.

Inoltre ci possiamo chiedere anche chi genera i processi? I processi sono organizzati gerarchicamente in una struttura ad albero: ogni processo (escluso init) ha un padre e ha eventualmente dei figli.

Proviamo questo semplice programma:

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. void main() {
  4. /* Trova e stampa il Process ID del processo corrente */
  5. int pid = getpid();
  6. printf(“%d\n,pid);
  7. /* Trova e stampa il Process ID del processo padre */
  8. int ppid = getppid();
  9. printf(“%d\n,ppid);
  10. }

Questo programma non fa altro che stampare il PID del processo corrente (il programma stesso) e il PID del processo padre che ha generato il processo. Le due funzioni che fanno questo sono rispettivamente getpid e getppid

Ma come si generano i processi?

In unix generare un processo è molto semplice. Si può usare la seguente chiamata di sistema.

int fork()

Questa funzione duplica il processo corrente e restituisce 0 al processo figlio e il PID del figlio al processo padre. Oppure  -1 in caso di fallimento.

Sembra complicato poichè scrivere un programma che si duplica mantenendo lo stesso codice è decisamente fuori norma. L’uso però è semplicemente più intuitivo:

if (fork() == 0) printf("Sono il figlio!");
else printf("Sono il padre!");

Il fork va praticamente sempre inserito in un if per poter determinare se si sta eseguendo il padre o si sta eseguendo il figlio.

Il corrispettivo per window è la CreateNewProcess una funzione con 16 parametri che però permetti di creare direttamente un nuovo processo con un codice diverso da quello del padre.

Come si fa in Unix per sostituire il codice di un processo con quello di un nuovo programma?

Lo vedremo alla prossima dove parleremo della famiglia di funzioni exec.

Comments are closed.