2017-09-16 41 views
1

我不明白这段代码有什么问题。我有一个共享的变量(部分)分配共享内存。当零部分,生产者(厨师)填充锅,消费者(野蛮)消费部分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 
+0

“*我不知道为什么可变部分也不会减少。*”,因为没有代码这样做? – alk

+0

This:diff =(* portion)-n; – Jing

+0

切勿在不检查其返回值的情况下使用'sem_'函数。它们可能被诸如IO之类的信号中断。你这样写的代码会显示奇怪的虚假行为,这很难追查到。 –

回答

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. 
+0

好的谢谢。你知道为什么,开始播放节目的时候,制作人有一个循环,当可变部分<= 0时,制作人不会填满整个锅? – Jing

+0

我认为你展示的代码背后的想法可能是什么,并大大调整了我的答案。 – alk

+0

我在您显示的代码中看不到“<= 0”。 – alk