mercredi 17 mai 2023

Shared Memory: Consumer process of shared memory does not read the data from memory region

I am working on a gstreamer based streaming application. I have created set of gstreamer plugins as per project requirements. I am facing a challenge of sharing data between the main application and one of the gstreamer plugin. I have tried different IPC mechanisms such as files, namedPipes and message queues. These IPC mechanisms do not cater solution to my problem. I am finally using shared memory to transfer data from the main application to the plugin. I need to pass a struct data that contains 4-5 integer array variables.

My main application is producer of the data and plugin is the consumer.

The below code is for the producer:

#ifndef __IPC_SHMW__
#define __IPC_SHMW__

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>

typedef struct {
  int x[20];
  int y[20];
  int w[20];
  int h[20];
  int num;
} send_data_WR; 

class IPC_DATA_SEND {
        public:
                int shmid;
                key_t key = 1996;
                send_data_WR *_data;

                int create_shm(){
                        shmid = shmget(key, sizeof(send_data_WR), IPC_CREAT | 0666);
                        printf("SHMID Write Process %d \n",shmid);
                        if (shmid < 0) {
                                perror("shmget");
                                exit(1);
                        } 
                        _data = (send_data_WR*) shmat(shmid, NULL, 0);
                        if (_data == (send_data_WR *) -1) {
                                perror("shmat");
                                exit(1);
                        }
                        //std::cout << "SHMID Write Address " << _data << std::endl;
                        printf("SHMID Write Address %x \n", _data);
                }

                int write_data(send_data_WR * data){
                        _data->num = data->num;
                        for(int i=0; i<data->num; i++){
                                _data->x[i] = data->x[i];
                                _data->y[i] = data->y[i];
                                _data->w[i] = data->w[i];
                                _data->h[i] = data->h[i];
                                printf("Write: x=%d y=%d w=%d h=%d \n", _data->x[i], _data->y[i], _data->w[i], _data->h[i]);
                        }
                        sleep(1);
                        return 0;
                }

                int clean_shm(){
                        // Detach shared memory segment
                        shmdt(_data);
                        // Remove shared memory segment
                        shmctl(shmid, IPC_RMID, NULL);
                        return 0;
                }
};

#endif

The below code is for the consumer plugin:

#ifndef __IPC_SHMR__
#define __IPC_SHMR__

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>


typedef struct {
  int x[20];
  int y[20];
  int w[20];
  int h[20];
  int num;
} read_data_WR; 

class IPC_DATA_READ {
        public:
                int shmid;
                key_t key = 1996;
                read_data_WR *_data;

                int read_shm(){
                        shmid = shmget(key, sizeof(read_data_WR), 0);
                        printf("SHMID Read Process %d \n",shmid);
                        if (shmid < 0) {
                                perror("shmget");
                                exit(1);
                        }

                        _data = (read_data_WR*) shmat(shmid, NULL, 0);
                        if (_data == (read_data_WR *) -1) {
                                perror("shmat");
                                exit(1);
                        }
                        printf("SHMID Read Address %x \n",_data);
                }

                int read_data(read_data_WR * data){
                        printf("Inside Read Data SHM \n");
                        printf("[Read SHM] num = %d \n", _data->num);
                        data->num = _data->num;
                        printf("[Read SHM] data num = %d \n", data->num);
                        for(int i=0; i<data->num; i++){
                                data->x[i] = _data->x[i];
                                data->y[i] = _data->y[i];
                                data->w[i] = _data->w[i];
                                data->h[i] = _data->h[i];
                                printf("Read: x=%d y=%d w=%d h=%d \n", data->x[i], data->y[i], data->w[i], data->h[i]);
                        }
                        return 0;
                }

                int clean_shm(){
                        // Detach shared memory segment
                        shmdt(_data);
                        // Remove shared memory segment
                        shmctl(shmid, IPC_RMID, NULL);
                        return 0;
                }
};

#endif //__IPC_SHMR__

There are no issues with the compilation. The code compiles successfully and when I start the main application, the producer code starts writing to the shared memory region.

I could verify it by set of print statements. However, when I start the working of my plugin (consumer), there is no data available. The print statements just print 0.

I checked the fd & the address locations of the data pointed by the pointer of each process and I see the fd has different values and pointers are pointing to different addresses.


SHMID Write Process 0
SHMID Write Address 8a087000
...
SHMID Read Process 1
SHMID Read Address 8a05c000

I tried figuring out what might be the issue.

I have not found any solution online and i am not able to get to the root cause of the problem. Can someone help me, in understanding what i am doing wrong.

Thanks

Aucun commentaire:

Enregistrer un commentaire