Click here to Skip to main content
15,918,303 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
I am pretty new to the concepts of inter-process communication, therefore, need some help, I need to implement a multiple producer-consumer problem using message queues in which there is a manager process that calls 5 producers and 5 consumers (call to the respective files i.e producer.c and consumer.c) and along with that, I need to check for deadlocks.


There are two queues represented in the form of 2D-matrix and producer and consumer insert and delete respectively using respective files from the matrice.

The matrix will be in following format :

    P1 P2 P3 P4 P5 C1 C2 C3 C4 C5
Q0 :    -   -  -  -  -  -  -  -  -  -
Q1 :    -   -  -  -  -  -  -  -  -  -


What I have tried:

I have understood most of the concept involved but I'm lacking in the part where I need to call producer.c and consumer.c from the manager process (i.e manager.c). I have implemented my method using fork but it resulted in segmentation fault, any help will be very welcome.

Here's my code.
C
int main(int argc, char* argv[]){
    int dpp, i;
    float prob=0.2;
    if(argc!=3){
        printf("Please run the program with 2 arguments : <DPP_toggle (0 or 1)> <probability> \n"); // 
                 DPP --> Deadlock Prevention Protocol
        exit(1);
    }

    sscanf(argv[1], "%d", &dpp);
    sscanf(argv[2], "%f", &prob);

    semid = semget((key_t)SEMAPHORE_KEY, 7, IPC_CREAT|0666);

    for(i=0; i<=6; i++){
        if(semctl(semid, i, SETVAL, 1) < 0){
            printf("Error in initializing semaphore");
            exit(EXIT_FAILURE);
        }
    }

    int msgid0 = msgget((key_t)MSGQ0KEY, IPC_CREAT|0666);
    int msgid1 = msgget((key_t)MSGQ1KEY, IPC_CREAT|0666);

    // calling producer and consumer with fork process.
    pid_t pid = fork();

    if(pid < 0){
        perror("fork()");
        return -1;
     }

     for(int index=0; index<NUM_PRODUCERS; index++){
         if(pid > 0){
             execlp("./producer", "./producer", index, MSGQ0KEY, MSGQ1KEY,  (char *)0);
             exit(0);
         }
         else{
             execlp("./consumer", "./consumer", NUM_PRODUCERS+index, MSGQ0KEY, MSGQ1KEY, dpp, prob, (char*)0);
             exit(0);
         }
     }

     // detectDeadlock();
    // ...
}
Posted
Updated 20-Apr-20 16:10pm

1 solution

You will need to call fork() for each producer and consumer you wish to create, so more like
C++
pid_t producers[NUM_PRODUCERS];
pid_t consumers[NUM_CONSUMERS];

for(size_t i = 0; i < NUM_PRODUCERS; ++i) {
    pid_t child = fork();
    if(child === -1)  {
         // handle error
    } else if ( child == 0 ) {
         // child process
         execlp("./producer", ...);
    }
    // parent continues on
    producer[i] = child;
}

for(size_t i = 0; i < NUM_CONSUMERS; ++i) {
    // create children as per producers
    consumer[i] = child;
}

// at this point you have NUM_PRODUCERS + NUM_CONSUMERS children and the parent
// process is the controller.  

You probably want to look at wait(), waitpid(), and kill to manage your children, as well as the message queue and semaphore system calls. If you have not already done so, you should get a copy of W. Richard Stevens's Unix Network Programming, Volume 1. This is the standard reference for this kind of thing, and he covers both Network and IPC programming, including a detailed section on semaphores.
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900