Programmazione Concorrente e distribuita z Bibliografia z Ancillotti
Programmazione Concorrente e distribuita z. Bibliografia: z. Ancillotti- Boari. Principi e Tecniche di Programmazione Concorrente. Utet Libreria z. Bacon. Concurrent Systems. Addison- Wesley z. Ben-Ari. Principles of concurrent and distributed programming. Prentice-Hall z. Raynal. Distributed Algorithms and Protocols. Wiley & Sons 1
Concorrenza: hardware e software z. Architetture fortemente connesse architetture in cui n processori (n > 1) condividono memoria centrale e clock z. Architetture debolmente connesse architetture in cui n processori (n > 1) hanno ciascuno una propria memoria centrale e un clock 2
Primitive di concorrenza in architetture fortemente connesse Scopo: nascondere le primitive di kernel e migliorare la correttezza e la leggibilità del programma Scopo: rendere le primitive di kernel più efficaci, combinando il trsferimento di informazioni e la sincronizz. -RCC -Monitor -Path expression -Scambio di messaggi -Pipes -Sockets -Canali -RPC SO con memoria condivisa IPC SO senza memoria condivisa Primitive di sincronizzazione a basso livello (kernel) Semafori, eventi 3
Linguaggi concorrenti: memoria condivisa vs scambio di messaggi z Un programma concorrente scritto in un linguaggio che prevede la memoria condivisa e’ adatto: yquando più processi del linguaggio sono realizzati all’interno di un unico processo di sistema y nei sistemi operativi che forniscono “multithreading” ynei sistemi operativi che permettono la condivisione di moduli (come Unix) ynei sistemi a tempo reale e sistemi di controllo “embedded” 4
Linguaggi concorrenti: memoria condivisa vs scambio di messaggi z Un programma concorrente scritto in un linguaggio che prevede la memoria condivisa non e’adatto: yin sistemi multiutente in cui lo spazio degli indirizzi e’ separato e protetto ytra processi residenti su macchine diverse in un’architettura a rete yin sistemi distribuiti in cui e’ desiderabile mantenere un certa flessibilita’ sul loading dei processi (load balancing) 5
Concorrenza: hardware e software La realizzazione di scambio di comunicazione tra processi puo’ essere effettuata secondo due modalita’ duali: yin modo procedurale xmonitor (se esiste condivisione di memoria) xrendez-vous-esteso (se non esiste memoria condivisa) ycon scambio di messaggi 6
Concorrenza: hardware e software z Struttura di un sistema procedurale Dominio chiamante MONITOR Processo Procedure 1 Call monitor-name DATI Procedure 2 Procedure n 7
Concorrenza: hardware e software z Struttura di un sistema a scambio di messaggi WAIT Process call requested procedure SEND (request) WAIT (reply) SEND reply Procedura 1 DATI Procedura 2 Procedure interne Procedura n 8
Scambio di messaggi: Classificazione I meccanismi di comunicazione si possono classificare in base alle seguenti caratteristiche: ydesignazione sorgente e destinatario xsimmetrica xasimmetrica ytipo di sincronizzazione xsend • sincrona • asincrona • chiamata di procedura xreceive • bloccante • non bloccante 9
Scambio di messaggi: Primitive asincrone y. Comunicazione asimmetrica y. Send non bloccante y. Receive bloccante y. Ogni processo ha unica coda di messaggi a lui inviati, gestita FIFO Send (mes, proc) proc : = Receive (mes) 10
Primitive asincrone a scambio di messaggio a livello kernel z Le primitive di scambio di messaggi possono essere realizzate a livello di kernel (anche in un’ architettura a memoria condivisa). Processo A Processo B Wait(. , bid) Send (B, . . ) WAIT SEND 11
Semafori vs Scambio di messaggi (per sistemi con memoria condivisa) z In un kernel a scambio di messaggi il kernel deve gestire il pool dei buffer, e le code dei messaggi => ymaggior complessita’ delle primitive di kernel ymaggior memoria a disposizione del kernel z In un kernel con semafori lo scambio di informazioni tra i processi deve essere fatto a livello delle applicazioni => yl’ onere (di tempo d’ esecuzione e di memoria) e’ a carico dei processi interessati yil kernel e’ piu’ snello 12
Implementazione di Scambio di messaggi z Dimensione dei messaggi y lunghezza fissa a livello kernel y lunghezza variabile nei linguaggi ad alto livello z Bufferizzazione dei messaggi y numero massimo della lunghezza delle code y problema del deadlock y messaggi persi z Tecniche di gestione della memoria y messaggi grandi possono essere tenuti in segmenti o pagine passate da sender a receiveer y tecniche copy-on-write 13
Primitive asincrone: Produttori-Consumatori type tipo_messaggio_ricevuto = (dati, pronto) type in_mess = record case specie: tipo_messaggio_ricevuto of dati : (informazione: T) pronto: segnale end type out_mess: T 14
Primitive asincrone: Produttori-Consumatori Process buffer; var coda_dati: <coda di elementi di tipo. T> coda_cons: <coda di nomi di processo> inf: T cons, proc : process in : in_mess out: out_mess begin while true do begin proc: = Receive (in) trattadato(informazione) pronto: trattasegnale end case in. specie of dati: 15
Primitive asincrone: Produttori-Consumatori trattadato(informazione) begin if <coda_cons vuota> then put (informazione, coda_dati) else begin cons : =get(coda_cons) out: = in. informazione Send (out, cons) end 16
Primitive asincrone: Produttori-Consumatori trattasegnale begin if <coda_dati vuota> then put(proc, coda_cons) else begin inf : =get(coda_dati) out: = inf Send (out, proc) end 17
Primitive asincrone: Produttori-Consumatori Process produttore_i var mess: in_mess; contenuto: T; begin mess. specie: =dati while true do begin <produci dato> mess. informazione: = contenuto Send (mess, buffer) end 18
Primitive asincrone: Produttori-Consumatori Process consumatore_j var mess 1: in_mess; mess 2: out_mess; proc: process; begin mess 1. specie: =pronto while true do begin Send (mess 1, buffer) proc : = Receive (mess 2) <consuma mess 2 > end 19
Primitive asincrone: Produttori-Consumatori z. Variante primitiva Receive proc : = Receive (mess) when B z si ricevono solo i messaggi che soddisfano la condizione B z se non esiste nessun messaggio che soddisfa la condizione B la Receive e’ bloccante 20
Primitive asincrone: Produttori-Consumatori z Problemi realizzativi delle primitive con la Receive selettiva: yanaloghi a quelli della Regione Critica Condizionale: il processo bloccato in attesa del verificarsi della condizione logica viene svegliato ogni qualvolta un nuovo messaggio viene inserito in coda => busy form of waiting. 21
Primitive asincrone: Produttori-Consumatori Process buffer; var proc 1, proc 2 : process; in 1, in 2: in_mess; out: = out_mess; begin while true do begin proc 1: = Receive (in 1) case in 1. specie of dati: trattadato(informazione) pronto: trattasegnale end 22
Primitive asincrone: Produttori-Consumatori Trattadato (informazione) begin proc 2: = Receive (in 2) when in 2. specie=pronto out: = in 1. informazione Send (out, proc 2) end 23
Primitive asincrone: Produttori-Consumatori trattasegnale begin proc 2 : = Receive (in 2) when in 2. specie = dati out: = in 2. informazione Send (out, proc 1) end 24
Variazioni su scambio di messaggio asincrono z Primitive di domanda e risposta z Piu’ code di messaggi per processo y Porte y Canali: mailbox autonoma (detta anche global port) con un suo nome proprio y Broadcast e multicast x I canali possono fornire una comunicazione “from anyone” e/o “to everyone” a tutti i processi di un gruppo definito al momento della configurazione (broadcast) x Multicast : capacita’ di inviare un messaggio a tutti i processi di un dato gruppo 25
Variazioni su scambio di messaggio z Piu’ code di messaggi per processo y porte multiple per processo Risposte per il processo P Messaggi per P, porta 1 Messaggi per P, porta 2 Messaggi per P, porta n Porta 0 Porta 1 Op. 1 Dati Porta 2 Op. 2 Procedure interne Porta n Op. n 26
Variazioni su scambio di messaggio y Porte di input e di output controllo dei tipi Mittente Send(m) Ricevente Porta di output Porta di input Wait(m) Binding e verifica di tipo a tempo di configurazione Verifica di tipo a tempo di compilazione 27
Variazioni su scambio di messaggio z Una sola porta di input e molte di output Mittente Send(m) Porta di output Mittente Send(m) Ricevente Porta di output Porta di input Wait(m) Mittente Send(m) Porta di output 28
Variazioni su scambio di messaggio Mittente Ricevente Send(m) Wait(m) Mittente Global Port Send(m) Ricevente Mittente Wait(m) Send(m) 29
Primitive asincrone: porte multiple z. Piu’ porte di ingresso: port x: T; Send (m) to x; proc : = Receive (m) from x; 30
Primitive asincrone: Comandi con guardia Comandi con guardie <guardia> -----> <istruzione> guardia: espressione logica + (guardia logica) primitiva Receive (guardia di input) 31
Primitive asincrone: Comandi con guardia La guardia viene valutata quando il comando viene eseguito; si possono avere i seguenti risultati: guardia fallita guardia valida guardia ritardata La guardia viene usata all’interno di comandi alternativi e di comandi ripetitivi. 32
Primitive asincrone: Comandi con guardia comando alternativo if . . . Bn end B 1 B 2 --> istruzione 1 istruzione 2 --> istruzionen Se esistono guardie valide ne viene scelta (in modo non deterministico) una Se tutte le guardie sono fallite il comando viene abortito Se tutte le guardie non fallite sono ritardate il processo si blocca in attesa dell’input. 33
Primitive asincrone: Comandi con guardia comando ripetitivo do B 1 . . . end --> B 2 istruzione 1 --> istruzione 2 Bn --> istruzionen Il comando viene ripetuto fino a che tutte le guardie falliscono. In questo caso il comando termina. 34
Primitive asincrone: Comandi con guardia Problemi realizzativi delle primitive con porte multiple (e/o guardie): ysupporto run time deve fornire tante code quante sono le porte ycomandi con guardia richiedono la realizzazione di risveglio di un processo in attesa su un insieme di porte yun processo deve sospendersi su un insieme di porte 35
Primitive asincrone: Produttori-Consumatori porte multiple Process buffer port p-dati: T p-controllo: signal var inf: T pronto: signal produttore, consumatore: process begin do produttore: = Receive(inf) from p-dati; consumatore: = Receive(pronto) from p-controllo; Send (inf) to consumatore. inport consumatore: = Receive(pronto) from p-controllo; produttore: = Receive(inf) from p-dati; Send (inf) to consumatore. inport od end 36
Primitive asincrone: Produttori-Consumatori porte multiple Process consumatore_j port inport: T; var pronto: signal; inf: T; buffer: process; begin while true do begin Send (pronto) to buffer. p-controllo; buffer: = Receive (inf) from inport; <consuma inf > end 37
Primitive asincrone: Produttori-Consumatori porte multiple Process produttore_i var inf: T; begin while true do begin <produci contenuto> inf: = contenuto Send (inf) to buffer. p-dati end 38
Send asincrona: Produttori-Consumatori con buffer limitato Process buffer port p-dati: T p-ctrl-p: signal p-ctrl-c: signal var inf: T ok-p, ok-c, ok-s: signal produttore, consumatore: process contatore: integer (init. 0) begin do (contatore < N); produttore: = Receive(ok-p) from p-ctrl-p; contatore: = contatore + 1 Send (ok-s) to produttore. okport (contatore >0); consumatore: = Receive(ok-c) from p-ctrl-c; _ produttore: = Receive(inf) from p-dati; contatore: = contatore - 1 Send (inf) to consumatore. inport od end 39
Send asincrona: Produttori-Consumatori con buffer limitato Process produttore_i port okport: signal var inf: T; ok-p, ok-s: signal buffer: process begin while true do begin <produci contenuto> inf: = contenuto Send (ok-p) to buffer. p-ctrl-p; buffer: = Receive (ok-s) from okport Send (inf) to p-dati end 40
Send asincrona Sistema Pipelining Tre processi provvedono alla: zlettura di N record da un file zelaborazione dei record zcreazione di un nuovo file con i record modificati ELABOR INPUT A OUTPUT 41
Send asincrona Sistema Pipelining Program pipeline var file 1, file 2: file of T; Process Input; var buf: T; begin reset (file 1); for i : = 1 to N do begin Read (file 1, buf) Send (buf, Elabora) end 42
Send asincrona Sistema Pipelining Process Elabora; var bufin, bufout: T; proc: process; begin for i : = 1 to N do begin proc : = Receive (bufin) bufout : =Elabora (bufin) Send (bufout, Output) end 43
Send asincrona Sistema Pipelining Process Output; var buf: T; proc: process; begin rewrite (file 2) for i : = 1 to N do begin proc : = Receive (buf) write(file 2, buf) end 44
Primitive sincrone a scambio di messaggio a livello kernel z Processo A Send (B, . . ) SEND Processo B Wait(. , bid) WAIT 45
Primitive sincrone Rendez-vous E Invocazione Send E Trasmissione messaggio BO z Stato di un processo che esegue la Send (BO: bloccato per output) Invocazione Receive Ricezione messaggio BI z Stato di un processo che esegue la Receive (BI: bloccato per input) 46
Primitive sincrone Rendez-vous Mitt Ric E BI Posso mandarti un messaggio? BO BO E OK! manda messaggio BI BI E 47
Primitive sincrone a scambio di messaggio a livello kernel z Le primitive sincrone a livello di kernel non richiedono la gestione dei buffer, ma non sono adatte a tutti i tipi di sincronizzazione tra processi (ad esempio client/server). SERVIZI O Server Cliente Processo di Interfaccia Wait (request) Send(request) <Do request> Wait (replay) Send(reply) 48
Primitive sincrone Rendez-vous y. Comunicazione asimmetrica y. Send bloccante y. Receive bloccante y. Non esistono code di messaggi associati ai processi gestiti dal meccanismo di comunicazione Send (mes, proc) proc : = Receive (mes) 49
Primitive sincrone Produttore- Consumatore Process buffer; var coda: queue of T; proc : process; ccpronto, ppronto: boolean (init. false); dati: T; pronto: signal begin while true do begin proc: = Receive (pronto) case proc of produttore: trattaprod consumatore: trattacons end 50
Primitive sincrone Produttore- Consumatore trattaprod begin if <coda piena> then ppronto : = true else begin proc : = Receive (dati) if cpronto then begin Send (dati, cons) cpronto : = false end else put(dati, coda) end 51
Primitive sincrone Produttore- Consumatore trattasegnale begin if <coda vuota> then cpronto : = true else begin dati: =get(coda) Send (dati, cons) if ppronto then begin proc: =Receive (dati) put(dati, coda) ppronto : = false end end 52
Primitive sincrone Produttore- Consumatore Process produttore var dati: T; pronto: signal begin while true do begin <produci dato> Send (pronto, buffer) Send (dati, buffer) end 53
Primitive sincrone Produttore- Consumatore Process consumatore var dati: T; pronto: signal; proc: process; begin while true do begin Send (pronto, buffer) proc : = Receive (dati) <consuma dati > end 54
Primitive sincrone Produttore- Consumatore con guardie Process buffer type p-pronto = signal c-pronto= signal var coda: queue of T datipronti: p-pronto datirichiesti: c-pronto proc: process dati : T begin do (coda nonpiena); proc: = Receive(datipronti) _ proc: = Receive(dati) put (dati, coda); (coda nonvuota); proc: =Receive(datirichiesti) get(dati, coda) Send (dati, consumatore) od end 55
Primitive sincrone Produttore- Consumatore con guardie (senza uso del segnale datipronti) Process buffer var coda: queue of T proc: process dati : T cpronto: signal begin do (coda nonpiena); proc: = Receive(dati) ; put (dati, coda); (coda nonvuota); proc: =Receive(cpronto) get(dati, coda) Send (dati, consumatore) od end 56
Primitive sincrone Produttore- Consumatore Process produttore var dati: T; begin while true do begin <produci dato> Send (dati, buffer) end 57
Primitive sincrone Produttore- Consumatore guardie di input/output Comandi con guardie per primitive sincrone <guardia> -----> <istruzione> guardia: espressione logica (guardia logica) + primitiva Receive (guardia di input) oppure primitiva Send (guardia di output) 58
Primitive sincrone Produttore- Consumatore con guardie di input/output Process buffer var coda: queue of T proc: process dati : T begin do (coda nonpiena); proc: = Receive(dati) ; put (dati, coda); (coda nonvuota); Send (first(coda), consumatore) aggiorna coda od end 59
Primitive sincrone Produttore- Consumatore con guardie di input/output Le guardie di output sono utili nel caso di sistemi client/server con piu’ di un server. if Send (richiesta, server 1) --> ………; Send (richiesta, server 2) --> ………; Send (richiesta, server. N) --> ………; : : end proc : = Receive (risposta) 60
Primitive sincrone Produttore- Consumatore con guardie di input/output Att!! Le guardie di output sono difficili da realizzare e possono portare a deadlock. La validita’ di una guardia di output non garantisce che venga scelta l’istruzione associata alla guardia stessa 61
Primitive sincrone Produttore- Consumatore con buffer parallelo Process produttore var dati: T; begin while true do begin <produci dato> Send (dati, buffer 1) end Process consumatore var dati: T; proc: process; begin while true do begin proc : = Receive (dati) <consuma dati > end 63
Primitive sincrone Produttore- Consumatore con buffer parallelo Process buffer-i var dati: T; proc: process; begin while true do begin proc : = Receive (dati) Send (dati, buffer-(i+1)) end Process buffer-N var dati: T; proc: process; begin while true do begin proc : = Receive (dati) Send (dati, consumatore) end 64
Primitive sincrone canali uno-uno • Comunicazione simmetrica • Send bloccante • Receive bloccante • Mittente e ricevente devono conoscere il nome del processo con cui vogliono comunicare x. Send (mes, proc) x. Receive (mes, proc) 65
Send sincrona Sistema Pipelining Program pipeline var file 1, file 2: file of T; Process Input; var buf: T; begin reset (file 1); for i : = 1 to N do begin Read (file 1, buf) Send (buf, Elabora) end 66
Send sincrona Sistema Pipelining Process Elabora; var bufin, bufout: T; proc: process; begin for i : = 1 to N do begin proc : = Receive (bufin) bufout : =elabora (bufin) Send (bufout, Output) end 67
Rendez- vous esteso Remote Procedure Call z Meccanismo di tipo sincrono in cui il processo che richiede un servizio ad un altro processo rimane sospeso fino al completamento del servizio. mittente ricevente accept chiamata attesa Parametri input Inizio rendez-vous Parametri output Fine rendez-vous 68
Rendez- vous esteso Remote Proceure Call z. Primitiva dal lato cliente: cliente call <servizio> (input, output) Primitiva dal lato servitore: remote procedure <servizio> (in <…>out <…>)) var …; begin … end accept <servizio> (in <…>out <…>)) --> S 1, …, Sn 69
Rendez-vous esteso Produttore- Consumatore Process buffer var buff: array[0. . N-1] of T testa, coda : 0. . N-1 (init. 0) cont: 0. . N (init. 0) begin do (cont < N); accept inserisci (in dato: T) --> buff[coda]: = dato; end cont : = cont +1 coda : = (coda +1) mod N; (cont > 0); accept preleva(out dato: T) _--> dato: = buff[testa]; end cont : = cont - 1 testa : = (testa +1) mod N; od end 70
Rendez-vous esteso Produttore- Consumatore Process produttore-i var dati: T; begin while true do begin <produci dato> call buffer. inserisci (dati) end 71
Rendez-vous esteso Produttore- Consumatore Process consumatore-j var dati: T; begin while true do begin call buffer. preleva(dati) <consuma dati> end 72
Rendez-vous esteso Segnalazione di sveglia Process allarme var tempo: integer tempo-di-sveglia: array[1. . N} of record risveglio: integer intervallo: integer end begin do accept tick tempo : = tempo + 1; accept richiesta-sveglia (in intervallo: integer) <inserimento tempo + intervallo e intervallo in tempo di sveglia> (tempo = tempo di sveglia[1]. risveglio); accept svegliami [tempo di sveglia[1]. intervallo]; <riordinamento di tempo-di-sveglia> od end 73
Rendez-vous esteso Pipeline Process Input; var buff: T; . . . call Elabora. ricezione (buff). . . end Process Elabora; var buff: T; . . . accept. ricezione (buff) … call Output. ricezione (buff) … end Process Output; var buff: T; . . . accept ricezione (buff) end . . . 74
Linguaggi di programmazione a scambio di messaggi CSP Communicating Sequential Processes z non e’ un vero e proprio linguaggio ma piuttosto un modello di interazione tra processi z notazione per la specifica di concorrenza z comunicazione sincrona z ricezione selettiva dei messaggi 75
Linguaggi di programmazione a scambio di messaggi CSP z Processi <identificatore> : : <lista comandi> z Comando parallelo [<processo> //<processo>//…//<processo>] z Invio di messaggi (Send) <destinatario> ! <espressione> z Ricezione di messaggi (Receive) <sorgente> ? <variabile> 76
Linguaggi di programmazione a scambio di messaggi CSP Schema di sincronizzazione La comunicazione puo’ essere stabilita se e solo se: a) P contiene un comando di uscita e Q contiene un comando di ingresso, ognuno specificante il nome del rispettivo partner (comunicazione simmetrica) b) la variabile del comando di input e’ compatibile con l’ espressione del comando di output c) la sincronizzazione e’ a rendez-vous esteso P : : … ; Q: : …; …; …; Q!<exp>; P? <var> ; …; …; (comandi corrispondenti) 77
Linguaggi di programmazione a scambio di messaggi CSP Schema di comunicazione z Tra i due processi si individua un canale, definito dalla terna: – nome mittente – nome ricevente – tipo del messaggio z La sequenzializzazione tra processi e’ data dai comandi alternativi e ripetitivi con guardie: y alternativo: [ <guardia 1> --> <lista comandi 1> … <guardia n> --> <lista comandi n>] y ripetitivo: * [<guardia 1> --> <lista comandi 1> … <guardia n> --> <lista comandi n>] 78
Linguaggi di programmazione a scambio di messaggi CSP Linguaggi ispirati dai CSP OCCAM (transputer) z processi comunicano tramite canali z ad ogni canale è associato un tipo di dato z un canale connette due soli processi: un processo di output ed un processo di input z comunicazione di tipo rendez-vous esteso z processi statici 79
Linguaggi di programmazione a scambio di messaggi CSP Linguaggi ispirati dai CSP OCCAM (sintassi) z ogni statement è considerato un processo z il programmatore deve esplicitare l’esecuzione parallela o sequenziale: SEQ PAR stat 1 stat 2 stat 3 stat 1 stat 2 z comunicazione denotata con ? e ! channel ? var channel ! value 80
Linguaggi di programmazione a scambio di messaggi CSP Linguaggi ispirati dai CSP OCCAM Prodotto di matrici * = 81
Linguaggi di programmazione a scambio di messaggi CSP Linguaggi ispirati dai CSP OCCAM Prodotto di matrici 1, 0, 2 4, 2, 6 RIS 0, 1, 2 2 1 RIS 5 6, 5, 10 7 16, 8, 30 6, 0, 0 8 9, 8, 16 SINK ZERO 3, 0, 0 4 RIS 1, 0, 0 3 3, 2, 4 10, 5, 18 SRC SRC SINK 6 ZERO 9, 0, 0 SINK 82
Linguaggi di programmazione a scambio di messaggi CSP Linguaggi ispirati dai CSP Moltiplicatore per matrici: Prendere un elemento da NORD Passarlo a SUD Moltiplicarlo per val Prendere il valore somma parziale da EST Sommare aggiornare il valore Mandare il risultato OVEST N O val E S 83
Linguaggi di programmazione a scambio di messaggi CSP a) b) Moltiplicatore in OCCAM WHILE TRUE SEQ north ? x WHILE TRUE SEQ PAR north ? x south ! x east ? sum : = sum + a * x west ! sum south ! x east ? sum tmp : = a * x west ! sum + tmp north ? x 84
Linguaggi di programmazione a scambio di messaggi DP Distributed Processes z linguaggio basato su RPC z proposto per applicazioni in tempo reale z un sistema e’ visto come un insieme di processi concorrenti che “vivono insieme” per tutta la durata del sistema 85
Linguaggi di programmazione a scambio di messaggi DP Processi Process <identificatore> <variabili> <procedure locali> <procedure comuni> begin … end Comandi con guardia if B 1 : S 1 / B 2 : S 2 /…end do B 1 : S 1 / B 2 : S 2 /…end Varianti sospensive when B 1 : S 1 / B 2 : S 2 /…end cycle B 1 : S 1 / B 2 : S 2 /…end Rendez-vous esteso 86
Linguaggi di programmazione a scambio di messaggi ADA z linguaggio studiato soprattutto per applicazioni in tempo reale z notazione per la specifica di concorrenza: task z comunicazione asimmetrica e sincrona z remote procedure call 87
Linguaggi di programmazione a scambio di messaggi ADA Schema di comunicazione dalla parte del server: accept <servizio> (in <…>out <…>)) do S 1, …, Sn end l’ accept puo’ essere selettiva: select accept entry 1 do, …, end accept entry 2 do, …, end or … or accept entryn do, …, end select 88
Linguaggi di programmazione a scambio di messaggi ADA si possono usare guardie logiche: select when B 1 --->accept entry 1 …, or when B 2 ---> accept entry 2 …, … or when Bn --->accept entryn …, end select 89
Linguaggi di programmazione a scambio di messaggi ADA Schema di comunicazione dalla parte del client: le chiamate alle entry del server sono effettuate con la notazione “. ” server. Entryname e’ possibile una chiamata condizionale: select else <chiamata di una entry> <comandi> end select la chiamata viene effettuata solo se il server e’ in attesa su quella entry 90
Linguaggi di programmazione a scambio di messaggi ADA Esempio : Implementazione semaforo task body SEMAPHORE is count : integer begin accept Init (N: integer) do count : = N loop select when count >0 => accept WAIT do count : = count -1 end or accept SIGNAL do count : = count +1 end select end loop end SEMAPHORE 91
Linguaggi di programmazione a scambio di messaggi ADA Moltiplicatore task body MULTIPLIER is X, Sum: array[1. . n] A: integer Nord, Sud, Est, Ovest: task begin accept Init (I: integer; N, S, E, O: channel) do A: = I Nord: = N; Sud: = S; Est: = E; Ovest: = O end loop accept Input (Nord) (I: array[1. . n] ) do X: = I end Sud. Output (X) accept Input (Est) (I: array[1. . n] ) do Sum : = I end Sum : = Sum + A*X Ovest. Output (Sum) end 92
Linguaggi di programmazione ADA Implementazione del Rendez-vous select when B 1 ---> accept entry 1 …, when B 2 ---> accept entry 2 …, … or when Bn ---> accept entryn …, end select or ad ogni accept si associa una coda di processi in attesa (eventualmente un semaforo) 93
Linguaggi di programmazione a scambio di messaggi Linda z Linda è un linguaggio concorrente radicalmente diverso di precedenti z Nei linguaggi tipo Ada e Occam, i processi comunicano mediante un rendez-vous sincrono; essi sono accoppiati nel tempo e nello spazio: y tempo: sincronia y spazio: indirizzo del canale z Linda permette un disaccoppiamento nel tempo e nello spazio; concetto fondamentale è lo spazio delle tuple (TS), che può essere visto come un insieme di sequenze tipate di dati (tupla): y (1, “A”) y (1, 2) (integer, character) (integer, integer) 94
Linguaggi di programmazione a scambio di messaggi Linda Le primitive di Linda sono: y. Output (T): aggiunge la tupla t allo spazio di tuple y. Input (T): rimuove dallo spazio di tuple una tupla matching con T, se tale tupla non esiste il processo viene sospeso y. Read (T): come il precedente, ma senza rimozione y. Try-Input (T): versione non bloccante dell’ Input (T) y. Try-Read (T): versione non bloccante della Read (T) 95
Linguaggi di programmazione a scambio di messaggi Linda Le tuple di Linda possono contenere parametri formali o attuali e, in maniera analoga alla chiamata di procedura, l’accoppiamento di due tuple corrispondenti, provoca il trasferimento dei valori attuali di una tupla nei parametri formali dell’altra. Es. lo statement di input Input (I: integer, C: character) sarà sospeso sino a che lo statement di output Output (1, “A”) avrà inserito la sua tupla a TS 96
Linguaggi di programmazione a scambio di messaggi Linda Esempio 1: z Richiesta di uno specifico servizio da parte di un processo. Le tuple hanno tre elementi: y stringa che identifica richiesta di servizio y intero che identifica il tipo di servizio y identificativo di un processo Input (“job”, J: job_id, 24) / Il processo 24 aspetta di servire/ Output (“job”, 17, 24) / richiesta inviata al processo 24/ Input (“job”, 17, p: Process_id) / richiesta inviata a qualsiasi processo/ 97
Linguaggi di programmazione a scambio di messaggi Linda Esempio 2: z Rendez-vous (tipo ADA): accept Proc (I: in integer, C: in character, B: out Boolean) …. end call Proc (65, “X”, B) z Le tuple hanno i seguenti campi: y stringa contenente il nome del servizio y nome del processo chiamante y due parametri di input (intero e carattere) Codice per la chiamata di procedura Output (“Proc”, 24, 65, “X”) Input (24, B: boolean) Codice per l’accept Input (“Proc”, Caller: p-id, I: integer, C: character) Proc (I, C, B) Output (Caller, B) 98
Linguaggi di programmazione a scambio di messaggi Linda Moltiplicatore in Linda main process Output Output (‘A’, (‘B’, 1, 2, 1, 1, (1, 2, 3) (4, 5, 6) (7, 8, 9) (1, 0, 2) (1, 2, 1) (1, 1, 1) Output (“Next”, 1) righe prima matrice colonne sec. matrice Next job counter for I in 1. . 3 loop for J in 1. . 3 loop Input (‘C’, I, J : integer, C: integer) Print C(I, J) end loop 99
Linguaggi di programmazione a scambio di messaggi Linda Moltiplicatore in Linda worker processes task body Workers is -----dichiarazioni dati locali ----begin loop Input (“Next”, Element) Output (“Next”, Element +1) exit when Element > 3*3 I : = (Element -1)/3 +1 J : = (Element -1) mod 3 + 1 Row-tuple : = Read (`A`, I, V 1) Col-tuple : = Read (`B`, J` V 2) X : = prodotto_interno (V 1, V 2) Output (`C`, I, J, X) end loop end Workers 100
- Slides: 99