Azzurra IRC Network Forum

[C]martrice statica o dinamica o memoria condivisa

viridovix · 16/08/2005 15:34 · #1
Sistema Suse 9.2, linguaggio C , compilatore gcc.
Ho realizzato un sistema di prenotazione posti per una sala cinematografica, con un processo su una macchina server che gestisce la mappa dei posti.
Ogni posto è caratterizzato da numero di fila, numero di poltrona e da un flag che indica se il posto è prenotato o meno.
Il server accetta e processa sequenzialmente le richieste prenotazioni di posti da uno o piu' client che possono essere sulla stessa macchina o in remoto(quindi macchine diverse).

Come struttura ho utilizzato una matrice statica [3][3]
Con un unico client funziona tutto perfettamente , ma quando si connette un secondo client ,questo visualizza una matrice che nn tiene conto delle prenotazioni effettuate dal primo client, e la stessa cosa vale per il primo client.
Quindi i vari client nn fanno riferimento alla stessa matrice:(
All'inizio pensavo che dipendesse dalla posizione dell chiamata alla funzione inizializza(cinema) , ma quando il secondo client si connette questa nn dovrebe essere chiamata.

Ecco (http://server4.103092804.com/Release3/linkredirect.php?h=42321,13951,1124199258) il codice del main del server:



//main server
int main(int argc,char *argv[])
{
char scelta[1];
char out[MAX_DIM];
char buff[MAX_DIM];
int ds_sock,/*ds_sock_acc,*/ret,lenght;
struct sockaddr_in server;
struct sockaddr client;
struct posto cinema[3][3];
//
inizializza_cinema(cinema);
//
system("clear" );
//qui ho omesso il codice del socket x snellire la lettura del testo

printf("in attesa di connessione da parte del client!!\n\n" );
//
//
while(1)
{
while((ds_sock_acc=accept(ds_sock,&client,&lenght)) ==-1);
printf("client connesso!!\n\n" );
if (fork()==0)
{ close(ds_sock);
do

{ strcpy(out," ");
read(ds_sock_acc,buff,MAX_DIM);
// scelta=buff;
if ((strcmp(buff,"A")==0)||(strcmp(buff,"a") ==0))
{ posti_vuoti(cinema);
//printf("%s\n",buff);
}
else if ((strcmp(buff,"B")==0)||(strcmp(buff,"b") ==0))
{
controllo_posto(cinema);
}

else if ((strcmp(buff,"C") ==0)||(strcmp(buff,"c") ==0))
{
annulla_posto(cinema);
}
else if((strcmp(buff,"D") ==0)||(strcmp(buff,"d") ==0))
{ strcpy(out,"fatto");
}

}//relativa al do
while (strcmp(out,"fatto") !=0);
//
write(ds_sock_acc,"\n\nArrivederci!!",20);
close(ds_sock_acc);
printf("Client disconnesso!!\n\n");
printf("\nIn attesa di connessione da nuovo client!!\n\n");
exit(0);

}//della fork
else close(ds_sock_acc); //è del fork==0

}//del while(1)
}//del main



La struttra posto l'ho definita cosi

struct posto
{
unsigned char idPosto[6];
int flag;
};

la funzione inizializza_cinema

void inizializza_cinema(struct posto cine[3][3])
{
unsigned char i,j,k;
k='1';
for(i='A';i<='C';i++)
{
//printf("\n");
for(j='1';j<='3';j++)
{
cine[i-'A'][j-'1'].flag=0;
cine[i-'A'][j-'1'].idPosto[0]=' ';
cine[i-'A'][j-'1'].idPosto[1]=i;
cine[i-'A'][j-'1'].idPosto[2]=j;
cine[i-'A'][j-'1'].idPosto[3]=' ';
cine[i-'A'][j-'1'].idPosto[4]='\t';
cine[i-'A'][j-'1'].idPosto[5]='\0';
}
cine[i-'A'][2].idPosto[4]='\n';
}


Non ben chiaro come procedere per risolvere. Se usare una matrice dinamica (ho il problema che la matrice l'ho dichiarata di tipo posto), memoria condivisa o tutte e due.
Spero che la discussione troppo lunga nn spaventi e che qualcuno riesca ad aiutarmi.
sottovento · 21/11/2005 14:35 · #2
Non farti imbrogliare! Nel momento che esegui la fork(), viene fatta una copia del processo, tale e quale a quella di partenza!
Questo vuol dire che viene duplicata la tabella dei descrittori degli stream aperti, ...
Viene ovviamente duplicata anche la memoria. Dal momento che fai la fork(), dunque, hai due tabelle diverse, a cui ovviamente i tuoi client fanno riferimento.

Per quello che vuoi fare, questa soluzione non va bene. Ti consiglio di ripensarci ed usare altre strutture condivise (oppure,banalmente, un file).
In alternativa, il sistema da te utilizzato supporta i thread, i quali non duplicano memoria ma la condividono. Questo ti risolve il problema.
(ovviamente la tabella diventa una risorsa condivisa, dunque dovrai fare attenzione a regolarne gli accessi con qualche meccanismo di sincronizzazione).

ciao ciao
sottovento