Esperimenti con message passing in C
Ho messo a vostra disposizione alcuni sorgenti che implementano in C le astrazioni di message passing sincrono, asincrono e completamente asincrono come le abbiamo viste (o vedremo presto) a lezione.
Ho messo il materiale in questo file.
La directory comprende:
- un Makefile
- suspend.[ch] è il modulo che implementa la sospensione e riattivazione dei pthread (usando il segnale SIGUSR1).
- msg.[ch] modulo di implementazione dei paradigmi di message passing.
- sender.c receiver.c: esempi di processi che si scambiano un messaggio (sender manda a receiver che risponde).
IL file msg.h spiega come usare i servizi forniti da questi sorgenti.
Per iniziare occorre dare il nome al processo durante l'inizializzazione del servizio:
void async_msg_init(char *procname);
void sync_msg_init(char *procname);
void nb_msg_init(char *procname);
IL tipo di servizio (sincrono, asincrono o completamente asincrono) viene deciso al momento della inizializzazione e non puo' piu' essere cambiato.
Per spedire un messaggio basta indicare il nome del destinatario, il buffer contenente il messaggio e la lunghezza in byte del messaggio.
ssize_t msg_send(char *dest, const void *buf, size_t len);
L'interfaccia e' simile alla system call "write" ma al posto del file descriptor c'e' il nome del destinatario. E' possibile inviare messaggi vuoti (di solito servono per indicare un acknowledgement. Al momento della spedizione il processo destinatario deve esistere, altrimenti la funzione ritorna errore. In caso di successo la funzione restituisce ilnumero di byte inviati, -1 un caso di errore.
Per ricevere un messaggio si usa la funzione msg_receive:
ssize_t msg_recv(char *sender, void *buf, size_t len);
Il campo sender può essere:
- una stringa: in questo caso viene ricevuto il primo messaggio spedito dal mittente indicato
- NULL: viene consegnato il primo messaggio ricevuto qualsiasi ne sia stato il mittente
- una variabile di tipo msg_procname con il primo byte zero (una stringa vuota di dimensione adeguata): viene consegnato il primo messaggio ricevuto qualsiasi ne sia stato il mittente e il nome del mittente viene salvato nella variabile sender.
aggiornamento Dec. 6 2016
E' stata aggiunta una funzione per ottenere il proprio nome.
void msg_myname(char *myname);
(il parametro deve essere di tipo msg_procname per essere certi che il nome non sia più lungo del buffer).
La costante MAXLEN indica la massima lunghezza dei messaggi che la libreria gestisce.
Il makefile ha ora un parametro opzionale per la compilazione dei test/tutorial "receiver" e "sender".
make clean; make MPTYPE=async
make clean; make MPTYPE=sync
make clean; make MPTYPE=nb
generano gli eseguibili di esempio per i vari paradigmi di message passing. Lanciando da due shell diverse (e.g. due finestre terminale) prima receiver in una e poi sender nell'altra si potranno osservare le stampe dei due programmi.