Garmaine Staff asked 1 year ago

I need help with a problem: "Enable" communication between parallel processes using a limited length buffer. The program receives two input parameters via the command line. The first parameter indicates number of producer's processes, and the second parameter indicates the number of random numbers that each producer must generate and place in the buffer. The consumer receives the number by number from the producer via the buffer and calculates their sum. After receiving all the numbers from all manufacturers and calculating their sum, it should print the sum on the screen.

Solution structure

Producer and Consumer Data Common (Shared Memory (shmget)): integer variables INPUT, OUTPUT and N, buffer M (array of 5), semaphores MUTEX, FULL, EMPTY (semget)

I need to solve this with semop, semctl, etc. Not with sem_t, sem_init… Here's what I got so far

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

#define MUTEX 0
#define FULL 1
#define EMPTY 2

using namespace std;
int INPUT, OUTPUT, A, N;
int *M;
int shmID, semID;

union semun {
        int val;
        struct semid_ds *buf;
        unsigned short *array;
}semval;

void SemGet(int nsems) { //nsems = number of semaphores
        semID=semget(IPC_PRIVATE, nsems, 0600);
        if(semID<0) {
                cout<<"\nNo semaphores"<<endl;
                exit(1);
        }
}

int SemSetVal(int SemNum, int SemVal) {
        return semctl(semID, SemNum, SETVAL, semval);
}

sembuf SemBuf;

int SemOp(int SemNum, int SemOp){
        SemBuf.sem_num = SemNum;
        SemBuf.sem_op  = SemOp;
        SemBuf.sem_flg = 0;
        return semop(semID, &SemBuf, 1);
}

void SemRemove(int sig) {
        semctl(semID, 0, IPC_RMID, 0);
        shmctl(shmID, IPC_RMID, 0);
        cout<<"\nDeleting shared memory and semaphores!"<<endl;
        exit(0);
}

void producer() {
        int i=0;
        do {
                SemOp(FULL, -1); //where -1 is wait, 1 is signal
                SemOp(MUTEX, -1);
                M[INPUT]=rand()%1000+1;
                INPUT=(INPUT+1)%5;
                SemOp(MUTEX, 1);
                SemOp(EMPTY, 1);
                i++;
        } while(i<N);
}

void consumer() {
        int i=0;
        int sum=0;
        do {
                SemOp(EMTPY, -1);
                sum += M[OUTPUT];
                OUTPUT = (OUTPUT+1)%5;
                SemOp(FULL, 1);
                i++;
        } while(i<N*A);
        cout<<"sum: "<<sum<<endl;
}

int main(int argc, char *argv[]) {
        sigset(SIGINT, SemRemove);
        if(argc!=3) {
                cout<<"Error!"<<endl;
                return 0;
        }
        A=atoi(argv[1]);
        N=atoi(argv[2]);
        srand(time(0));
        shmID=shmget(IPC_PRIVATE, A*N*sizeof(int), 0600);
        if(shmID<0) {
                cout<<"Error!"<<endl;
                exit(0);
        }
        M=(int*)shmat(shmID, NULL, 0);

        SemGet(3);


        SemRemove(0);
        return 0;
}