• Non ci sono risultati.

Costrutti linguistici per la specifica della concorrenza

N/A
N/A
Protected

Academic year: 2021

Condividi "Costrutti linguistici per la specifica della concorrenza"

Copied!
19
0
0

Testo completo

(1)Costrutti linguistici per la specifica della concorrenza. 1.

(2) Fork/Join L’esecuzione di una fork coincide con la creazione e l’attivazione di un processo che inizia la propria esecuzione in parallelo con quella del processo chiamante /* processo p: */. ======= A: ........;. . p = fork fun; B: ........;. . ======= ======= /* codice nuovo processo:*/ void fun() { C: ........; ======= }. A. fork. C B. 2.

(3) La join consente di determinare quando un processo, creato tramite la fork, ha terminato il suo compito, sincronizzandosi con tale evento.. Am. A1. join. B. 3.

(4) /* processo p: */. ... A: ........; p = fork fun; B: ........; join p; D: ........; ... /* codice nuovo processo:*/ void fun() { C: ........; ... }. A fork. B. C fun(). join D. Possibilità di denotare in modo esplicito il processo sulla cui terminazione ci si vuole sincronizzare. 4.

(5) Cobegin-Coend La concorrenza viene espressa nel modo seguente:! ! ! S 0; cobegin S. S 1; S 2; S S S. S 3; S. coend S 4; 0. 1. 2. 3. 4. Le istruzioni S1, S2,…,Sn sono eseguite in parallelo. Ogni Si può contenere altre istruzioni cobegin..coend al suo interno. 5.

(6) Processo !Costrutto linguistico per individuare, in modo sintatticamente preciso, quali moduli di un programma possono essere eseguiti come processi autonomi: !! !. process <identificatore>(<parametri formali>) { <dichiarazione di variabili locali>; <corpo del processo> }. 6.

(7) Il Nucleo di un sistema monoprocessore: realizzazione delle primitive di specifica della concorrenza. fork usata da un processo per creare un altro processo. join la. usata per consentire ad un processo di attendere terminazione di un processo figlio (equivalente alla wait di Unix).. quit. usata per terminare un processo (equivalente alla exit di Unix).. 7.

(8) Passaggio del controllo fra ambiente dei processi e ambiente di nucleo interruzione esterna. salvataggio_stato;. chiamata di sistema SVC. interrupt_handler; ripristino_stato; IRET. primitiva di sistema. 8.

(9) !Rappresentazione dei processi: descrittori di processo typedef des_processo * p_des; typedef struct { PID nome; modalità_di_servizio servizio; tipo_contesto contesto; tipo_stato stato; PID padre; int N_figli; des_figlio prole[max_figli]; p_des successivo; }des_processo;. 9.

