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

これは:diff =(*部分)-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

関連する問題