questo è il file canale.c
codice:
#include "libporto.h"
int senso_unico; //indirizzo del pool di semafori del senso unico alternato
/* gestore del segnale */
void handler_int(int num_segnale) {
if (semctl(senso_unico, 0, GETVAL, 0) == 1)
{
printf("\n------------------------------\n");
printf("ENTRATA NAVI NEL PORTO\n");
printf("------------------------------\n");
semctl(senso_unico, 0, SETVAL, 0); //semaforo entrata porto: verde
semctl(senso_unico, 1, SETVAL, 1); //semaforo uscita porto: rosso
}
else
{
printf("\n------------------------------\n");
printf("USCITA NAVI DAL PORTO\n");
printf("------------------------------\n");
semctl(senso_unico, 0, SETVAL, 1); //semaforo entrata porto: rosso
semctl(senso_unico, 1, SETVAL, 0); //semaforo uscita porto: verde
}
}
/* main */
int main()
{
int pid_capitaneria; //pid della capitaneria
int pid_nave; //pid della nave
msgpid capitaneria_pid; //messaggio con pid della capitaneria
msgpid nave_pid; //messaggio con pid della nave
printf("Il pid di canale è: %d\n", getpid()); //stampa il pid del processo
invia_pid(getpid(), "CANALE", PID_CANALE); //invia il pid agli altri processi
invia_pid(getpid(), "CANALE", PID_CANALE);
printf("Attendo i pid degli altri due processi\n");
//esegue finché non ottiene i pid dei due processi complementari
do{
if(strcmp(capitaneria_pid.mittente, "CAPITANERIA") != 0)
{
capitaneria_pid = ricevi_pid(PID_CAPITANERIA); //riceve il messaggio
pid_capitaneria = capitaneria_pid.p_npid; //assegna il pid
}
if(strcmp(nave_pid.mittente, "NAVE") != 0)
{
nave_pid = ricevi_pid(PID_NAVE); //riceve il messaggio
pid_nave = nave_pid.p_npid; //assegna il pid
}
} while(strcmp(capitaneria_pid.mittente, "CAPITANERIA") != 0 || strcmp(nave_pid.mittente, "NAVE") != 0);
printf("PID_CAPITANERIA è %d\n", pid_capitaneria);
printf("PID_NAVE è %d\n", pid_nave);
senso_unico = crea_semafori(2, SEMALT);
semctl(senso_unico, 0, SETVAL, 1); //entrata verde
semctl(senso_unico, 1, SETVAL, 0); //uscita rosso
signal(SIGALRM, handler_int);
while(1){
alarm(3);
sleep(1000);
}
return 0;
}
questo è il file capitaneria.c
codice:
#include "libporto.h"
msg dati_nave; //contiene il messaggio ricevuto dalla nave
boat *mem_cond; //puntatore alla memoria condivisa
int i = 0; //indice per la memoria condivisa
/* gestore del segnale */
void handler_int(int num_segnale)
{
dati_nave = ricevi_msg(); //riceve il messaggio da nave
printf(" $ La nave <%s> trasporta %d tonnellate di %s e attenderà nel porto per %d ore\n", dati_nave.info.nome_nave, dati_nave.info.quantita, dati_nave.info.carico.merce, dati_nave.info.ore);
salva_msg(mem_cond, dati_nave, i);
i++;
}
/* main */
int main()
{
int pid_canale; //pid del canale
int pid_nave; //pid della nave
msgpid canale_pid; //messaggio con pid del canale
msgpid nave_pid; //messaggio con pid dela nave
int coda; //variabile di controllo per la coda messaggi
mem_cond = crea_memcond();
coda = crea_codamsg();
if(coda == -1)
{
printf("*** ERRORE CREAZIONE CODA MESSAGGI ***");
return 0;
}
printf("Il pid di capitaneria è: %d\n", getpid()); //stampa il pid del processo
invia_pid(getpid(), "CAPITANERIA", PID_CAPITANERIA); //invia il pid agli altri processi
invia_pid(getpid(), "CAPITANERIA", PID_CAPITANERIA);
printf("Attendo i pid degli altri due processi\n");
//esegue finché non ottiene i pid dei due processi complementari
do{
if(strcmp(canale_pid.mittente, "CANALE") != 0)
{
canale_pid = ricevi_pid(PID_CANALE); //riceve il messaggio
pid_canale = canale_pid.p_npid; //assegna il pid
}
if(strcmp(nave_pid.mittente, "NAVE") != 0)
{
nave_pid = ricevi_pid(PID_NAVE); //riceve il messaggio
pid_nave = nave_pid.p_npid; //assegna il pid
}
} while(strcmp(canale_pid.mittente, "CANALE") != 0 || strcmp(nave_pid.mittente, "NAVE") != 0);
printf("PID_CANALE è %d\n", pid_canale);
printf("PID_NAVE è %d\n", pid_nave);
signal(SIGINT, handler_int);
while(1){
sleep(1000);
}
return 0;
}
questo è il file nave.c
codice:
#include "libporto.h"
int main()
{
int pid_canale; //pid del canale
int pid_capitaneria; //pid della capitaneria
int num_navi; //numero di navi create
int i; //indice per il ciclo for
int pid; //pid per la fork()
int wait_son; //wait()
int senso_unico; //indirizzo del pool di semafori del senso unico alternato
int sem_cont; //indirizzo del semaforo contatore
boat nave; //struttura contenente i dati della nave
msgpid canale_pid; //messaggio con pid del canale
msgpid capitaneria_pid; //messaggio con pid della capitaneria
sem_cont = crea_semafori(1, SEMCONT); //crea il semaforo contatore
semctl(sem_cont, 0, SETVAL, 10); //inizializza il semaforo contatore
printf("Il pid di nave è: %d\n", getpid()); //stampa il pid del processo
invia_pid(getpid(), "NAVE", PID_NAVE); //invia il pid agli altri processi
invia_pid(getpid(), "NAVE", PID_NAVE);
printf("Attendo i pid degli altri due processi\n");
printf("Quante navi vuoi gestire? ");
scanf("%d", &num_navi);
//esegue finché non ottiene i pid dei due processi complementari
do{
if(strcmp(canale_pid.mittente, "CANALE") != 0)
{
canale_pid = ricevi_pid(PID_CANALE); //riceve il messaggio
pid_canale = canale_pid.p_npid; //assegna il pid
}
if(strcmp(capitaneria_pid.mittente, "CAPITANERIA") != 0)
{
capitaneria_pid = ricevi_pid(PID_CAPITANERIA); //riceve il messaggio
pid_capitaneria = capitaneria_pid.p_npid; //assegna il pid
}
} while(strcmp(canale_pid.mittente, "CANALE") != 0 || strcmp(capitaneria_pid.mittente, "CAPITANERIA") != 0);
printf("PID_CANALE è %d\n", pid_canale);
printf("PID_CAPITANERIA è %d\n", pid_capitaneria);
senso_unico = semget(SEMALT, 0, 0);
for(i = 1; i <= num_navi;) //ciclo for necessario per creare i processi figlio
{ //APERTURA FOR
pid = fork(); //fork() su pid per creare il figlio
if(pid) //if(pid != 0) entro nel codice del processo padre
{ //APERTURA IF-THEN(1)
printf("SUN EL PARE\n");
i++; //incremento l'indice del ciclo for per evitare il loop
fflush(stdout); //chiude lo stream
wait_son = wait(0); //il processo padre aspetta la terminazione del processo figlio
fflush(stdout); //chiude lo stream
} //CHIUSURA IF-THEN(1)
else //if(pid == 0) entro nel codice del processo figlio
{ //APERTURA IF-ELSE(1)
printf("SONO IL FIGLIO\n");
S(senso_unico, 0); //controllo per l'accesso al porto
P(sem_cont, 0); //decremento il valore del semaforo
nave = crea_nave(i); //creazione della nave
invia_msg(getpid(), nave); //invio messaggio a capitaneria
kill(pid_capitaneria, SIGINT); //uccide il processo
sleep(nave.ore);
//S(senso_unico, 1);
//V(sem_cont, 0);
i = num_navi + 1; //incremento dell'indice per l'uscita dal ciclo
fflush(stdout); //chiude lo stream
} //CHIUSURA IF-ELSE(1)
} //CHIUSURA FOR
return 0;
}