web-dev-qa-db-fra.com

Programme Consumer Producer utilisant des sémaphores et des pthreads

J'ai écrit un code pour un problème producteur-consommateur.Mais je ne reçois pas la sortie.Il n'y a pas d'erreur de compilation, mais un avertissement dans mon programme.Je suis confus.Essayez très fort.Mais je ne peux pas l'obtenir.Veuillez me dire ce que est erroné dans mon programme.Quel sera le bon programme.Je suis frustré.Veuillez aider les gars. Voici le code-

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include </usr/include/semaphore.h>

#define BUFF_SIZE   5           /* total number of slots */
#define NP          3           /* total number of producers */
#define NC          3           /* total number of consumers */
#define NITERS      4           /* number of items produced/consumed */

typedef struct {
    int buf[BUFF_SIZE];   /* shared var */
    int in;               /* buf[in%BUFF_SIZE] is the first empty slot */
    int out;              /* buf[out%BUFF_SIZE] is the first full slot */
    sem_t full;           /* keep track of the number of full spots */
    sem_t empty;          /* keep track of the number of empty spots */
    sem_t mutex;          /* enforce mutual exclusion to shared data */
} sbuf_t;

sbuf_t shared;


void *Producer(void *arg) {
    int i, item, index;

    index = (int) arg;


    for (i = 0; i < NITERS; i++) {
        /* Produce item */
        item = i;

        /* Prepare to write item to buf */

        /* If there are no empty slots, wait */
        sem_wait(&shared.empty);
        /* If another thread uses the buffer, wait */
        sem_wait(&shared.mutex);
        shared.buf[shared.in] = item;
        shared.in = (shared.in+1)%BUFF_SIZE;
        printf("[P%d] Producing %d ...\n", index, item); fflush(stdout);
        /* Release the buffer */
        sem_post(&shared.mutex);
        /* Increment the number of full slots */
        sem_post(&shared.full);

        /* Interleave  producer and consumer execution */
        if (i % 2 == 1) sleep(1);
    }
    return NULL;
}

void *Consumer(void *arg) {
    int i, item, index;

    index = (int) arg;
    for (i = NITERS; i > 0; i--) {
      sem_wait(&shared.full);
      sem_wait(&shared.mutex);
      item = i;
      item = shared.buf[shared.out];
      shared.out = (shared.out + 1) % BUFF_SIZE;
      printf("[C%d] Consuming  %d ...\n", index, item); fflush(stdout);
      /* Release the buffer */
      sem_post(&shared.mutex);
      /* Increment the number of full slots */
      sem_post(&shared.empty);

      /* Interleave  producer and consumer execution */
      if (i % 2 == 1) sleep(1);
    }
    return NULL;
}

int main() {
    pthread_t idP, idC;
    int index;

    sem_init(&shared.full, 0, 0);
    sem_init(&shared.empty, 0, BUFF_SIZE);
    pthread_mutex_init(&shared.mutex, NULL);
    for (index = 0; index < NP; index++) {
       /* Create a new producer */
       pthread_create(&idP, NULL, Producer, (void*)index);
    }
    /*create a new Consumer*/
    for (index = 0;index < NC;index++) {
        pthread_create(&idC, NULL, Consumer, (void*)index);
    }
    pthread_exit(NULL);
}
9
Twity 56876

Vous devriez peut-être prendre les avertissements du compilateur plus au sérieux. Les types incorrects et les fonctions non définies sont généralement affichés comme des avertissements ...

Je n'ai pas vérifié la logique de votre programme, mais le principe devrait fonctionner:

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include </usr/include/semaphore.h>

// for sleep
#include <unistd.h>

#define BUFF_SIZE   5           /* total number of slots */
#define NP          3           /* total number of producers */
#define NC          3           /* total number of consumers */
#define NITERS      4           /* number of items produced/consumed */

typedef struct
{
    int buf[BUFF_SIZE];   /* shared var */
    int in;               /* buf[in%BUFF_SIZE] is the first empty slot */
    int out;              /* buf[out%BUFF_SIZE] is the first full slot */
    sem_t full;           /* keep track of the number of full spots */
    sem_t empty;          /* keep track of the number of empty spots */

    // use correct type here
    pthread_mutex_t mutex;          /* enforce mutual exclusion to shared data */
} sbuf_t;

sbuf_t shared;


void *Producer(void *arg)
{
    int i, item, index;

    index = (int)arg;


    for (i=0; i < NITERS; i++)
    {

        /* Produce item */
        item = i;

        /* Prepare to write item to buf */

        /* If there are no empty slots, wait */
        sem_wait(&shared.empty);
        /* If another thread uses the buffer, wait */
        pthread_mutex_lock(&shared.mutex);
        shared.buf[shared.in] = item;
        shared.in = (shared.in+1)%BUFF_SIZE;
        printf("[P%d] Producing %d ...\n", index, item);
        fflush(stdout);
        /* Release the buffer */
        pthread_mutex_unlock(&shared.mutex);
        /* Increment the number of full slots */
        sem_post(&shared.full);

        /* Interleave  producer and consumer execution */
        if (i % 2 == 1) sleep(1);
    }
    return NULL;
}

void *Consumer(void *arg)
{
    int i, item, index;

    index = (int)arg;
    for (i=NITERS; i > 0; i--) {
        sem_wait(&shared.full);
        pthread_mutex_lock(&shared.mutex);
        item=i;
        item=shared.buf[shared.out];
        shared.out = (shared.out+1)%BUFF_SIZE;
        printf("[C%d] Consuming  %d ...\n", index, item);
        fflush(stdout);
        /* Release the buffer */
        pthread_mutex_unlock(&shared.mutex);
        /* Increment the number of full slots */
        sem_post(&shared.empty);

        /* Interleave  producer and consumer execution */
        if (i % 2 == 1) sleep(1);
    }
    return NULL;
}

int main()
{
    pthread_t idP, idC;
    int index;

    sem_init(&shared.full, 0, 0);
    sem_init(&shared.empty, 0, BUFF_SIZE);
    pthread_mutex_init(&shared.mutex, NULL);
    for (index = 0; index < NP; index++)
    {
        /* Create a new producer */
        pthread_create(&idP, NULL, Producer, (void*)index);
    }
    /*create a new Consumer*/
    for(index=0; index<NC; index++)
    {
        pthread_create(&idC, NULL, Consumer, (void*)index);
    }



    pthread_exit(NULL);
}

J'espère que ça aide.

16
user2859193

Il existe toujours des avertissements du compilateur. La bonne façon d'obtenir la valeur entière d'un pointeur vide est:

index = *(int*)arg;

Et, également pour passer un pointeur entier, est ci-dessous:

pthread_create(&idC,NULL,Consumer,(void*)&index);

J'ai encore des doutes quant à la façon dont le thread consommateur ou producteur recevra la valeur entière transmise car il s'agit de l'adresse de la variable d'index dans la boucle for du thread principal. Dès que l'index est incrémenté, le thread consommateur ou producteur est affecté par cet incrément.

1
typelogic