Docsity
Docsity

Prepara i tuoi esami
Prepara i tuoi esami

Studia grazie alle numerose risorse presenti su Docsity


Ottieni i punti per scaricare
Ottieni i punti per scaricare

Guadagna punti aiutando altri studenti oppure acquistali con un piano Premium


Guide e consigli
Guide e consigli


Processi & programmazione concorrente, Dispense di Informatica

Dispensa sui processi con introduzione alla programmazione concorrente nel linguaggio C.

Tipologia: Dispense

2014/2015

Caricato il 23/11/2015

Fabrizio.Cafolla
Fabrizio.Cafolla 🇮🇹

2 documenti

1 / 18

Toggle sidebar

Questa pagina non è visibile nell’anteprima

Non perderti parti importanti!

bg1
4 A INF
Processi & Programmazione Concorrente
Tesina
Fabrizio Cafolla
28/04/2015
Introduzione sui processi e la programmazione concorrente su S.O. Linux in linguaggio C.
Utilizzo di costrutti Fork-Join e Cobegin-Coend.
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12

Anteprima parziale del testo

Scarica Processi & programmazione concorrente e più Dispense in PDF di Informatica solo su Docsity!

4 A INF

Processi & Programmazione Concorrente

Tesina

Fabrizio Cafolla 28/04/

Introduzione sui processi e la programmazione concorrente su S.O. Linux in linguaggio C. Utilizzo di costrutti Fork-Join e Cobegin-Coend.

Pagina 2

LICENZA

Quest'opera è stata rilasciata con licenza Creative Commons

Attribuzione - Non commerciale - Condividi allo stesso modo 4.

Internazionale. Per leggere una copia della licenza visita il sito

web http://creativecommons.org/licenses/by-nc-sa/4.0/

Pagina 4

1. Introduzione Processi

B- Kernel & Scheduling

FCFS ( First Come First Served ) esegue i processi nello stesso ordine in cui essi vengono avviati dal sistema. Il primo processo ad essere eseguito è esattamente quello che per primo richiede l'uso della CPU. Quelli successivi vengono serviti non appena questo ha terminato la propria esecuzione. Questo tipo di algoritmo è molto semplice da implementare ma è anche poco efficiente, almeno considerando il tempo medio d'attesa.

Round-Robin è un particolare algoritmo che esegue i processi nell'ordine d'arrivo, come l' FCFS, ma ad ogni processo assegna un quanto di tempo in base alla grandezza del processo stesso, se un processo termina il quanto di tempo prima ancora di essere terminato viene spostato nello stato di attesa per poi riandare nella pila FCFS.

Le prestazioni di quest'algoritmo sono dunque influenzate dal tempo medio d'attesa sebbene consenta a tutti i processi di ottenere il controllo della CPU ed evita quindi il problema dell'attesa delle risorse HW e SW. È inoltre da tenere in considerazione l'impatto dovuto ai frequenti cambi di contesto (context switch) effettuati.

Priorità è un tipo di algoritmo che assegna a ogni processo un numero intero che corrisponde al livello di priorità con il quale deve essere eseguito. I processi sono inseriti in una coda dove lo scheduler in base alla priorità massima sceglierà il processo da eseguire prima, non tiene conto del tempo di esecuzione del processo.

La priorità viene assegnata dal S.O. in base al tipo di richiesta:

Interna al sistema : ovvero processi di sistema che vengono lanciati dal S.O. e la priorità viene calcolata sulla base delle caratteristiche e del comportamento del processo da eseguire.  Esterna al sistema : processi lanciati dall' utente, il S.O. in base a dei criteri assegna la priorità.

L' algoritmo di priorità può essere di tipo pre-emptive ovvero che permette l'interruzione del processo che è in esecuzione, o di tipo non pre-emptive che non permette l'interrupt.

Esistono altri tipi di algoritmi Scheduling come SJF , MLFQ.

Pagina 5

1.1 Processi

A- Classificazione Processi

La classificazione dei processi si riferisce al modo in cui un processo evolve.

Indipendenti : Sono quei processi che evolvono in modo autonomo, senza necessità di comunicare con altri processi.  Cooperanti : Sono quei processi che evolvono solamente comunicando con altri processi, scambiandosi informazioni necessarie per l' evoluzione del processo.  Competitivi : Sono quei processi che evolvono in modo indipendente, ma che entrano in conflitto con altri processi per l' utilizzo di risorse o dati.

B- Stato dei Processi

Figura 1 Stati dei processi

Un processo è un' entità dinamica che si può trovare in cinque stati differenti.

New (nuovo) è lo stato in cui si trova un processo appena creato.  Ready (pronto) è lo stato per cui il processo viene inserito in base allo scheduler nella lista dei processi pronti detta RL(Ready List).  Running (esecuzione) è lo stato in cui un processo viene prima scelto dalla RL in base all'algoritmo di scheduling, una volta scelto viene eseguito, se l' esecuzione è terminata passa allo stato termined. Se non è terminato può tornare nello stato di ready per via di un' interrupt, oppure se ha necessita di risorse o informazioni passa allo wait.  Waiting (attesa) è lo stato in cui il processo ha bisogno di risorse o informazioni per poter evolvere, oppure ha finito il suo time slice(tempo di esecuzione). Lo stato wait ha una lista detta WS (Waiting List) dove il processo viene inserito per poi passare nuovamente allo stato ready.  Terminated (terminato) quando è finita la sua esecuzione.

