Visualizzazione dei risultati da 1 a 2 su 2
  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.



    Codice PHP:
    #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,charargv[]) 
    {
    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,"interrupt")!=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,0666); 
    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); 
    }


    voidalloca_sh_mem(int id_sh_mem)
    {
    voidsh_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 chiaveint 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 oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Scusa, ma perche' un altro thread? Non potevi continuare in quello gia' aperto ? (anzi, avresti dovuto farlo ...) ...
    No MP tecnici (non rispondo nemmeno!), usa il forum.

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.