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

标签 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

最佳答案

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

           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.

关于c - 具有共享内存和进程的生产者/消费者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46251797/

相关文章:

linux - 如何增加子进程数量

c - C中如何使用指针表达式访问二维数组的元素?

c - 关于 C 中的返回类型

将函数指针转换为另一种类型

c - 在 bash 脚本中自动引用 .h 文件

bash - Bash 中的 "> (tee -a ...)"命令

c++ - 在 UNIX 中通过 recv/send 交换数据时如何正确使用缓冲区?

linux - 在内核版本 3.16.x 中实现自定义系统调用

multithreading - Go 调度器什么时候会创建新的 M 和 P?

c - 如果我运行同一个程序两次,哪一部分内存将被共享