0

I'm having an issue in my project for university. I have a shared variable with products and the quantity of each product in a warehouse. In intervals of "I" seconds there is a supply of Q in a random product. It sends a message to process "Warehouse" which adds that quantity to shared memory. In central it prints the product and its quantity. However, in central, the quantity is always the same and it doesn't increment. Here's the code:

//Struct for Shared Memory
typedef struct Warehouse{
    char name[50];
    int W_NO;
    pid_t pid;
    double x;
    double y;
    char products[3][50];
    int quantity[3];
}shared_mem;

//Struct for Message Queue
typedef struct Message_QUeue{

    long type;
    char product[50];
}message_queue;

shared_mem *shm;
int shmid;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void* receive_supply(void* id){
    int W_NO = *((int *)id);
    message_queue msg;
    while(1){
        //Receive messamge
        msgrcv(mq_id,&msg,sizeof(msg) - sizeof(long),1,0);
        for(int i = 0; i < (sizeof(shm.products)/sizeof(shm.products[0])); i++){  
            if(strcmp(msg.produto,shm.products[i]) == 0){ //Sees which product was randomizem
                pthread_mutex_lock(&mutex);
                shm.quantity[i] += Q;  //add quantity Q
                pthread_mutex_unlock(&mutex);   
                break;
            }
        }
    }
}

void warehouse(int W_NO){
    ids_supply[0] = W_NO;
    pthread_t supply;
    pthread_create(&supply,NULL,receive_supply,&W_NO);
}

void central(){
    while(1){
        for(int j = 0; j < (sizeof(shm.products)/sizeof(shm.products[0]));j++){
            printf("Warehouse: %d Quantity of product %s: %d\n",shm.W_NO,shm.products[j],shm.quantity[j]);
        }
        sleep(10);
    }
}

int main(){

    //Initialize shared memory
    if((shmid = shmget(IPC_PRIVATE,sizeof(shared_mem),IPC_CREAT | 0766)) < 0)
    {
      perror("Error in shmget with IPC_CREAT\n");
      exit(1);
    }

    if((shm = (shared_mem*)shmat(shmid, NULL, 0)) == (shared_mem*)-1)
    {
       perror("Shmat error");
       exit(1);
    }

    //Create process for Warehouse
    pid_t child_ID;
    switch(child_ID = fork()){
        case -1:
            printf("Error creating new process\n");
            break;
        case 0 :
            pthread_mutex_lock(&mutex);
            shm.W_NO = 1;
            pthread_mutex_unlock(&mutex);
            warehouse(1);
            exit(0);
            break;
        default:
            pthread_mutex_lock(&mutex);
            shm.pid = child_ID;
            shm.W_NO = 1;
            pthread_mutex_unlock(&mutex);
            break;
    }

    //Create Process Central
    id_central = fork();
    if (id_central == 0){
         central();
         exit(0);
    }

    srand(getpid());
    //send message to process Warehouse every S seconds with a random product
    while(1){
        message_queue msg;
        strcpy(msg.product,shm -> info_wh.produtos[rand()%(sizeof(shm.products)/sizeof(shm.products[0]))]);
        msg.type = 1;
        msgsnd(mq_id,&msg,sizeof(msg) - sizeof(long),0);
        sleep(S);
    }

Some variables like Q, S, products and quantity are taken from a text file. All that works perfectly, just shared memory is not updating in central and I'm not seeing what's wrong. Any help would be appreciated. Soma code might be wrong because I've taken it from the original file and tried to adapt it to this post. If you get any doubt, feel free to ask.

stelyt
  • 1
  • 1

1 Answers1

0

The shared memory is created with IPC_PRIVATE key, which means the memory is private to the process. The child processes get their own private copy of that memory.

Instead of obsolete System V calls shmget and shmat do one call:

shm = mmap(NULL, sizeof(shared_mem), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
if(MMAP_FAILED == shm)
    perror('mmap');

This creates an anonymous memory that is shared between the parent and its child processes.


The mutex needs to be in the shared memory as well, otherwise each process has its own copy.

Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271