Member 14807614 Ответов: 1

Как вызвать несколько производителей и потребителей с помощью очередей сообщений из процесса менеджера


Я довольно новичок в концепциях межпроцессной коммуникации, поэтому мне нужна некоторая помощь, мне нужно реализовать множественную проблему производитель-потребитель, используя очереди сообщений, в которых есть процесс менеджера, который вызывает 5 производителей и 5 потребителей (вызов соответствующих файлов, то есть producer.c и consumer.c), и наряду с этим мне нужно проверить наличие тупиков.


Существует две очереди, представленные в виде 2D-матрицы, а производитель и потребитель вставляют и удаляют соответственно, используя соответствующие файлы из Матрицы.

Матрица будет иметь следующий формат :

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


Что я уже пробовал:

Я понял большую часть задействованной концепции, но мне не хватает той части, где мне нужно вызвать producer.c и consumer.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();
    // ...
}

1 Ответов

Рейтинг:
2

k5054

Вам нужно будет позвонить fork() для каждого производителя и потребителя вы хотите создать, так что больше похоже

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.  

Вы, наверное, хотите посмотреть на wait(), waitpid(), и kill для управления вашими детьми, а также очередью сообщений и семафорными системными вызовами. Если вы еще этого не сделали, вам следует приобрести экземпляр книги У. Ричарда Стивенса Сетевое Программирование Unix, Том 1. Это то стандартный справочник для такого рода вещей, и он охватывает как сетевое, так и IPC-Программирование, включая подробный раздел о семафорах.