cipcshared-memoryipcs

Processes accessing a Shared Memory segment returning different values


I'm new to the IPCS concept,i want to achieve that one process creates and initializes a shared memory and then calls another process which attaches to the same shared memory segment and prints the data in the shared memory. However i'm unable to achieve it:

AlgoCommon.h

struct sub_algo_shm
{
int time;
int pno;
};
struct AlgoShm
{
int head;
int tail;
char fFlag;
struct sub_algo_shm algoshm;
};

AlgoThrottle.c

#define key (key_t)111119
#define SHM_SIZE 1024

    int main()
        {
                int shmid ;
                struct timeval CurTime;
                struct timespec nTime;
                struct AlgoShm *shmaddr,*ptr;

                ptr = (struct AlgoShm *)malloc(10*sizeof(struct AlgoShm));
                //Creating Shared Memory
                if((shmid = shmget(key,SHM_SIZE,0644 |IPC_CREAT)) < 0)
                {
                        perror("shmget:error");
                }
                else
                {
                        printf("Shm created key=[%d] \n Segment Id [%d] ",key,shmid);
                        //Attaching to Shared Memory
                        shmaddr = (struct AlgoShm *)shmat(shmid,0,0);
                        if(shmaddr < 0)
                        {
                                perror(" shmat :error");
                        }
                        else
                        {
                                printf(" SHM Segment attached at [%x] ",shmaddr);
                        }
                        //Loading/Initializing Data Blocks in SHM
                        clock_gettime(CLOCK_REALTIME,&nTime);
                        printf(" Time in N secs[%ld] \n ",nTime.tv_nsec);
                        ptr->head = 5;
                        ptr->tail = 3;
                        ptr->fFlag = '0';
                        ptr->algoshm.time = 0;
                        ptr->algoshm.pno = 1;
                        //memcpy(shmaddr,&ptr,sizeof(ptr));
                        printf(" AlgoThrottle|ptr->head [%d] ",ptr->head);
                //      sleep(1);
                        system("./AlgoRead"); 

                }

        return 0;
        }

AlgoRead.c

#define key (key_t)111119
#define SHM_SIZE 1024

    int main()
    {

    int shmid ;
    struct AlgoShm *shmaddr,*ptr1 ;
    ptr1 = (struct AlgoShm *)malloc(10*sizeof(struct AlgoShm));

    if((shmid = shmget(key,SHM_SIZE,0)) < 0)
    {

    perror(" AlgoRead|shmget:error ");
    }
    else
    {
            printf(" AlgoRead|SHM Created shmid [%d] ",shmid);

            if((shmaddr = (struct AlgoShm *)shmat(shmid,0,0)) < 0)
            {
                    perror("AlgoRead|shmat error");
            }
            else
            {
                    //memcpy(ptr1,shmaddr,sizeof(struct AlgoShm));
                    printf(" AlgoRead|Attached to Segment at Address[%x] \n ",shmaddr);
                    printf(" AlgoRead|ptr1->head [%d] ptr1->tail [%d] ptr1->fFlag[%c] \n ",ptr1->head,ptr1->tail,ptr1->fFlag);
            }
    }

    return 0;
    }

This is my output:

Shm created key=[111119]
 Segment Id [1179615678]  SHM Segment attached at [4a6b4000]  Time in N secs[114594083]
 AlgoRead|SHM Created shmid [1179615678]  AlgoRead|Attached to Segment at Address[624cb000]
  AlgoRead|ptr1->head [36810768] ptr1->tail [0] ptr1->fFlag[▒]
   AlgoThrottle|ptr->head [5]

Also,system call's output is showing first then the printf statement even after i used a sleep(1) before invoking system()


Solution

  • first thing, if you are using shared memory then why malloc() ? shared memory itself will attach shmid with shared memory you don't have to do explicitly malloc().

    second thing, you are attaching shmaddr pointer with memory returned by shmat() but putting data into ptr, ptr is attached with heap memory not with shared memory. So either put the data into shmaddr pointer or replace this

    shmaddr = (struct AlgoShm *)shmat(shmid,0,0);
    

    with

    ptr = (struct AlgoShm *)shmat(shmid,0,0);
    

    and don't allocate memory using mallocc().then do

                    ptr->head = 5;
                    ptr->tail = 3;
                    ptr->fFlag = '0';
                    ptr->algoshm.time = 0;
                    ptr->algoshm.pno = 1;
    

    do all these modification in both process. and finally you should do shmdt() for de-attaching shared memory otherwise it will be a memory leakage.

    I modified your code as one.c :

    int main()
    {
            int shmid ;
            struct timeval CurTime;
            struct timespec nTime;
            struct AlgoShm *shmaddr,*ptr;
            if((shmid = shmget(key,SHM_SIZE,0644 |IPC_CREAT)) < 0)
            {
                    perror("shmget:error");
            }
            else
            {
                    printf("Shm created key=[%d] \n Segment Id [%d] ",key,shmid);
                    ptr = (struct AlgoShm *)shmat(shmid,0,0);
                    if(shmaddr < 0)
                    {
                            perror(" shmat :error");
                    }
                    else
                    {
                            printf(" SHM Segment attached at [%x] ",ptr);
                    }
                    clock_gettime(CLOCK_REALTIME,&nTime);
                    printf(" Time in N secs[%ld] \n ",nTime.tv_nsec);
                    ptr->head = 5;
                    ptr->tail = 3;
                    ptr->fFlag = 'a';
                    ptr->algoshm.time = 10;
                    ptr->algoshm.pno = 11;
                    printf(" AlgoThrottle|ptr->head [%x] ",ptr->head);
    
            }
            system("./AlgoRead");
            return 0;
    }
    

    two.c :

    int main()
    {
            int shmid ;
            struct AlgoShm *shmaddr,*ptr1 ;
            if((shmid = shmget(key,SHM_SIZE,0)) < 0)
            {
    
                    perror(" AlgoRead|shmget:error ");
            }
            else
            {
                    printf(" AlgoRead|SHM Created shmid [%d] ",shmid);
    
                    if((ptr1 = (struct AlgoShm *)shmat(shmid,0,0)) < 0)
                    {
                            perror("AlgoRead|shmat error");
                    }
                    else
                            printf(" AlgoRead|Attached to Segment at Address[%x] \n ",ptr1);
                    printf(" AlgoRead|ptr1->head [%d] ptr1->tail [%d] ptr1->fFlag[%c] \n ",ptr1->head,ptr1->tail,ptr1->fFlag);
            }
            shmdt(ptr1);
            return 0;
    }
    

    I hope it helps you and my advise to you is to go through man page of shmget(), shmat() & shmdt() properly.