No no !! posterò delle parti di codice. Prima però spiego come funziona l'applicativo.
L'applicativo è una simulazione di un' asta di vendita:
Un processo (banditore) comunica ad N processi (partecipanti) di voler vendere un oggetto.
Gli N processi, una volta ricevuta la comunicazione, generano un numero casuale (l'offerta) e la inviano al banditore.
Il banditore cerca l'offerta più alta, e una volta trovata, comunica a tutti partecipanti il pid del vincitore e l'offerta vincente.
NB: la comunicazione tra banditore e partecipanti può avvenire o con code di mesaggi o con memoria condivisa. Tuttavia almeno uno dei partecipanti comunica con il banditore con memoria condivisa e almeno uno dei restanti con code di messaggi.
Allora ho realizzato l'applicazione creando i seguenti file:
1. functions_lib.c e functions_lib.h
2. init.c // inizializza le risorse di comunicazione
3. bandit.c // file con processo banditore
4. partecipants.c file con i processi partecipanti
5. play.c // avvia i file init, bandit e partecipants
per gestire le risorse di comunicazione ho creato dei file appositi semaphore_null.h memory_null.h memory_null2.h e queue.h, questi file " restituiscono" le chiavi di accesso alle risorse:
// la costante MUTEX_PATH l'ho definita sul file functions_lib.h
#define MUTEX_PATH "/src_code/semaphore_null.h"
key_t semKeyMutex = ftok(MUTEX_PATH, 1);
int mutex_box = semget(semKeyMutex,1,0666);
vi posto il codice dei pasrtecipanti, perchè è quello che mi da più errori:
#include "functions_lib.h"
#define RES_PERM 0666
/*
la funzione makeOffer#() prende come parametro il pid del processo j-esimo
processo
*/
void makeOffer1(pid_t pid);
void makeOffer2(pid_t pid);
void makeOffer3(pid_t pid);
int main(){
int n = PARTECIPANTS;
int wait_player = 0; // per attendere che termini il player (processo figlio)
int wait_parent = 0; // per attendere che il padre termini
int wait_end = 0;
int j;
for(j=0; j<n; j++){
pid_t player;
player = fork();
if(player < 0){
//printf("Error on %d child creation\n");
//strerror(errno);
perror("fork: ");
exit(-1);
}
if(player == 0){ // processo figlio (il partecipante)
//if(j == 0) // il primo processo fa l'offerta tramite la coda di messaggi
makeOffer3(player);
//else if(j == 1) // il secondo processo fa l'offerta sulla memoria condivisa SHARED_MEMORY1
makeOffer1(player);
//else // i restanti N-2 processi comunicano con il banditore attraverso la SHARED_MEMORY
makeOffer2(player);
if(wait_player)
sleep(wait_player);
//printf("Partecipant %d parent %d exiting\n");
exit(0);
}
else{ //processo padre
if(wait_parent)
sleep(wait_parent);
//printf("Go to next partecipant\n");
}
/*
int i;
int *returnValue = NULL;
int error = 0;
for(i=0; i<n; i++){
wait(returnValue);
if(returnValue < 0)
error = 1;
}
*/
}
if(wait_end)
sleep(wait_end);
return 0;
}
void makeOffer1(pid_t pid){
key_t semKeyRead;
semKeyRead = ftok(PATH_READ, 1);
int read = semget(semKeyRead,1, IPC_CREAT | IPC_EXCL | RES_PERM);
if(read < 0){
printf("semget for semaphore read failed!");
exit(-1);
}
key_t semKeyWright;
semKeyWright = ftok(PATH_WRIGHT, 1);
int wright = semget(semKeyWright,1, IPC_CREAT | IPC_EXCL | RES_PERM);
if(wright < 0){
printf("semget for semaphore wright failed!");
exit(-1);
}
key_t semKeyAnswer;
semKeyAnswer = ftok(PATH_ANSWER, 1);
int answer = semget(semKeyAnswer,1, IPC_CREAT | IPC_EXCL | RES_PERM);
if(answer < 0){
printf("semget for semaphore answer failed!");
exit(-1);
}
key_t semKeyMutex;
semKeyMutex = ftok(MUTEX_PATH, 1);
int mutex_box = semget(semKeyMutex,1, IPC_CREAT | IPC_EXCL | RES_PERM);
if(mutex_box < 0){
printf("semget for semaphore mutex_box failed!");
exit(-1);
}
key_t shmKeyBox2;
shmKeyBox2 = ftok(SHARED_MEMORY1, 1);
int box_2 = shmget(shmKeyBox2, sizeof(int), IPC_CREAT | IPC_EXCL | RES_PERM);
if(box_2 < 0){
perror("shmget SHARED_MEMORY1: ");
exit(-1);
}
int *ptr_box2 = (int *)shmat(box_2,NULL,0);
if(ptr_box2 < 0){
perror("shmat shared memory 2 (for a single partecipant): ");
exit(-1);
}
int offer = offerGenerator();
pid = getpid();
waitSem(mutex_box);
ptr_box2[0] = offer;
ptr_box2[1] = pid;
signalSem(wright);
waitSem(read);
signalSem(mutex_box);
waitSem(answer);
//a questo punto il banditore ha inserito nella memoria condivisa i dati del vincitore
int offer_win = ptr_box2[0];
int winner = ptr_box2[1];
//solo chi ha vinto stampa il risultato
if(winner == pid) {
printf("\nSono il processo %d e ho acquistato con un'offerta di %d\n\n",winner, offer_win);
}
}
void makeOffer2(pid_t pid){
// allaccio con i semafori
key_t semKeyRead;
semKeyRead = ftok(PATH_READ, 1);
int read = semget(semKeyRead,1, IPC_CREAT | IPC_EXCL | RES_PERM);
if(read < 0){
printf("semget for semaphore read failed!");
exit(-1);
}
key_t semKeyWright;
semKeyWright = ftok(PATH_WRIGHT, 1);
int wright = semget(semKeyWright,1, IPC_CREAT | IPC_EXCL | RES_PERM);
if(wright < 0){
printf("semget for semaphore wright failed!");
exit(-1);
}
key_t semKeyAnswer;
semKeyAnswer = ftok(PATH_ANSWER, 1);
int answer = semget(semKeyAnswer,1, IPC_CREAT | IPC_EXCL | RES_PERM);
if(answer < 0){
printf("semget for semaphore answer failed!");
exit(-1);
}
key_t semKeyMutex;
semKeyMutex = ftok(MUTEX_PATH, 1);
int mutex_box = semget(semKeyMutex,1, IPC_CREAT | IPC_EXCL | RES_PERM);
if(mutex_box < 0){
printf("semget for semaphore mutex_box failed!");
exit(-1);
}
key_t shmKeyBox1;
shmKeyBox1 = ftok(SHARED_MEMORY, 1);
int box_1 = shmget(shmKeyBox1, 8*sizeof(int), 0);
if(box_1 < 0){
perror("shmget SHARED_MEMORY: ");
exit(-1);
}
int *ptr_box1 = (int *)shmat(box_1,NULL,0);
if(ptr_box1 < 0){
perror("shmat shared memory: ");
exit(-1);
}
int offer = offerGenerator();
pid = getpid();
waitSem(mutex_box);
ptr_box1[0] = offer;
ptr_box1[1] = pid;
signalSem(wright);
waitSem(read);
signalSem(mutex_box);
waitSem(answer);
int offer_win = ptr_box1[0];
int winner = ptr_box1[1];
if(winner == pid) {
printf("\nSono il processo %d e ho acquistato l'oggetto con un'offerta di %d\n\n", winner, offer_win);
}
}
void makeOffer3(pid_t pid){
/* coda di messaggi */
key_t msgKey;
msgKey = ftok(QUEUE_MSG, 1);
int msg_queue = createQueue(msgKey);
if(msg_queue < 0){
printf("Error creation queue is failed!!");
exit(-1);
}
int offer = offerGenerator();
pid = getpid();
/* invio del messaggio */
message *msg = malloc(sizeof(message));
msg->msgdata[0] = offer;
msg->msgdata[1] = pid;
wrightMsg(msg_queue, msg, msg->msgdata[0], msg->msgdata[1]);
/* ricezione del messaggio */
msgWin *msg_winner = malloc(sizeof(msgWin));
readMsgWinner(msg_queue, msg_winner);
int offer_win = msg_winner->msgdata[0];
int winner = msg_winner->msgdata[1];
if(winner == pid) {
printf("\nSono il processo in coda %d e ho acquistato l'oggetto con un'offerta di %d\n\n",winner, offer_win);
}
}
le funzioni makeOffer(pid_t pid); prendono per parametro il pid del processo j-esimo, che verrà inserito nelle memorie e nella coda e verrà inviato al banditore, insieme all'offerta.