2017-09-16 102 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