Programmazione concorrente Linux
Programmazione concorrente La concorrenza è una caratteristica dei sistemi di elaborazione nei quali può verificarsi che un insieme di processi o sottoprocessi (thread) sia in esecuzione nello stesso istante. Un'importante classe di sistemi informatici nei quali gli aspetti di concorrenza sono fondamentali è quella dei sistemi operativi. Si può parlare di concorrenza nel caso di: parallelismo reale di esecuzione (nel caso di sistemi multiprocessore dove si possono eseguire parallelamente un numero di processi pari al numero di processori) parallelismo virtuale di esecuzione (come nel caso del pipelining). Wikipedia
Clonazione dei processi Linux ha ereditato da Unix la funzione API fork che permette di clonare il processo che la invoca. Viene creato un nuovo processo con un PID (Process Identifier) differente. Le pagine di memoria del codice sono condivise Le pagine di memoria dei dati sono duplicate
fork Per permettere di distinguere nel codice il Processo Padre dal Processo Figlio la funzione fork restituisce un valore intero: <0 condizione di errore 0 restituito al processo figlio >0 restituito al processo padre /è il PID del figlio) #include <unistd.h>
int pFiglio,pPadre,mioPID,s; pPadre = getpid(); //PID del processo padre printf(“PID padre %i”,pPadre); pFiglio = fork(); if (pFiglio<0) //errore return; if (pFiglio>0) { //processo padre … wait(&s); // attesa termine processo figlio return; } else { // processo figlio mioPID = getpid();
wait La funzione API wait attende la conclusione del processo figlio L’argomento passato ritorna lo stato del figlio al momento della terminazione. #include <sys/wait.h>
Evoluzione dei processi
Esercitazione Caricare un array molto grande con valori casuali poi visualizzare gli indici degli elementi con valore uguale a quello ricevuto in input Il processo padre clona un processo figlio che ricerca nella prima parte dell’array mentre il processo padre ricerca nella seconda parte L’output deve precedere il PID del processo e l’indice dell’elemento Seconda versione ogni processo a sua volta esegue una fork per suddividere la ricerca con un ulteriore processo figlio
Copy on write Per ottimizzare la gestione della memoria e la velocità nell’esecuzione di una fork (clonazione di un processo) le pagine della memoria non vengono inizialmente duplicate. La copia di ogni dato avviene solo quando uno dei due processi (padre o figlio) lo modifica e si rende quindi necessario differenziare la copia relativa al processo padre da quella relativa al figlio.