3. Un sistema di comunicazione tra processi remoti
L'IPC descritto nella sezione precedente si generalizza facilmente per consentire la comunicazione tra processi situati in luoghi geograficamente diversi, come per esempio all'interno di una rete di calcolatori.
Si consideri dapprima una semplice configurazione di processi distribuiti sui punti di una stella. In ogni punto della stella c'è un sistema operativo autonomo<5>. Al centro della stella esiste un sistema di calcolatori piuttosto grande e intelligente, detto controllore di rete (Network Controller). In questo sistema centrale non può essere eseguito alcun processo; esso va piuttosto considerato un'estensione del monitor di ciascuno dei sistemi operativi della rete.
Se il controllore di rete è in grado di eseguire le operazioni SEND, RECEIVE, SEND FROM ANY, RECEIVE ANY e UNIQUE, e se tutti i monitor di tutti i sistemi time-sharing della rete non eseguono essi stessi queste operazioni ma chiedono al controllore di rete di eseguirle per loro, allora il problema della comunicazione tra processi remoti è risolto. Non sono necessarie altre modifiche, poiché il controllore di rete può tenere traccia di quali RECEIVE e di quali SEND sono stati eseguiti e farli corrispondere esattamente come faceva il monitor nel sistema time-sharing modello. È inoltre possibile uno schema di numerazione delle porte valido per tutta la rete, con il controllore di rete che sa dove (cioè in quale sito) si trova una particolare porta in un particolare momento.
Si consideri poi una rete più complessa in cui non esiste un punto centrale comune, il che rende necessario distribuire tra i nodi della rete le funzioni svolte dal controllore di rete. Nel resto di questa sezione mostrerò che è possibile distribuire in modo efficiente e comodo tra i molti siti della rete le funzioni svolte dal controllore di rete a stella, consentendo comunque la comunicazione generale tra processi remoti.
Occorre apportare alcune modifiche a ciascuna delle quattro operazioni SEND/RECEIVE descritte sopra per adattarle all'uso con un controllore di rete distribuito. Al RECEIVE viene aggiunto un parametro che specifica un sito al quale il RECEIVE deve essere inviato. Ai messaggi SEND FROM ANY e SEND viene aggiunto un sito a cui inviare il SEND, sebbene di norma si tratti del sito locale. Sia RECEIVE sia RECEIVE ANY hanno acquisito la possibilità di ottenere il sito di origine di qualsiasi messaggio ricevuto. Così, quando viene eseguito un RECEIVE, il RECEIVE viene inviato al sito specificato, eventualmente un sito remoto. Contemporaneamente un SEND viene inviato allo stesso sito, normalmente il sito locale del processo che esegue il SEND. In questo sito, detto sito di incontro (rendezvous site), il RECEIVE viene fatto corrispondere al SEND appropriato e la trasmissione del messaggio può aver luogo dal sito SEND al sito da cui è venuto il RECEIVE.
Un RECEIVE ANY non lascia mai il suo sito di origine, e qui sta la necessità di SEND FROM ANY, poiché deve essere possibile inviare un messaggio a una porta RECEIVE ANY senza che il messaggio resti bloccato in attesa di un RECEIVE nel sito mittente. È possibile costruire un sistema in cui l'incontro SEND/RECEIVE avvenga nel sito RECEIVE ed elimini l'operazione SEND FROM ANY, ma a mio giudizio la possibilità di bloccare una normale trasmissione SEND nel sito di origine compensa abbondantemente la complessità aggiunta.
In ogni sito viene tenuta una tabella di incontro. Questa tabella contiene una voce per ogni SEND o RECEIVE non appaiato ricevuto in quel sito e anche una voce per tutti i RECEIVE ANY emessi in quel sito. Una coppia SEND/RECEIVE corrispondente viene cancellata dalla tabella non appena l'abbinamento ha luogo. Come nella tabella analoga tenuta nel sistema time-sharing modello, le voci SEND e RECEIVE scadono se restano non appaiate troppo a lungo e l'originatore viene avvisato. Le voci RECEIVE ANY vengono cancellate dalla tabella quando arriva un messaggio che le soddisfa.
L'ultima modifica necessaria per distribuire le funzioni del controllore di rete consiste nel dare a ciascun sito una porzione dei numeri unici da distribuire tramite la sua operazione UNIQUE. Approfondirò questo argomento più avanti.
Per rendere chiaro al lettore come funziona il controllore di rete distribuito, segue un esempio. I dettagli su quale processo sceglie i numeri di porta, ecc., sono soltanto esemplificativi e non costituiscono uno standard specificato nell'ambito dell'IPC.
Si supponga che, per due siti della rete, K e L, il processo A nel sito K desideri comunicare con il processo B nel sito L. Il processo B ha un RECEIVE ANY in sospeso sulla porta M.
SITE K SITE L
______ ______
/ \ / \
/ \ / \
/ \ / \
/ \ / \
| | | |
| Process A | | Process B |
| | | |
\ / \ /
\ / RECEIVE--> port M /
\ / ANY \ /
\______/ \______/
Il processo A, fortunatamente, conosce l'esistenza della porta M nel sito L e invia un messaggio usando l'operazione SEND FROM ANY dalla porta N alla porta M. Il messaggio contiene due numeri di porta e istruzioni perché il processo B invii con SEND i messaggi per il processo A dalla porta Q alla porta P. Il numero di sito del sito K è appeso a questo messaggio insieme alla porta SEND N del messaggio.
SITE K SITE L
______ ______
/ \ / \
/ \ / \
/ \ / \
/ \ / \
| | | |
| Process A | | Process B |
| | | |
\ port N / \ port M /
\ /--->SEND FROM --->\ /
\ / ANY \ /
\______/ \______/
to port M, site L
containing K,N,P, & Q
Il processo A esegue ora un RECEIVE sulla porta P dalla porta Q. Il processo A specifica il sito L come sito di incontro.
SITE K SITE L
______ ______
/ \ / \
/ \ / \
/ \ Rendezvous/ \
/ \ table \
| | | |
| Process A | ^ | Process B |
| | | | |
\ port P / | \ /
\ / | \ /
\ / <--RECEIVE __/ \ /
\______/ MESSAGE \______/
to site L
containing P, Q, & K
Un messaggio RECEIVE viene inviato dal sito K al sito L e viene inserito nella tabella di incontro del sito L. In un altro momento, il processo B esegue un SEND sulla porta P dalla porta Q, specificando il sito L come sito di incontro.
SITE K SITE L
______ ______
/ \ / \
/ \ / \
/ \ Rendezvous/ \
/ \ table \
| | | |
| Process A | | Process B |
| | | |
\ port P / <--------- port Q /
\ / \ /
\ / SEND \ /
\______/ \______/
to site L
containing P & Q
L'incontro ha luogo, la tabella di incontro viene cancellata e la trasmissione verso la porta P nel sito K si svolge. Il numero del sito SEND (e verosimilmente il numero della porta SEND) è appeso ai messaggi della trasmissione per edificazione del processo ricevente.
SITE K SITE L
______ ______
/ \ / \
/ \ / \
/ \ / \
/ \ / \
| | | |
| Process A | | Process B |
| | | |
\ port P / \ port Q /
\ /<--transmission<--\ /
\ / \ /
\______/ to port P, site K \______/
containing data and L
Il processo B può contemporaneamente desiderare di eseguire un RECEIVE dalla porta N sulla porta M.
Si noti che in questo sistema vi è un solo messaggio di controllo importante che si sposta tra i siti, il tipo di messaggio che in [2] è chiamato messaggio del protocollo Host/Host. Questo messaggio di controllo è il messaggio RECEIVE. Vi sono altri due possibili messaggi di controllo tra siti: un messaggio di errore al sito di origine quando un RECEIVE o un SEND scade, e il messaggio SEND nel raro caso in cui il sito di incontro non sia il sito SEND. Deve inoltre esistere un formato standard per i messaggi tra porte. Per esempio, quanto segue:
_________________ __________________ _____________
| rendezvous site | <6> | destination site | | source site |
|-----------------| |------------------| |-------------|
| RECEIVE port | | RECEIVE port | | RECEIVE port|
|-----------------| |------------------| |-------------|
| SEND port | | SEND port | | SEND port |
|-----------------| |------------------| |-------------|
| | | source site | | |
| | |------------------| | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| data | | data | | data |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
|_________________| |__________________| |_____________|
transmitted transmitted received
by SEND by Network by RECEIVE
process Controller process
Nel sistema time-sharing modello era possibile passare una porta da processo a processo. Ciò è ancora possibile con un controllore di rete distribuito.
Si ricordi che, perché un messaggio sia inviato da un processo a un altro, un SEND sulla porta M dalla porta N e un RECEIVE sulla porta M dalla porta N devono incontrarsi, normalmente nel sito SEND. Entrambi i processi tengono traccia di dove ritengono che sia il sito di incontro e forniscono questo sito come parametro delle operazioni appropriate. Anche il processo che esegue il RECEIVE ritiene di essere il sito SEND. Poiché, una volta che un SEND e un RECEIVE si incontrano, la trasmissione viene inviata all'origine del RECEIVE e la voce nella tabella di incontro viene cancellata e deve essere ricostituita per ogni ulteriore trasmissione da N a M, è facile spostare una porta RECEIVE. Se un processo invia sia i numeri di porta sia il numero del sito di incontro a un nuovo processo in un altro sito, il quale esegue un RECEIVE usando questi stessi vecchi numeri di porta e la stessa specifica del sito di incontro, il mittente non saprà mai che il ricevente si è spostato. È un po' più difficile spostare una porta di invio. Tuttavia, se ciò accade, la coppia di numeri di porta usata per un SEND e il numero del sito di incontro originale vengono passati al nuovo sito. Il processo nel nuovo sito SEND specifica il vecchio sito di incontro con il primo SEND dal nuovo sito. Anche il processo che esegue il RECEIVE continuerà a ritenere che il sito di incontro sia il vecchio sito, così il SEND e il RECEIVE si incontreranno nel vecchio sito. Quando si incontrano, la voce nella tabella di quel sito viene cancellata, e sia il messaggio SEND sia quello RECEIVE vengono inviati al nuovo sito SEND, esattamente come se fossero stati destinati fin dall'inizio a quel sito. Il SEND e il RECEIVE si incontrano poi di nuovo nel nuovo sito di incontro e la trasmissione può proseguire come se la porta non si fosse mai spostata. Poiché tutte le trasmissioni contengono il numero del sito di origine, i successivi RECEIVE saranno inviati al nuovo sito di incontro. È possibile scoprire che questa manipolazione speciale deve aver luogo perché un messaggio SEND viene ricevuto in un sito che non ha originato il messaggio SEND<7>. Si noti che la porta SEND e la porta RECEIVE possono spostarsi contemporaneamente.
Naturalmente, tutto ciò avrebbe potuto avvenire anche se i processi si fossero scambiati messaggi che annunciavano eventuali spostamenti e i nuovi numeri di sito.
Un problema che può essere venuto in mente al lettore è come si facciano corrispondere in dimensione i buffer SEND e RECEIVE. La soluzione più semplice sarebbe esigere che tutti i buffer abbiano una dimensione comune, ma ciò è inaccettabile poiché non si estende facilmente a una situazione in cui processi di sistemi operativi autonomi cercano di comunicare. Una seconda soluzione è che i processi si scambino messaggi che specificano le dimensioni dei buffer. Se si adotta questa soluzione, i dati in eccesso inviati dal processo SEND e che non riescono a entrare nel buffer RECEIVE vengono scartati e il processo RECEIVE viene avvisato. Questa soluzione ha grande attrattiva per la sua semplicità. Una terza soluzione sarebbe passare la dimensione del buffer RECEIVE al sito SEND insieme al messaggio RECEIVE e avvisare il processo SEND quando vengono inviati troppi dati, o persino trasmettere la dimensione del buffer RECEIVE al processo SEND. Quest'ultimo metodo consentirebbe anche al controllore di rete nel sito SEND di ricavare due o più SEND da uno solo, se ciò fosse necessario per adattarsi a una dimensione di buffer RECEIVE più piccola.
Anche la manutenzione dei numeri unici è un problema quando i processi sono distribuiti geograficamente. Qui vengono presentate tre soluzioni a questo problema. La prima possibilità è che i sistemi operativi autonomi chiedano inizialmente i numeri unici al controllore di rete e poi garantiscano l'integrità di tutti i numeri unici attualmente posseduti da processi e programmi locali, usando qualsiasi mezzo a disposizione del sistema operativo. In questo caso il controllore di rete fornirebbe un metodo per inviare un numero unico da un sito a un altro e garantirebbe per l'identità del numero nel nuovo sito. Il secondo metodo consiste semplicemente nel consegnare i numeri unici ai processi che li usano, contando sul comportamento non malevolo dei processi per preservare i numeri unici o, se dovesse capitare un incidente, sulle due parole d'ordine (i numeri di porta SEND e RECEIVE) richieste per avviare una trasmissione. Se i numeri unici vengono distribuiti in modo non sequenziale e sono ragionevolmente lunghi (diciamo 32 bit), il pericolo è scarso. Nell'ultimo metodo, un'identificazione dell'utente è inclusa nei numeri di porta e i singoli sistemi operativi garantiscono l'integrità di questi bit di identificazione. Così un processo, pur non potendo essere certo che la porta corretta stia trasmettendo verso di lui, può essere certo che stia trasmettendo qualche porta dell'utente corretto. Questo è il cosiddetto concetto di rete virtuale (virtual net) suggerito da W. Crowther [2].<8>
Un terzo problema difficile sorge quando processi remoti desiderano comunicare: il problema di mantenere connessioni ad alta larghezza di banda tra i processi remoti. La soluzione di questo problema sta nel consentire ai processi di disporre di una notevole informazione sullo stato di una trasmissione in corso. Esaminiamo dapprima in dettaglio un processo SEND. Quando un processo esegue un SEND, la parte locale del controllore di rete passa il SEND al sito di incontro, normalmente il sito locale. Quando arriva un RECEIVE corrispondente a un SEND in sospeso, il controllore di rete avvisa il processo SEND provocando un interrupt verso la locazione di ripresa specificata. Contemporaneamente il controllore di rete inizia a spedire il buffer SEND verso il sito RECEIVE. Quando la trasmissione è completa, viene posto un indicatore che il processo SEND può verificare. Mentre una trasmissione è in corso, il processo può chiedere al controllore di rete di eseguire altre operazioni, compresi altri SEND. Un secondo SEND su una coppia di porte già in fase di trasmissione viene annotato e il SEND diventa attivo non appena la prima trasmissione è completa. Un terzo SEND identico produce un messaggio di errore verso il processo che lo ha eseguito. Esaminiamo poi in dettaglio un processo RECEIVE. Quando un processo esegue un RECEIVE, il RECEIVE viene inviato al sito di incontro. Quando i dati risultanti da questo RECEIVE iniziano ad arrivare nel sito RECEIVE, il processo RECEIVE viene avvisato tramite un interrupt verso la locazione di ripresa specificata. Quando la trasmissione è completa, viene posto un indicatore che il processo RECEIVE può verificare. Un secondo RECEIVE sulla stessa coppia di porte è consentito. Un terzo produce un messaggio di errore verso il processo RECEIVE. Vi è dunque macchinario sufficiente per consentire a una coppia di processi di avere sempre sia una trasmissione in corso sia la successiva in sospeso. Pertanto non si perde efficienza. D'altro canto, ogni trasmissione deve essere preceduta da un RECEIVE in un buffer specificato, continuando così a fornire un controllo di flusso completo.