Почему процессы производителя не прекращают производить, даже если буфер заполнен? - PullRequest
1 голос
/ 16 февраля 2020

Я написал код синхронизации производитель-потребитель с m процессами производителя и n процессами потребителя. У меня проблемы с отладкой. Буфер является общим для всех процессов-потребителей и производителей, а переменная - для всех процессов-производителей. Каждый продукт представлен идентификатором продукта.

Существует 3 семафора:

i) Полный семафор для остановки пользовательских процессов для доступа к буферу, если значение полного семафора равно 0.

ii) Пустой семафор для остановки производителя обрабатывает доступ к буферу, если значение пустого семафора равно 0.

iii) Семафор мьютекса предназначен для взаимного исключения.

Shared.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;
}

Producer. 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  

В чем / где проблема? Как его отладить?

Если требуется дополнительная информация, оставьте комментарий ниже.

...