# Piattaforme e Software per la rete - lezione 5 #### William Fornaciari ###### 31 March 2016 ## Programmazione di rete parte 2 Server di tipo - sequenziale: una richiesta gestita alla volta - parallelo: usano un pool di processi per elaborare le richieste Per la programmazione faccio una `accept(...)` che è bloccante e ritorna quando ho un client che comunica, a quel punto faccio la fork e gestisco il client nel figlio. Statisticamente risulta più comodo creare dei server fatti da piccoli multicore, in quanto le richieste di un server di solito non sono intensive di calcolo ma con tante richieste parallele. Per questo ultimamente vengono usati server blade che montano molte cpu ARM che a pari di potenza di calcolo parallelo consumano meno 9:1 Per questo si parla di computer continuum, (es: progetto montblanc). ## Inter-process Communication Per comunicazione tra processi su una stessa macchina si può usare shared memory come nel mulithtreading. Per comunicazione tra pocessori distanti o diversi ci sono problemi di compatibilità su piattaforme diverse, e java in questo caso non può essere una soluzione perchè non è abbastanza efficiente per sistemi emebedded. IPC methods - message passing - signals - pipes - message passing classico (sockets, RPC...) Come aspetti prestazionali sono diversi ma come semantica sono intercambiabili. Metodi di __Message Passing__ evita problemi di *memoria condivisa* nei sistemi multicore Di solito viene implementato prima del resto quando si realizza una nuova architettura. La __comunicazione asincrona__ a differenza di quella bloccante ha bisogno di un buffer. Una __comunicazione sincrona__ non ha bisogno di buffer ed è *esplicitamente sincronizzata* Normalmente la `send()` non è bloccante mentre la `receive()` lo è, in caso di comunicazione sincrona, sia `send()` che `receive()` sono bloccanti, quest'ultimo modo di comunicazione si chiama *rendez-vous*. #### Addressing in Message Passing Posso avere una destinazione esplicita per i messaggi, che però va fissata nel codice o scelta durante la compilazione, mentre se non si conosce il destinatario si può usare un meccanismo a __mailbox__ o __port__ che è la variante con un solo lettore per mailbox Di solito la porta viene distrutta quando il processo owner termina. #### Message Format Generalmente consiste in - Header: contiene informazioni su destinazione e controllo - Body o Payload: contiene i dati inviati nel messaggio. Altre soluzioni sono quelle __produttore/consumatore__ ### Unix Pipes è molto efficiente in termine di cicli macchina, presenta mutua esclusione (può accederci un solo processo alla volta) il produttore è bloccato se non c'è spazio. Vengono gestite come dei file, con la primitiva `pipe()` ``` int p[2]; if(pipe(p) == -1) print(error); ``` In questo modo ho due pipe, posso usare `pipe[0]` per scrivere e `pipe[1]` per leggere Inizialmente posso leggere e scrivere la pipe dallo stesso processo in modo __loopback__ Posso usare le pipe per comunicare tra padre e figlio, ma devo gestirlo bene, altrimenti entrambi leggono e scrivono sulla stessa pipe. Quindi mi serve chiudere uno dei due pipe nel padre e nel figlio con `close(p[0])` o `close(p[1])` Rispettivamente nel padre e nel figlio o viceversa, in modo da avere una comunicazione normale. Una chiusura non pulita di una pipe può portare a un errore `broken pipe`.