(10) Ogni processo viene identificato univocamente con un numero intero: ! ! !typedef int PID; Funzione (assegna_nome) che, chiamata all’atto della creazione di un processo, restituisce il suo PID: !. !. !PID assegna_nome();. ! Modalità di servizio (es. scheduling time sharing con priorità): typedef struct { int priorità; int delta_t; // time slice } modalità_di_servizio; 10.

(11) Descrittore del figlio (des_figlio): typedef struct{ PID figlio; boolean terminato; //true = terminato } des_figlio; Insieme di tutti i descrittori (descrittori): ! des_processo descrittori[num_max_proc]; Funzione per scegliere un descrittore (descrittore): ! ! !p_des descrittore(PID x); 11.

(12) Descrittore coda (des_coda): typedef struct { p_des primo, ultimo; }des_coda; Inserimento e prelievo in/da coda: !void Inserimento (p_des proc,des_coda coda); p_des Prelievo (des_coda coda); Code dei processi pronti (scheduling multilevel, con priorità): des_coda coda_processi_pronti[num_min_priorità]; Coda dei descrittori liberi: ! !des_coda descrittori_liberi; 12.

(13) Cambio di contesto p_des. processo_in_esecuzione;. void salvataggio_stato () { p_des esec = processo_in_esecuzione; esec -> contesto = <valori dei registri della CPU>; } void ripristino_stato( ) { p_des esec = processo_in_esecuzione; <registri della CPU> = esec -> contesto; }. 13.

(14) !Schedulazione. void assegnazione_CPU { int k=0; p_des p; while ((coda_processi_pronti[k].primo)==null) k++; p = prelievo(coda_processi_pronti [k]); p -> stato = < running>;. processo_in_esecuzione = p;. <registro-temporizzatore>= p -> servizio.delta_t; } Invocata ogni volta che il processo in esecuzione esce dallo stato di “running”. 14.

(15) Attivazione di un processo L’attivazione di un processo P, dopo una fase di sospensione, porta P nello stato di pronto (code dei processi pronti). Se lo scheduling prevede preemption, il processo attivato P può scalzare il processo in esecuzione nell’uso della CPU. void attiva (p_des proc) { p_des esec = processo_in_esecuzione; int pri_esec = esec -> servizio.priorità; int pri_proc = proc -> servizio.priorità; if (pri_esec > pri_pro) { /* pre-emption*/ proc -> stato = < running>; inserimento(esec,coda_processi_pronti[pri_esec]); processo_in_esecuzione = proc; } else { proc -> stato = < ready>; inserimento(proc,coda_processi_pronti[pri_proc]); } } 15.

(16) fork typedef enum {OK,eccezione} risultato; risultato fork (des_processo inizializzazione) { p_des p; int NF; p_des esec = processo_in_esecuzione; if (descrittori_liberi.primo == NULL ) return eccezione; /* non ci sono descritt. liberi*/ else { p = prelievo(descrittori_liberi); *p = inizializzazione; p -> nome = assegna_nome(); p -> padre = esec -> nome; NF = esec->N_figli; esec -> prole[NF].figlio = p -> nome; esec -> prole[NF].terminato = false; esec -> N_figli++; attiva(p); return ok; } } 16.

(17) join. void join (PID nome_figlio) { p_des esec = processo_in_esecuzione; int k =indice_figlio(esec,nome_figlio); if (esec -> prole[k].terminato == false) { /* figlio non terminato*/ esec -> stato = < “sospeso in attesa che il figlio termini”>; assegnazione_ CPU(); } }. 17.

(18) quit void quit(){ p_des esec = processo_in_esecuzione; PID nome_padre = esec -> padre; p_des p_padre = descrittore(nome_padre); int k=indice_figlio(p_padre, esec -> nome); p_padre -> prole[k].terminato=true; inserimento(esec, descrittori_liberi); if (p_padre -> stato==<“ in attesa che questo figlio termini”>) { int pri = p_padre -> servizio.priorità; inserimento(p_padre,coda_processi_pronti[pri]); p_padre -> stato = < ready>; } assegnazione_CPU( ); }. 18.

(19) Time sharing Per consentire la realizzazione di modalità di servizio a divisione di tempo occorre revocare ad intervalli fissati di tempo la CPU al processo in esecuzione e di assegnarla ad un nuovo processo pronto: void interruzione_temporizzatore () { p_des esec=processo_in_esecuzione; int k; k=esec->servizio.priorità; esec-> stato = < ready>; Inserimento(esec,coda_processi_pronti[k]); assegnazione_CPU(); }. 19.

(20)

Riferimenti

Documenti correlati

Fermi / teoria dei giochi Plank / teoria quantistica Newton / caduta dei gravi Einstein / teoria della relatività Galileo / metodo sperimentale. &#34;Il cantante Tizio e' un cane;

1973: UK, Irlanda e Danimarca entrano nell'UE Il governo inglese riteneva che fosse nel suo interessa far parte del processo di integrazione economica europea, in particolare per

La Raccomandazione prevede che ciascuno Stato dell’Unione Europea, in base alle conoscenze scientifiche attuali, provveda affinché gli allevatori effettuino una

c) materiali di interesse marginale — materiali che costituiscono una distrazione per i suini ma che non dovrebbero essere considerati tali da soddisfare i loro

E nonostante tutto cio' che sta accadendo ancora oggi, dopo un anno, penso che questa esprienza bruttissima ci cambierà tutti e che noi stiamo com- prendendo che

[r]

P er la prima volta il comune di Milano potrà avvalersi delle competenze e conoscenze di due medici veterinari come Garanti per la tutela degli animali. Paola Fossati e Gustavo

Con nota prot. 379 del 7 gennaio 2019, la Questura di Biella segnalava la necessità di ripristinare la tinteggiatura delle pareti e del soffitto degli alloggi di servizio al 2^