Visualizzazione dei risultati da 1 a 4 su 4
  1. #1

    [C - LINUX] Memoria Condivisa

    Salve a tutti!
    Purtroppo sono molto arrugginito per quanto riguarda la programmazione e sicuramente sto facendo un errore stupido che non riesco a notare.
    Riguarda l'aggancio della memoria condivisa ad un vettore, il quale deve essere letto sia dal main che da altre funzioni per eseguire il compito del codice.

    Il codice in questione fa parte di un sistema client-server e nella fattispecie è il server, il quale genera i figli che comunicheranno con i client: il complesso client-server si occupa ti passare dei pacchetti di numeri e, tramite crivello di Eratostene, di scovare i numeri primi da rimandare al server.

    Vorrei chiedervi gentilmente due cose:

    1. in che modo agganciare il vettore addr_mem[], come devo inizializzarlo senza che mi dia errore;

    2. se poteste dare un'occhiata alla dichiarazione delle variabili locali/globali e dirmi se sia corretta.

    Posto il codice qui di seguito. Scusate il disturbo,
    Geggio.



    #include <netdb.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <fcntl.h>
    #include <signal.h>
    #include <sys/types.h>
    #include <sys/shm.h>
    #include <sys/ipc.h>
    #include <sys/msg.h>
    #include <sys/sem.h>
    #include <sys/socket.h>
    #include <netinet/in.h>

    void lancia_client(int);
    void ricevi();
    void gestione_mancanti();
    void ordina_primi();
    void scrivi_file();
    int crea_sh_mem(key_t,int);
    void *alloca_sh_mem(int);
    void dealloca_sh_mem(void*);
    void elimina_sh_mem(int);
    int crea_init_sem(key_t,int);
    void elimina_sm(int);
    int sem_wait(int);
    int sem_signal(int);
    void inizializza_connessione();
    int instaur_connessione();
    void terminazione();

    int porta,
    primo,
    ultimo,
    dim,
    sem,
    addrlen,
    ds_sock,
    ds_sock_acc,
    id_sh_mem;

    struct sockaddr_in my_addr;
    struct sockaddr addr;

    char buffer[20];

    main(int argc,char* argv[])
    {
    div_t
    divisione,
    dim_mem;

    int
    status,
    chiave_sem,
    chiave_memoria,
    n_pac,
    i,
    id_shmem;


    porta=atoi(argv[1]);
    primo=atoi(argv[2]);
    ultimo=atoi(argv[3]);
    dim=atoi(argv[4]);

    divisione=div((ultimo-primo),dim);
    dim_mem=div((ultimo-primo),2);
    chiave_memoria=10;
    chiave_sem=20;

    id_shmem=crea_sh_mem(chiave_memoria,(dim_mem.quot) *sizeof(int));
    addr_mem=alloca_sh_mem(id_shmem);
    sem=crea_init_sem(chiave_sem,1);
    addr_mem[0]=1;

    signal(SIGHUP,terminazione);
    signal(SIGINT,terminazione);
    signal(SIGQUIT,terminazione);

    n_pac=divisione.quot;

    if(divisione.rem!=0)
    n_pac++;
    inizializza_connessione();
    i=primo;

    while (i<ultimo)
    {
    if (instaura_connessione()>0)
    {
    printf("CONNESSIONE INSTAURATA\n");
    switch (fork())
    {
    case -1:{printf("ERRORE NELLA FORK\n"); exit(0);}
    case 0:lancia_client(0);
    default:close(ds_sock_acc);
    }
    i=i+dim;
    }
    else
    {
    printf("CONNESSIONE FALLITA\n");
    exit(1);
    }
    }

    for (i=0;i<n_pac;i++)
    wait(&status);

    gestione_mancanti();
    close(ds_sock);

    for (i=0;i<n_pac;i++)
    wait(&status);

    for (i=1;i<addr_mem[0];i++)
    printf("%d ",addr_mem[i]);

    ordina_primi();
    scrivi_file();
    dealloca_sh_mem(addr_mem);
    elimina_sh_mem(id_shmem);
    elimina_sem(sem);
    exit(0);
    }


    void lancia_client(int inizio)
    {
    int
    ultimo_loc,
    i;
    close(ds_sock);
    if (inizio<0)
    {
    sprintf(buffer,"%d",-inizio);
    write(ds_sock_acc,buffer,20);
    ultimo_loc=((div(-inizio-primo,dim)).quot+1)*dim-1;
    if (ultimo_loc>ultimo)
    ultimo_loc=ultimo;
    sprintf(buffer,"%d",ultimo_loc);
    write(ds_sock_acc,buffer,20);
    }
    else
    {
    sprintf(buffer,"%d",i);
    write(ds_sock_acc,buffer,20);
    if (i+dim<ultimo)
    i+=dim-1;
    else
    i=ultimo;
    sprintf(buffer,"%d",i);
    write(ds_sock_acc,buffer,20);
    }
    ricevi();
    close(ds_sock_acc);
    exit(0);
    }


    void ricevi()
    {
    read(ds_sock_acc,buffer,20);
    while ((strcmp(buffer,"fine")!=0)&&(strcmp(buffer,"inter rupt")!=0))
    {
    sem_wait(sem);
    addr_mem[addr_mem[0]]=atoi(buffer);
    addr_mem[0]++;
    sem_signal(sem);
    read(ds_sock_acc,buffer,20);
    }
    if (strcmp(buffer,"interrupt")==0)
    {
    read(ds_sock_acc,buffer,20);
    printf("INTERRUZIONE: RICEVO %s",buffer);
    sem_wait(sem);
    addr_mem[addr_mem[0]]=-atoi(buffer);
    addr_mem[0]++;
    sem_signal(sem);
    }
    }


    void gestione_mancanti()
    {
    int j;
    for (j=1;j<addr_mem[0];j++)
    if (addr_mem[j]<0)
    {
    if(instaura_connessione()>0)
    {
    printf("CONNESSIONE INSTAURATA PER INTERRUZIONE\n");
    switch (fork())
    {
    case -1:{printf("ERRORE NELLA FORK\n");exit(0);}
    case 0:lancia_client(addr_mem[j]);
    default:close(ds_sock_acc);
    }
    }
    else
    {
    printf("CONNESSIONE FALLITA\n");
    exit(1);
    }
    sem_wait(sem);
    addr_mem[j]=0;
    sem_signal(sem);
    }
    }


    void ordina_primi()
    {
    int
    i,
    j,
    tmp;
    for(i=1;i<addr_mem[0]-1;i++)
    for(j=i+1;j<addr_mem[0];j++)
    if (addr_mem[j]<addr_mem[i])
    {
    tmp=addr_mem[j];
    addr_mem[j]=addr_mem[i];
    addr_mem[i]=tmp;
    }
    }


    void scrivi_file()
    {
    int fd,
    i;
    fd=open("numeri.primi",O_WRONLY|O_CREAT|O_TRUNC,06 66);
    for (i=1;i<addr_mem[0];i++)
    if ((addr_mem[i]!=0)&&(addr_mem[i]!=addr_mem[i-1]))
    {
    sprintf (buffer,"%d\n",addr_mem[i]);
    write(fd,buffer,strlen(buffer));
    }
    close(fd);
    }


    int crea_sh_mem(key_t chiave,int n_byte)
    {
    id_sh_mem=shmget(chiave,n_byte,IPC_CREAT|0666);
    if (id_sh_mem==-1)
    {
    printf("IMPOSSIBILE CREARE MEMORIA CONDIVISA CON CHIAVE %d\n",chiave);
    exit(1);
    }
    return(id_sh_mem);
    }


    void* alloca_sh_mem(int id_sh_mem)
    {
    void* sh_mem_addr;

    sh_mem_addr=shmat(id_sh_mem,0,SHM_RND);
    if (sh_mem_addr==(void*)-1)
    {
    printf("IMPOSSIBILE ALLOCARE LA MEMORIA CONDIVISA\n");
    exit(1);
    }
    return(sh_mem_addr);
    }


    void dealloca_sh_mem (void *sh_mem_addr)
    {
    if (shmdt(sh_mem_addr)==-1)
    {
    printf("IMPOSSIBILE DEALLOCARE LA MEMORIA CONDIVISA\n");
    exit(1);
    }
    }


    void elimina_sh_mem(int id_sh_mem)
    {
    if (shmctl(id_sh_mem,IPC_RMID,NULL)==-1)
    {
    printf("IMPOSSIBILE ELIMINARE LA MEMORIA CONDIVISA\n");
    exit(1);
    }
    }


    int crea_init_sem(key_t chiave, int val)
    {
    sem=semget(chiave,1,IPC_CREAT|0666);
    if (sem==-1)
    {
    printf("IMPOSSIBILE CREARE IL SEMAFORO\n");
    exit(1);

    }
    semctl(sem,0,SETVAL,val);
    return(sem);
    }


    void elimina_sem(int id_sem)
    {
    if (semctl(id_sem,IPC_RMID,0)==-1)
    {
    printf("IMPOSSIBILE ELIMINARE IL SEMAFORO\n");
    exit (1) ;
    }
    }


    int sem_wait(int sem)
    {
    struct sembuf operazione[1]={{0,-1,0}};
    return semop(sem,operazione,1);
    }


    int sem_signal(int sem)
    {
    struct sembuf operazione[1]={{0,+1,0}};
    return semop(sem,operazione,1);
    }


    void inizializza_connessione()
    {
    ds_sock=socket(AF_INET,SOCK_STREAM,0);
    if(ds_sock==-1)
    exit(1);
    my_addr.sin_family=AF_INET;
    my_addr.sin_port=porta;
    my_addr.sin_addr.s_addr=INADDR_ANY;
    if(bind(ds_sock,&my_addr,sizeof(my_addr))<0)
    exit(1);
    listen(ds_sock,3);
    }


    int instaura_connessione()
    {
    printf("TENTATIVO DI CONNESSIONE\n");
    ds_sock_acc=accept(ds_sock,&addr,&addrlen);
    return(ds_sock_acc);
    }


    void terminazione()
    {
    sem_wait(sem);
    ordina_primi();
    scrivi_file();
    kill(-1,SIGKILL);
    }

  2. #2
    Utente di HTML.it L'avatar di Stoicenko
    Registrato dal
    Feb 2004
    Messaggi
    2,254
    Usa i tag code o php.. così il codice è illeggibile..

  3. #3
    Scusa,ma sono neofita dei forum,ho provato a riscreverlo,puoi dargli un occhiata ora?

    Grazie in anticipo!!!!!!!!!!!!!!!!

    #include <netdb.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <fcntl.h>
    #include <signal.h>
    #include <sys/types.h>
    #include <sys/shm.h>
    #include <sys/ipc.h>
    #include <sys/msg.h>
    #include <sys/sem.h>
    #include <sys/socket.h>
    #include <netinet/in.h>

    void lancia_client(int);
    void ricevi();
    void gestione_mancanti();
    void ordina_primi();
    void scrivi_file();
    int crea_sh_mem(key_t,int);
    void *alloca_sh_mem(int);
    void dealloca_sh_mem(void*);
    void elimina_sh_mem(int);
    int crea_init_sem(key_t,int);
    void elimina_sm(int);
    int sem_wait(int);
    int sem_signal(int);
    void inizializza_connessione();
    int instaur_connessione();
    void terminazione();

    int porta,
    primo,
    ultimo,
    dim,
    sem,
    addrlen,
    ds_sock,
    ds_sock_acc,
    id_sh_mem;

    struct sockaddr_in my_addr;
    struct sockaddr addr;

    char buffer[20];

    main(int argc,char* argv[])
    {div_t divisione,dim_mem;

    int status,chiave_sem,chiave_memoria,n_pac,i,id_shmem;

    porta=atoi(argv[1]);
    primo=atoi(argv[2]);
    ultimo=atoi(argv[3]);
    dim=atoi(argv[4]);
    divisione=div((ultimo-primo),dim);
    dim_mem=div((ultimo-primo),2);
    chiave_memoria=10;
    chiave_sem=20;
    id_shmem=crea_sh_mem(chiave_memoria,(dim_mem.quot) *sizeof(int));
    addr_mem=alloca_sh_mem(id_shmem);
    sem=crea_init_sem(chiave_sem,1);
    addr_mem[0]=1;
    signal(SIGHUP,terminazione);
    signal(SIGINT,terminazione);
    signal(SIGQUIT,terminazione);
    n_pac=divisione.quot;
    if(divisione.rem!=0) n_pac++;
    inizializza_connessione();
    i=primo;
    while (i<ultimo)
    {if (instaura_connessione()>0)
    {printf("CONNESSIONE INSTAURATA\n");
    switch (fork())
    {case -1:{printf("ERRORE NELLA FORK\n"); exit(0);}
    case 0:lancia_client(0);
    default:close(ds_sock_acc); }i=i+dim;}
    else
    {printf("CONNESSIONE FALLITA\n");
    exit(1); }
    }
    for (i=0;i<n_pac;i++)
    wait(&status);
    gestione_mancanti();
    close(ds_sock);
    for (i=0;i<n_pac;i++)
    wait(&status);
    for (i=1;i<addr_mem[0];i++)
    printf("%d ",addr_mem[i]);
    ordina_primi();
    scrivi_file();
    dealloca_sh_mem(addr_mem);
    elimina_sh_mem(id_shmem);
    elimina_sem(sem);
    exit(0);}


    void lancia_client(int inizio)
    {int ultimo_loc,i;
    close(ds_sock);
    if (inizio<0)
    {sprintf(buffer,"%d",-inizio);
    write(ds_sock_acc,buffer,20);
    ultimo_loc=((div(-inizio-primo,dim)).quot+1)*dim-1;
    if (ultimo_loc>ultimo)
    ultimo_loc=ultimo;
    sprintf(buffer,"%d",ultimo_loc);
    write(ds_sock_acc,buffer,20);}
    else
    {sprintf(buffer,"%d",i);
    write(ds_sock_acc,buffer,20);
    if (i+dim<ultimo) i+=dim-1;
    else i=ultimo;
    sprintf(buffer,"%d",i);
    write(ds_sock_acc,buffer,20);}
    ricevi();
    close(ds_sock_acc);
    exit(0);}

    void ricevi()
    {read(ds_sock_acc,buffer,20);
    while ((strcmp(buffer,"fine")!=0)&&(strcmp(buffer,"inter rupt")!=0)){
    sem_wait(sem);
    addr_mem[addr_mem[0]]=atoi(buffer);
    addr_mem[0]++;
    sem_signal(sem);
    read(ds_sock_acc,buffer,20);}
    if (strcmp(buffer,"interrupt")==0) {
    read(ds_sock_acc,buffer,20);
    printf("INTERRUZIONE: RICEVO %s",buffer);
    sem_wait(sem);
    addr_mem[addr_mem[0]]=-atoi(buffer);
    addr_mem[0]++;
    sem_signal(sem); }
    }


    void gestione_mancanti()
    {int j;
    for (j=1;j<addr_mem[0];j++)
    if (addr_mem[j]<0){
    if(instaura_connessione()>0){
    printf("CONNESSIONE INSTAURATA PER INTERRUZIONE\n");
    switch (fork()){
    case -1:{printf("ERRORE NELLA FORK\n");exit(0);}
    case 0:lancia_client(addr_mem[j]);
    default:close(ds_sock_acc);}
    }
    else{
    printf("CONNESSIONE FALLITA\n");
    exit(1);}
    sem_wait(sem);
    addr_mem[j]=0;
    sem_signal(sem);}
    }


    void ordina_primi()
    { int i,j,tmp;
    for(i=1;i<addr_mem[0]-1;i++)
    for(j=i+1;j<addr_mem[0];j++)
    if (addr_mem[j]<addr_mem[i]){
    tmp=addr_mem[j];
    addr_mem[j]=addr_mem[i];
    addr_mem[i]=tmp;}
    }

    void scrivi_file()
    {int fd,i;
    fd=open("numeri.primi",O_WRONLY|O_CREAT|O_TRUNC,06 66);
    for (i=1;i<addr_mem[0];i++)
    if ((addr_mem[i]!=0)&&(addr_mem[i]!=addr_mem[i-1])) {
    sprintf (buffer,"%d\n",addr_mem[i]);
    write(fd,buffer,strlen(buffer));
    }
    close(fd);
    }


    int crea_sh_mem(key_t chiave,int n_byte)
    {id_sh_mem=shmget(chiave,n_byte,IPC_CREAT|0666);
    if (id_sh_mem==-1){
    printf("IMPOSSIBILE CREARE MEMORIA CONDIVISA CON CHIAVE %d\n",chiave);
    exit(1);
    }
    return(id_sh_mem);
    }

    void* alloca_sh_mem(int id_sh_mem)
    {void* sh_mem_addr;
    sh_mem_addr=shmat(id_sh_mem,0,SHM_RND);
    if (sh_mem_addr==(void*)-1)
    {printf("IMPOSSIBILE ALLOCARE LA MEMORIA CONDIVISA\n");
    exit(1);}
    return(sh_mem_addr);
    }


    void dealloca_sh_mem (void *sh_mem_addr)
    {if (shmdt(sh_mem_addr)==-1)
    {printf("IMPOSSIBILE DEALLOCARE LA MEMORIA CONDIVISA\n");
    exit(1);}
    }


    void elimina_sh_mem(int id_sh_mem)
    {if (shmctl(id_sh_mem,IPC_RMID,NULL)==-1){
    printf("IMPOSSIBILE ELIMINARE LA MEMORIA CONDIVISA\n");
    exit(1);}
    }

    int crea_init_sem(key_t chiave, int val)
    {sem=semget(chiave,1,IPC_CREAT|0666);
    if (sem==-1){
    printf("IMPOSSIBILE CREARE IL SEMAFORO\n");
    exit(1);}
    semctl(sem,0,SETVAL,val);
    return(sem);
    }


    void elimina_sem(int id_sem)
    {if (semctl(id_sem,IPC_RMID,0)==-1){
    printf("IMPOSSIBILE ELIMINARE IL SEMAFORO\n");
    exit (1) ;
    }
    }


    int sem_wait(int sem)
    {struct sembuf operazione[1]={{0,-1,0}};
    return semop(sem,operazione,1);
    }


    int sem_signal(int sem)
    {struct sembuf operazione[1]={{0,+1,0}};
    return semop(sem,operazione,1);
    }


    void inizializza_connessione()
    {ds_sock=socket(AF_INET,SOCK_STREAM,0);
    if(ds_sock==-1) exit(1);
    my_addr.sin_family=AF_INET;
    my_addr.sin_port=porta;
    my_addr.sin_addr.s_addr=INADDR_ANY;
    if(bind(ds_sock,&my_addr,sizeof(my_addr))<0) exit(1);
    listen(ds_sock,3);
    }


    int instaura_connessione()
    { printf("TENTATIVO DI CONNESSIONE\n");
    ds_sock_acc=accept(ds_sock,&addr,&addrlen);
    return(ds_sock_acc);
    }


    void terminazione()
    {sem_wait(sem);
    ordina_primi();
    scrivi_file();
    kill(-1,SIGKILL); }

  4. #4

    Scusa ho perso 1/2 ora ,ma a quanto pare riporta il tutto a capo da solo

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.