共享变量仅在一个过程中发生变化

时间:2018-12-05 14:32:00

标签: c multithreading message-queue shared-memory multiple-processes

我在上大学的项目中遇到问题。我有一个与产品和仓库中每个产品的数量共享的变量。在“ I”秒的间隔中,随机产品中有Q的供应。它发送一条消息来处理“仓库”,该仓库将数量添加到共享内存中。在中央打印产品及其数量。但是,在中心,数量始终是相同的,并且不会增加。 这是代码:

//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);
    }

某些变量(例如Q,S,产品和数量)是从文本文件中获取的。一切工作正常,只是共享内存未在中央进行更新,而且我也没有发现问题所在。任何帮助,将不胜感激。 Soma代码可能是错误的,因为我已从原始文件中获取了该代码,并试图将其改编成本文。如果您有任何疑问,请随时提问。

1 个答案:

答案 0 :(得分:0)

使用IPC_PRIVATE键创建共享内存,这意味着该内存是该进程专用的。子进程获得该内存的私有副本。

进行一次呼叫而不是过时的System V呼叫shmgetshmat

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

这将创建一个匿名内存,该内存在父进程及其子进程之间共享。


互斥锁也必须位于共享内存中,否则每个进程都有自己的副本。