[C]errore shared memory unix

di il
8 risposte

[C]errore shared memory unix

Ho iniziato da poco con la programmazione c in unix e ho diversi problemi...
ad esempio mi sapete dire perchè non funziona questo codice? cioè in compilazione va tutto bene ma in compilazione mi da errore cioè non da il risultato richiesto...
praticamente ho due file .c e uno dei in una zona di memoria condivisa mette 2 interi, l'altro li somma e poi ritorna il controllo al primo che stampa il risutlato a video.
qui sotto il codice
ADDER:

#include <sys/types.h>
#include <sys/sem.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#define SEMPERM 0600

typedef union _semun {
    int val;
    struct semid_ds *buf;
    unsigned short *array;
}semun;
int initsem (key_t semkey){
    int status=0, semid;
    semid=semget(semkey, 1 , SEMPERM | IPC_CREAT | IPC_EXCL);
    if (semid==-1){
        if (errno=EEXIST){semid=semget(semkey,1,0);}
    } else {
        semun arg;
        arg.val=0;
        status=semctl(semid,0,SETVAL,arg);
    }
    if (semid==-1 | status==-1){
        perror("initsem fallita");
        return (-1);
    }
    return (semid);
}
int waitSem(int semid){
    struct sembuf wait_buf;
    wait_buf.sem_num=0;
    wait_buf.sem_op=1;
    wait_buf.sem_flg=SEM_UNDO;
    if (semop(semid,&wait_buf, 1)==-1){
        perror("waitSem Fallita");
        exit(-1);
    }
    return 0;
}

int signalSem (int semid){
    struct sembuf signal_buf;
    signal_buf.sem_num=0;
    signal_buf.sem_op=1;
    signal_buf.sem_flg=SEM_UNDO;
    if (semop(semid,&signal_buf,1)==-1){
        perror("signalSem fallita");
        exit(1);
    }
    return 0;
}
int main(){
    int id,*point,a,b,c;
    key_t keysem=0x050,chiavemem=0x100;
    int sem,buffer[2];
    sem=initsem(keysem);
    if (sem<0){
        perror("errore creazione semaforo");
        exit(-1);
    }
    id=shmget(chiavemem,sizeof(buffer),0666|IPC_CREAT);
    point=(int *)shmat(id,NULL,0); 
    point[0]=a;
    point[1]=b;
    waitSem(sem);
    c=a+b;
    point[2]=c;
    signalSem(sem);
    shmdt(point);
    exit(0);
}
MAIN

#include <sys/types.h>
#include <sys/sem.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <stdlib.h>
#define SEMPERM 0600

typedef union _semun {
    int val;
    struct semid_ds *buf;
    unsigned short *array;
}semun;
int initsem (key_t semkey){
    int status=0, semid;
    semid=semget(semkey, 1 , SEMPERM | IPC_CREAT | IPC_EXCL);
    if (semid==-1){
        if (errno=EEXIST){semid=semget(semkey,1,0);}
    } else {
        semun arg;
        arg.val=0;
        status=semctl(semid,0,SETVAL,arg);
    }
    if (semid==-1 | status==-1){
        perror("initsem fallita");
        return (-1);
    }
    return (semid);
}
int waitSem(int semid){
    struct sembuf wait_buf;
    wait_buf.sem_num=0;
    wait_buf.sem_op=1;
    wait_buf.sem_flg=SEM_UNDO;
    if (semop(semid,&wait_buf, 1)==-1){
        perror("waitSem Fallita");
        exit(-1);
    }
    return 0;
}

int signalSem (int semid){
    struct sembuf signal_buf;
    signal_buf.sem_num=0;
    signal_buf.sem_op=1;
    signal_buf.sem_flg=SEM_UNDO;
    if (semop(semid,&signal_buf,1)==-1){
        perror("signalSem fallita");
        exit(1);
    }
    return 0;
}
int main (){
    key_t chiavemem=0x100,keysem=0x050;
    int sem,a,id,*point;
    pid_t figlio;
    int buffer[2];
    sem=initsem(keysem);
    if(sem<0){
        perror ("creazione semaforo fallita");
        exit (-1);
    }
    id=shmget(chiavemem,sizeof(buffer),0666|IPC_CREAT);
    point=(int *)shmat(id,NULL,0);
    waitSem(sem);
    point[0]=3;
    point[1]=5;
    signalSem(sem);
    figlio=fork();
    if (figlio<0){
        perror("fork fallita");
        exit (-1);
    }
    if (figlio==0){
        execvp("/home/francesco/NetBeansProjects/Esercizio1/addizione",NULL);
        a=point[2];
        exit(0);
    }
    shmdt(point);
    shmctl(id,IPC_RMID,0);
    printf("il risultato è %d",a);
    exit(0);
}

8 Risposte

  • Re: [C]errore shared memory unix

    Sia su ADDER che su MAIN correggi:
     
          ...
          // doppio uguale per confronto, singolo uguale per assegnamento
    #20   if (errno==EEXIST){semid=semget(semkey,1,0);} 
          ...
          // || OR
    #26   if (semid==-1 || status==-1)
          ...
          // le variabili a b non sono inizializzate
    #66   point[0]=a;  
    #67   point[1]=b;
          ...
    
  • Re: [C]errore shared memory unix

    Non funziona ugualmente mi da come risultato numeri assurdi tipo 1447484 come risultato tra 3 e 5
  • Re: [C]errore shared memory unix

    Francesco, nel main, la printf di a da dove viene?
  • Re: [C]errore shared memory unix

    Non capisco...viene dal main, cioè l'ho dichiarata nel main...volendo se ne potrebbe fare a meno perchè sarebbe l'ultimo elemento del buffer che l'adder riempie.
    detta in poche parole il main mette sui primi due elementi del buffer due numeri, richiama l'adder che legge i due numeri dal buffer poi li somma e mette il risultato nell'ultimo elemento del buffer poi il main legge il contenuto di quest'ultimo e lo stampa a video.
    il fatto è che così mi stampa a video non la somma di 3 e 5 ma numeri tipo 11248567 o cose del genere...
  • Re: [C]errore shared memory unix

    Francesco, nel main, la printf di a da dove viene?
    ADDR:
    
        ....
        int buffer[2]  // <--- Qui
        ....
        point=(int *)shmat(id,NULL,0); 
        point[0]=a; //???? forse il contrario
        point[1]=b; //???? idem
        waitSem(sem);
        c=a+b;
        point[2]=c; //???? non esiste il 2
        signalSem(sem);
        ....
    
  • Re: [C]errore shared memory unix

    Il 2 non esiste ma infatti deve metterci il valore di c
    praticamente sarebbe
    
    point[2]=point[0]+point[1];
    
    si lo so il buffer è di 2 ma mi hanno detto di mettere 3...vabbè al massimo lascio una posizione vuota nell'array
  • Re: [C]errore shared memory unix

    Nessuno?
  • Re: [C]errore shared memory unix

    Francesco, a me funziona con le modifiche apportate.
    Un'accorgimento che non ti ho detto è che main deve attendere che adder abbia scritto il resultato, altrimenti rischi che il 'parent' venga eseguito prima della scrittura del 'child'.
    Questo lo puoi fare sia dalla gestione semaforica oppure semplicemente usando un byte sharato per indicarti lo status (READY/BUSY...).
Devi accedere o registrarti per scrivere nel forum
8 risposte