具有共享内存和进程的生产者/消费者

时间:2017-09-16 08:21:36

标签: c unix operating-system

我无法理解这段代码的错误。我有一个共享内存分配的共享变量(部分)。当零部分,生产者(厨师)填充锅,消费者(野蛮)消耗部分NROUNDS。我不知道为什么变量部分没有递减。

#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/wait.h>

sem_t mutex,empty,full;
int shmid;
int *portions;

void clear()  //destroy semaphores and shared memory
{
   sem_destroy(&mutex);
   sem_destroy(&empty);
   sem_destroy(&full);
   if (shmctl(shmid,IPC_RMID,0) == -1) perror("shmctl");
}

void producer(int num, int m)   //chef that produces portions
{
  int i, j;

   while(1) {  

    sem_wait(&mutex); //join critical region
    sem_wait(&empty);
    *portion=m; 
    printf("Chef fills the pot\n");
    sem_post(&mutex);
    sem_post(&full);
   }      
}

void consumer(int num, int rounds, int m)   //savage that consumes portions
{

       int i, diff, n, j;

        for(i=0;i<rounds;i++) { 
           sleep(3);
           sem_wait(&mutex);
           if((*portion)==0) {
              sem_post(&empty);
              sem_wait(&full); 
            }        
         n=rand() % m;
         diff=(*portion)-n;  //consumes portions
         printf("Savage[%d] has eaten %d portions\n", num, diff);
         printf("Portions number in pot: %d\n", *portion);
         sem_post(&mutex);

     }  

}


int main(int argc, char *argv[])
{

int i;
int N, M, NROUNDS, pid;


if (argc != 4) 
{
    fprintf(stderr,"insert N savages, M portions and NROUNDS\n");
    exit(1);
}

N=atoi(argv[1]);
M=atoi(argv[2]);
NROUNDS=atoi(argv[3]);

// initialize semaphores and shared memory

sem_init(&mutex,1,1);

sem_init(&empty,1,M);

sem_init(&full,1,0);

shmid = shmget(IPC_PRIVATE,sizeof(int),0600);
  if (shmid == -1) perror("Creation shared memory");
  portions = (int *) shmat(shmid, NULL, 0);
  if (portions == (void *)-1) perror("Attach shared memory");
  *portions=M; //initialize shared variable(M is max portions in pot)

/* initialize producer and consumers (1 Producer and N Consumers) */



    if (fork()==0)
        { producer(i, M); exit(0);} //producer


   for (i = 0; i < N; i++){
        if (fork()==0)
            { consumer(i, NROUNDS, M); exit(0);} //consumers
      }

  for(i=0;i<N;i++) {
    pid=wait(NULL);
    printf("Terminated process %d\n", pid); //wait terminating processes
  }    

  clear();

}

输出是这样的:

./a.out 3 20 3

Chef fills the pot
Chef fills the pot
Chef fills the pot
Chef fills the pot
Chef fills the pot
Chef fills the pot
Chef fills the pot
Savage[2] has eaten 17 portions
Savage[1] has eaten 17 portions
Savage[0] has eaten 17 portions
Portions number in pot: 20
Portions number in pot: 20
Portions number in pot: 20
Savage[1] has eaten 14 portions
Savage[0] has eaten 14 portions
Savage[2] has eaten 14 portions
Portions number in pot: 20
Portions number in pot: 20
Portions number in pot: 20
Savage[2] has eaten 3 portions
Savage[0] has eaten 3 portions
Savage[1] has eaten 3 portions
Portions number in pot: 20
Portions number in pot: 20
Terminated process 4432
Portions number in pot: 20
Terminated process 4431
Terminated process 4433

1 个答案:

答案 0 :(得分:1)

我没有检查整个代码,但看起来好像在这里

           n=rand() % m;

代码计算吃掉的部分。

然后在这里计算剩余部分

           diff=(*portion)-n;  

错误将它们打印为在这里吃的

           printf("Savage[%d] has eaten %d portions\n", num, diff);

代码不会从底池中删除它们(m)。

要解决此问题

           n=rand() % m; // get portions eaten in to n
           diff=(*portion)-n;  // get the remaining portions
           printf("Savage[%d] has eaten %d portions\n", num, n); // log
           (*portion) = diff; // or just  (*portion) -= n; and drop diff at all.