Pagina 7

2. Introduzione Programmazione concorrente

A- Cos'è la programmazione concorrente

La programmazione concorrente nacque per sfruttare al meglio le risorse hardware, successivamente trovò utilizzo per aumentare la velocità di esecuzione delle applicazioni poiché da un singolo programma possono nascere N processi in cui ci sarà un padre e a esso saranno collegati i processi figli. Questa caratteristica permette di diminuire i tempi di esecuzione, perchè scompone un programma in N processi, ed ogni processo svolge blocchi di istruzioni differenti.

Perché è importante aumentare la velocità di esecuzione di un’applicazione?Migliorare i tempi di risposta e quindi l’interattività con l’utente.  Risparmiare energia (perché aumenta l’efficienza).  Perché da la possibilità di scomporre in più sotto parti problemi complessi.

Processo Padre è quel processo che crea dei processi figli a partire dal suo codice, conosce il loro PID cosi da poter comunicare e sincronizzare la loro esecuzione.

Processo Figlio è quel processo che è stato creato a partire da un processo padre tramite dei costrutti, è una copia identica del padre solamente che avrà dei compiti differenti da esso, il suo PID è diverso da quello del padre.

B- Processi Orfani

I processi orfani sono tutti quei processi che sono stati creati a partire da un processo padre (es. processo1) che per qualche " evento " termina prima della conclusione dei processi figli (es. processo2-3) in questi casi Linux assegna ai processi rimasti orfani un padre che per convenzione è init.

Pagina 8

2. Introduzione Programmazione concorrente

C- Sistemi concorrenti & Parallelismo

Un S.O. può essere definito :

Sistema sequenziale : quando i processi vengono eseguiti uno per volta e non si verifica alcuna forma di interazione tra essi durante l'esecuzione.  Sistema concorrente :é un modello avanzato che garantisce il parallelismo di processi in esecuzione, questo sistema rispetta la regola che ogni processo pur lavorando in parallelo con altri venga eseguito come se fosse in un sistema sequenziale.

La programmazione concorrente ovviamente può avvenire solamente su sistemi concorrenti, ovvero S.O. che permetto di operare con il parallelismo reale o virtuale.

Parallelismo Virtuale : nel caso di sistemi multiprocessore* dove si possono eseguire parallelamente un numero di processi pari al numero dei processori(core).

Parallelismo Reale : nel caso di sistemi monoprocessore dove è possibile l' esecuzione di un singolo processo in un certo periodo, ma con la possibilità di alternare l'esecuzione di più processi, cosi da elaborare più processi apparentemente in contemporanea.

*Il fenomeno di multitasking si riferisce alla possibilità di svolgere contemporaneamente più processi, questo si verifica quando si ha un multiprocessore ovvero una CPU con più di un core, a sua volta il core può generare uno o due tread in base al tipo di CPU.

Pagina 10

2.1 FORK-JOIN

A- Fork-Join

Il costrutto fork-join è utilizzato per scrivere programmi concorrenti poiché permette la creazione(fork) di un processo figlio da parte del padre e successivamente il loro ricongiungimento(join).

 Il processo figlio è la copia del processo padre quindi ha tutte le istruzioni successive al richiamo della funzione fork(), questo vuol dire che i processi sono identici, quindi il programmatore deve prevedere dei controlli sul PID ed in base a quello far svolgere istruzioni differenti per ogni processo figlio.  Quando si creano processi figli essi vengono eseguiti in maniera parallela(reale o virtuale) ma comunque sia ogni processo viene eseguito in modo sequenziale e in base all'algoritmo di scheduling la CPU esegue N istruzioni del processo, è possibile che vengano eseguite in modo alternato istruzioni di un processo padre e di un processo figlio.  Il costrutto fork-join viene utilizzato in linguaggio C su S.O Linux e su Mac OSx, mentre per Windows il corrispettivo di fork-join è CreateProcess che ha le stesse funzionalità.

La fork determina la creazione di UN nuovo processo(B), che viene eseguito parallelamente al processo padre.

La join permette di ricongiungere due (o più) processi figli al proprio padre(sincronizzazione).

Pagina 11

2.1 FORK-JOIN

B- Metodi fork() - wait() - exit()

Linux per manipolare i processi utilizza delle funzioni già implementate, le principali sono:

creare processo figlio, restituisce un numero di tipo pid_t (è un TDA, num. intero). istruzione fork();  terminare processo , restituisce un codice(è un numero) di terminazione al processo padre. istruzione exit();  sincronizzazione , corrisponde alla join serve a far attendere il padre fino termine del processo figlio. istruzione wait();

