使用信号量和pthreads的Producer Consumer程序

时间:2013-11-07 19:18:20

标签: c pthreads semaphore

我已经为生产者 - 消费者问题写了一个代码。但是我没有得到输出。没有编译错误,但在我的程序中发出警告。我很困惑。非常努力。但是不能得到它。请告诉我我的程序有什么问题。什么是正确的程序。我感到很沮丧。请帮助你们。 这是代码 -

#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);
}

2 个答案:

答案 0 :(得分:16)

也许您应该更严肃地对待编译器警告。 通常会显示不正确的类型和未定义的函数 作为警告...

我没有检查你的程序的逻辑,但原则应该有效:

#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);
}

我希望这会有所帮助。

答案 1 :(得分:1)

仍有编译器警告。从void指针获取整数值的正确方法是:

index = *(int*)arg;

并且,也传递一个整数指针,如下所示:

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

我仍然怀疑Consumer或Producer线程将如何接收传递的整数值,因为它是主线程中for循环中索引变量的地址。一旦索引增加,Consumer或Producer线程就会受到此增量的影响。