codice:
#include "libporto.h"
/* invia il pid di un processo */
void invia_pid(int pid, char *mit, int num_coda)
{
int num_quid;
msgpid pid_snd;
ssize_t val_snd;
num_quid = msgget(num_coda, IPC_CREAT | 0666);
pid_snd.p_npid = pid;
pid_snd.p_type = 1;
strcpy(pid_snd.mittente, mit);
val_snd = msgsnd(num_quid, &pid_snd, sizeof(msgpid) - sizeof(long), 0);
if(val_snd == -1)
printf("*** ERRORE INVIO PID ***\n");
return;
}
/* riceve il pid di un altro processo */
msgpid ricevi_pid(int num_coda)
{
msgpid pid_rcv;
ssize_t val_rcv;
int num_quid;
num_quid = msgget(num_coda, 0);
val_rcv = msgrcv(num_quid, &pid_rcv, sizeof(msgpid) - sizeof(long), 1, 0);
return pid_rcv;
}
/* crea il pool di semafori necessaria per la gestione dell'entrata ed uscita delle navi al porto */
int crea_semafori(int n, int id_sem)
{
int s_uid; //risultato della semget()
s_uid = semget(id_sem, n, IPC_CREAT | 0666);
if(s_uid == -1)
return -1;
else
return s_uid;
}
/* wait: ottiene la risorsa in mutua esclusione */
int P(int semid, int semnum)
{
struct sembuf cmd;
cmd.sem_num = semnum;
cmd.sem_op = -1;
cmd.sem_flg = 0;
return semop(semid, &cmd, 1);
}
/* gestisce il traffico nel senso unico alternato */
int S(int semid, int semnum)
{
struct sembuf cmd;
cmd.sem_num = semnum;
cmd.sem_op = 0;
cmd.sem_flg = 0;
return semop(semid, &cmd, 1);
}
/* signal: rilascia la risora */
int V(int semid, int semnum)
{
struct sembuf cmd;
cmd.sem_num = semnum;
cmd.sem_op = 1;
cmd.sem_flg = 0;
return semop(semid, &cmd, 1);
}
/* assegna in modo casuale ad ogni nave un tipo di merce */
prodotto get_carico()
{
prodotto mercanzia; //struttura con il tipo di merce
int valore; //numero casuale per assegnare una merce
srand(getpid()); //senza questo il random restituisce sempre lo stesso num
valore = rand() % 10 + 1; //assegna un valore casuale da 1 a 10 alla variabile valore
switch(valore) //inizializza il tipo di merce in base al risultato di random
{
case 1:
strcpy(mercanzia.merce, "arance");
mercanzia.attesa = ARANCE;
break;
case 2:
strcpy(mercanzia.merce, "acciaio");
mercanzia.attesa = ACCIAIO;
break;
case 3:
strcpy(mercanzia.merce, "GPL");
mercanzia.attesa = GPL;
break;
case 4:
strcpy(mercanzia.merce, "pesce");
mercanzia.attesa = PESCE;
break;
case 5:
strcpy(mercanzia.merce, "benzina");
mercanzia.attesa = BENZINA;
break;
case 6:
strcpy(mercanzia.merce, "cereali");
mercanzia.attesa = CEREALI;
break;
case 7:
strcpy(mercanzia.merce, "rifiuti");
mercanzia.attesa = RIFIUTI;
break;
case 8:
strcpy(mercanzia.merce, "banane");
mercanzia.attesa = BANANE;
break;
case 9:
strcpy(mercanzia.merce, "ferro");
mercanzia.attesa = FERRO;
break;
case 10:
strcpy(mercanzia.merce, "legname");
mercanzia.attesa = LEGNAME;
break;
default:
printf("*****ERRORE*****\n");
break;
}
return mercanzia; //restituisce il prodotto
}
/* assegna in modo casuale ad ogni nave una quantità di merce */
int get_quantita()
{
int n; //numero delle navi
srand(getpid()); //senza questo il random restituisce sempre lo stesso num
n = rand() % 1000 + 500; //assegna un valore casuale da 500 a 1000 alla variabile n
return n; //restituisce la quantità trasportata
}
/* assegna in modo casuale ad ogni nave un nome */
char *get_nomenave()
{
char name[25]; //struttura con il nome della nave
int valore; //numero casuale per assegnare un nome
srand(getpid()); //senza questo il random restituisce sempre lo stesso num
valore = rand() % 10 + 1; //assegna un valore casuale da 1 a 10 alla variabile valore
switch(valore) //inizializza il nome della nave in base al risultato di random
{
case 1:
strcpy(name, "Bismarck");
break;
case 2:
strcpy(name, "Calypso");
break;
case 3:
strcpy(name, "Endeavour");
break;
case 4:
strcpy(name, "HMS Victory");
break;
case 5:
strcpy(name, "Knock Nevis");
break;
case 6:
strcpy(name, "Moby Prince");
break;
case 7:
strcpy(name, "Principessa Mafalda");
break;
case 8:
strcpy(name, "RMS Lusitania");
break;
case 9:
strcpy(name, "Thistlegorm");
break;
case 10:
strcpy(name, "USS Constitution");
break;
default:
printf("*****ERRORE*****\n");
break;
}
return name; //restituisce il nome della nave
}
/* crea in modo casuale un numero di navi da un minimo di 1 ad un massimo di 15
int get_numnavi()
{
int n; //numero delle navi
srand(getpid()); //senza questo il random restituisce sempre lo stesso num
n = rand() % 15 + 7; //assegna un valore casuale da 1 a 15 alla variabile n
return n; //restituisce il numero di navi
}*/
/* crea una nave */
boat crea_nave(int val)
{
boat barca; //struttura con la nave da creare
int temp; //double
barca.id_nave = getpid(); //assegna all'identificatore della nave l'identificatore del processo
barca.carico = get_carico(); //assegna un tipo random di merce
strcpy(barca.nome_nave, get_nomenave()); //assegna un nome random
barca.quantita = get_quantita(); //assegna una quantità random
temp = barca.quantita/500;
barca.ore = barca.carico.attesa*temp;
printf("\n------------------------------------------------------------------------------\n");
printf(" § Identificatore nave ---> %d **\n", val); //stampa l'identificatore della nave
printf(" § Nome della nave ---> %s **\n", barca.nome_nave); //stampa il nome della nave
printf(" § Merce contenuta sulla nave ---> %s **\n", barca.carico.merce); //stampa la merce trasportata dalla nave
printf(" § Quantità di merce contenuta sulla nave ---> %d tonnellate **\n", barca.quantita); //stampa la quantità della merce
printf(" § Tempo di permanenza della nave nel porto ---> %d ore **\n", barca.ore); //stampa il tempo di scarico della merce dalla nave
printf("------------------------------------------------------------------------------\n");
fflush(stdout); //chiude lo stream
return barca; //ritorna la nave appena creata
}
/* crea la coda di messaggi necessaria per le comunicazioni tra nave e capitaneria */
int crea_codamsg()
{
int q_uid; //risultato della msgget()
q_uid = msgget(ID_CODA, IPC_CREAT | 0666);
if(q_uid == -1)
return -1;
else
return q_uid;
}
/* invia messaggi per le comunicazioni tra nave e capitaneria */
int invia_msg(int num_pid, boat barca)
{
msg sms_snd;
int val_snd;
int num_quid;
num_quid = msgget(ID_CODA, 0);
sms_snd.npid = num_pid;
sms_snd.type = 1;
sms_snd.info = barca;
val_snd = msgsnd(num_quid, &sms_snd, (sizeof(msg) - sizeof(long)), 0);
if(val_snd == -1)
{
printf("*** ERRORE INVIO MESSAGGIO ***\n");
return 0;
}
else
{
printf(" - INVIO MESSAGGIO DALLA NAVE NUMERO %d ESEGUITO CORRETTAMENTE **\n", sms_snd.npid);
return 1;
}
}
/* riceve messaggi scambiati tra nave e capitaneria */
msg ricevi_msg()
{
msg sms_rcv;
ssize_t val_rcv;
int num_quid;
num_quid = msgget(ID_CODA, 0);
val_rcv = msgrcv(num_quid, &sms_rcv, (sizeof(msg) - sizeof(long)), 1, 0);
if(val_rcv == 0)
printf("*** ERRORE RICEZIONE MESSAGGIO ***\n");
else
printf("\n - RICEZIONE MESSAGGIO DALLA NAVE NUMERO %d ESEGUITA CORRETTAMENTE **\n", sms_rcv.npid);
return sms_rcv;
}
/* crea la memoria condivisa e ne restituisce il puntatore */
boat *crea_memcond()
{
boat *s;
int shmid;
shmid = shmget(ID_MEM, sizeof(boat) - sizeof(long), IPC_CREAT | 0666);
s = (boat *) shmat(shmid, NULL, 0);
return s;
}
/* salva i messaggi nella coda di messaggi */
void salva_msg(boat *s, msg sms_nave, int n)
{
s[n] = sms_nave.info;
}
/* stampa i messaggi presenti nella coda di messaggi */
void stampa_codamsg(boat *s, int n)
{
int j;
for(j = 0; j <= n; j++)
printf(" ***la nave si chiamava %s\n", s[j].nome_nave);
}
codice:
#ifndef molo
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/wait.h>
#define molo
#define ID_CODA 1357
#define PID_CANALE 1234
#define PID_CAPITANERIA 5678
#define PID_NAVE 9012
#define SEMALT 5768
#define SEMCONT 9495
#define ID_MEM 8485
/*assegnamento tempo di scarico in ore in base a 500 tonnellate di merce*/
#define CEREALI 1
#define ARANCE 2
#define BANANE 3
#define PESCE 4
#define RIFIUTI 5
#define LEGNAME 6
#define FERRO 7
#define ACCIAIO 8
#define BENZINA 9
#define GPL 10
typedef struct {
int attesa;
char merce[25];
} prodotto;
typedef struct {
prodotto carico;
int id_nave;
int quantita; //double
int ore; //double
char nome_nave[25];
} boat;
typedef struct {
long type;
int npid;
boat info;
} msg;
typedef struct {
long p_type;
int p_npid;
char mittente[11];
} msgpid;
void invia_pid(int, char *, int);
msgpid ricevi_pid(int);
int crea_semafori(int, int);
prodotto get_carico();
int get_quantita();
char *get_nomenave();
boat crea_nave(int);
int P(int, int);
int V(int, int);
int S(int, int);
int invia_msg(int, boat);
int crea_codamsg();
msg ricevi_msg();
boat *crea_memcond();
void salva_msg(boat *, msg, int);
void stampa_codamsg(boat *, int);
#endif