Fork() è una funzione che quando viene richiamata in un programma crea a partire da esso un processo figlio che è la copia esatta del padre ma con PID diverso. La fork restituisce sempre un numero intero:

 al processo padre restituisce il PID del figlio cosi che lo riconosca.  al processo figlio restituisce 0.  mentre se restituisce -1 il processo figlio non è stato creato.

Utilizzo nel programma: fork(); non ha parametri, e ritorna un numero intero.

Contenuta nella libreria: #include <unistd.h>

Exit() è una funzione che permette ad un processo figlio di informare un processo padre della sua terminazione e di passare un codice in cui il padre sa che tipo di terminazione è avvenuta. Utilizzo nel programma: exit(int n); parametro intero, e non ritorna nulla.

Contenuta nella libreria: #include <stdlib.h>

Wait() è una funzione che viene utilizzata per sincronizzare il processo padre con il figlio, la wait fa sospendere l'esecuzione del padre fino a quando il figlio non è terminato. Questa funzione restituisce un numero intero che è il PID del figlio, inoltre tramite passaggio per indirizzo fa si che la variabile passata come parametro venga inizializzata con il valore della exit del figlio.

Utilizzo nel programma: *wait(int stuts); parametro ind. intero, ritorna il PID del figlio terminato.

Contenuta nelle librerie: #include <sys/types.h> #include <sys/wait.h>

NB [La variabile status dovrà essere divisa per 256 poiché i primi otto bit sono di controllo]

Pagina 13

2.2 COBEGIN-COEND

A. Cobegin-Coend

Il costrutto Cobegin-Coend è molto simile al Fork-Join con la differenza che quando si richiama l'istruzione Cobegin si possono creare N processi contemporaneamente che sospendono il padre fino a che non terminano con la Coend.

Figura 3 Pseudo codifica di Cobegin-Coend

Pagina 14

3. Virtualizzazione

Virtualizzazione è la possibilità di astrarre le componenti hardware, degli elaboratori, al fine di renderle disponibili al software in forma di risorsa virtuale.

Tramite questo processo è quindi possibile emulare un S.O. su hardware virtuale, ovvero assegnare risorse HW, ad un S.O. non installato sulla macchina.

Attraverso un processo di virtualizzazione che avviene tramite un programma, si crea una macchina virtuale che assegna l'HW al S.O. da emulare per renderlo funzionante e utilizzabile. Il S.O. emulato diventa un processo del sistema operativo che lo ha lanciato.

Pagina 16

4 Esercizio

Esercizio 2 : Creare un programma che a partire da un processo padre crei un processo figlio per poi far terminare prima il padre cosi da rendere orfano il figlio(non utilizzare la sleep).

#include <stdio.h> #include <unistd.h> //unix standard library int main(){ bool n=1; pid_t pid,mioPid,ppid; system("clear"); pid=fork(); //PADRE if(pid!=0){ mioPid=getpid(); //cattura il pid del padre printf("A1)SONO IL PADRE IL MIO PID E' %d \n",mioPid); sleep(3); //il processo padre si ferma per 3 secondi e passa al figlio printf("A2)SONO TERMINATO \n"); exit(0); } //FIGLIO else{ //controllo infinito fino a quando il ppid diventi 1 cioè il padre è morto, finiti i tre // secondi di sleep il padre riparte e trmina. do{ ppid=getppid(); //cattura il pid del padre //se entra nel controllo if vuol dire che il padre è morto if(ppid==1){ printf("SONO ORFANO, FIGLIO DI INIT %d\n",ppid); exit(0); } printf("B1)PID DI MIO PADRE %d \n",ppid); sleep(1); }while(n); } }

Pagina 17

5. Modelli di ambiente

I modelli di ambiente sono dei modelli che rappresentano l'utilizzo di una risorsa SW, HW o Dati da parte di un processo che ne fa richiesta.

Esistono due tipi di modelli:

Modello ad ambiente locale (scambio di messaggi): un singolo processo dispone di una o più risorse private a cui solo lui può accedere e utilizzar, processo indipendete, che per comunicare con altri processi deve scambiare dei messaggi tramite costrutti.

Modello ad ambiente globale (memoria comune): più processi interagiscono esclusivamente operando su risorse comuni, quindi saranno dei processi competitivi o cooperanti.

Ogni applicazione concorrente è composta da due componenti, processi(componenti attivi) e risorse(componenti passivi).

Risorsa è un qualunque oggetto, fisico o logico, di cui un processo necessita per portare a termine il suo compito è una struttura dati allocata nella memoria primaria. Risorsa privata (modello locale) quando un singolo processo può eseguire operazioni su di essa. Risorsa comune (modello globale): è una risorsa su cui più processi possono operare.

Esistono meccanismi di controllo degli accessi alle risorse poiché è necessario definire quali processi ed in quali istanti essi possono accedere correttamente alla risorsa. Il gestore può accettare, ritardare o rifiutare la richiesta.

Schema logico seguito da ogni processo che vuole accedere a una risorsa:

 richiesta della risorsa,  uso,  rilascio del diritto di accedere.

Deadlock è un fenomeno che avviene quando più processi competono per l'utilizzo di risorse comuni, e si viene a creare una situazioni di stallo detta deadlock o blocco critico.