首页 > 解决方案 > 为什么即使缓冲区已满,生产者进程也不会停止生产?

问题描述

我用m个生产者进程和n个消费者进程编写了一个生产者-消费者同步代码。我在调试它时遇到了麻烦。缓冲区在所有消费者和生产者进程之间共享,而变量在所有生产者进程之间共享。每个产品都由一个产品 ID 表示。

有3个信号量:

i) 如果 Full semaphore 值为 0,Full semaphore 将停止消费者进程访问缓冲区。

ii) 如果 Empty semaphore 值为 0,Empty semaphore 将停止生产者进程访问缓冲区。

iii) 互斥信号量用于互斥。

共享.h

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

#define buffer_size 5
#define empty_id 0
#define full_id 1
#define mutex_id 2
#define no_sem 3

struct sembuf signall = {0 , 1, 0};
struct sembuf wait = {0, -1, 0};

#define W(s) semop(s, &wait, 1);
#define S(s) semop(s, &signall, 1);

int shmid,shmid1,shmid2;
int *buffer;

union semun
{
                int val;
                struct semid_ds *buf;
                unsigned short  *array;
                struct seminfo  *__buf;

}setvalarg[3];

int *create_shared_mem_buffer()
{
        int *shmaddr;
        key_t key = 85;

        shmid = shmget(key, buffer_size, IPC_CREAT|0660);

        shmaddr= (int *)shmat(shmid, NULL, 0);

        return shmaddr;
}

int create_semaphore_set()
{
        key_t key=65;

        int semid= semget(key, no_sem, IPC_CREAT|0600);

        setvalarg[0].val=buffer_size;
        semctl(semid, empty_id, SETVAL, setvalarg[0]);

        setvalarg[1].val=0;
        semctl(semid, full_id, SETVAL, setvalarg[1]);

        setvalarg[2].val=1;
        semctl(semid, mutex_id, SETVAL, setvalarg[2]);

        return semid;
}

制作人.c

#include "shared.h"

void insert_product(int item, int *in, int *buffer)
{
        *in=(*in+1)%buffer_size;
        buffer[*in]=item;
        printf("Producer produces item with id %d stored in posn %d  \n",item,*in);
}


int main(int argc, char *argv[])
{
        int i, pid, item;
        int *in, *in1;
        buffer = create_shared_mem_buffer();
        int semid= create_semaphore_set();


        shmid2=  shmget(IPC_PRIVATE, sizeof(int),IPC_CREAT | 0777);
        in=(int *)shmat(shmid2, NULL, 0);
        *in=-1;

        int n=5;

        for(i=0;i<n;i++)
        {
                pid=fork();
                if(pid==0)
                {
                        srand(getpid());
                        in1=(int *)shmat(shmid2, NULL, 0);
                        while(1)
                        {
                                item=rand();
                                wait.sem_num=0;
                                W(semid);
                                wait.sem_num=2;
                                W(semid);
                                insert_product(item, in1, buffer);
                                signall.sem_num=2;
                                S(semid);
                                signall.sem_num=1;
                                S(semid);
                        }
                }
         }
        return(0);
}

问题是生产者进程在生产 5(buffer_size) 个产品后应该等待消费者进程消费产品,然后再次填充缓冲区。

输出如下:(没有执行消费者进程)

Producer produces item with id 1170454448 stored in posn 0  
Producer produces item with id 1942442557 stored in posn 1  
Producer produces item with id 1638563672 stored in posn 2  
Producer produces item with id 1338160125 stored in posn 3  
Producer produces item with id 2111694856 stored in posn 4  
Producer produces item with id 1525954635 stored in posn 0  
Producer produces item with id 1346192014 stored in posn 1  
Producer produces item with id 1158563802 stored in posn 2  
Producer produces item with id 973413556 stored in posn 3  
Producer produces item with id 787723313 stored in posn 4  

什么/哪里有问题?如何调试它?

如果需要更多信息,请在下面发表评论。

标签: cipcsemaphoreshared-memoryproducer-consumer

解决方案


推荐阅读