Newsgroup: it.comp.os.linux.development
Titolo: [C linux ] matrice statica,dinamica,memoria condivisa

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 il codice del main del server:
[CODE]
//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
[/CODE]
La struttra posto l'ho definita cosi
struct posto
{
  unsigned char idPosto[6];
  int flag;
};
la funzione inizializza_cinema
[CODE]
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';
   }
[/CODE]
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.
-----
Msg posted via: 
http://www.TechEye.it

 for(j='1';j<='3';j++)
Perdonami ma io sono per i linguaggi fortemente tipizzati e per me 
incrementare di uno un carattere non ha senso...
Alex



-----
Msg posted via: 
http://www.TechEye.it
Buono   il suggerimento per le strutture, se riesco a risolvere il problema
principale 
lo finalizzo.
Nel main c'è la dichiarazione struct posto cinema[3][3].
Purtroppo devo trovare il modo di modificare il codice e memorizzare la matrice
in 
memoria condivisa e sincronizzarla con un semaforo mutex(per impedire che
un 
client acceda mentre già un altro sta prenotando).
Solo nn ho benchiaro come procedere e se posso lasciare la matrice statica

 Quindi i vari client nn fanno riferimento alla stessa matrice:(
Quando fai una fork tutte le variabili del processo vengono COPIATE nel
nuovo processo figlio, da questo punto in poi sono come due variabili
differenti, quindi la modifica della matrice in un processo non modifica la
matrice di un altro processo (essendo di fatto due varibili diverse, in
spazi di indirizzamento completamente diversi).
Occorre quindi che il processo server "padre" crei uno spazio di memoria
condivisa capace di contenere la tua matrice e che ogni processo figlio
punti a quell'area di memoria condivisa.
vedi il man di queste funzioni o cmq cerca in internet per i parametri
la logica è la seguente:
shared_mem_des = shm_open() -> per creare un descrittore di mem condivisa
ftruncate(shared_mem_des,dimensione) -> per settare la dimensione della mem
condivisa
puntatore = mmap -> per mappare in memoria la memoria condivisa nella
memoria del processo
matrice = (struct matrice *)puntatore
ora puoi lavorare su matrice e le modifiche saranno leggibili in tutti i
processi chesono collegati alla memoria condisa.
per creare un semaforo binario
effettua una
sem_open (...) con valore 1
e prima di ogni modifica all amatrice chiami sem_wait(semaforo)
e dopo la modfica chiami sem_post(semaforo)
Ovviamente non è una spiegazione esaustiva, ma spero che cercando in
internet tu possa risovlvere i tuoi problemi (sono argomenti molto corposi)
--------------------------------
Inviato via 
http://arianna.libero.it/usenet/

 
Suggerirei all'OP di utilizzare la libmm. 
(Basta installare il pachetto libmm* appropriato e consultare la 
documentazione con "man mm".)
Max

ringrazio tutti x l'aiuto, per l'uso di   u nsemaforo mutex penso di aver
ottenuto u 
ndiscreto successo, ora tutti i processi si connettono, ma solo il primo
nn va in 
sleep. (anche se poi gli altri nn seguono l'ordine di connessione strano,
intendo 
che nn appena il primo processo si disconnette un altro prende i lsuo posto
ma nn 
è il secondo che si è connesso , ma magati il terzo o quarto).
Per saggiare l'uso della memoria condivisa  ho realizzato un semplice proramma
(client/server concorrente) x l'invio di stringhe da client  a server.
Tuttavia mi rimane il problema di come mettere la matrice che ho creato in
maniera 
statica, nella memoria condivisa, in modo che le modifiche siano visibili
a tutti i 
processi figli.
Ci sarà un modo x memorizzarla in memoria condivisa ed accedere cmq agli
elementi usando poi gli indici?!

 elementi usando poi gli indici?!
prova a cercare in questo gruppo di discussione "implementazione memoria
condivisa" vedi se puņ esserti utile.


Inviato via 
http://arianna.libero.it/usenet/
Il problema della memoria condivisa l'ho risolto purtroppo ho riscontrato
un 
problema con send e recv quando uso i processi client e server in remoto(
e nn 
simulo invece sulla stessa macchina come facevo prima).
Ho creato un nuovo post in proposito.
Grazie x l'aiuto :)
