【问题标题】:Producer Consumer program using semaphores and pthreads使用信号量和 pthread 的生产者消费者程序
【发布时间】:2013-11-19 14:47:39
【问题描述】:

我已经为生产者-消费者问题编写了代码。但我没有得到输出。没有编译错误,但我的程序中有警告。我很困惑。非常努力。但无法得到它。拜托告诉我我的程序出了什么问题。什么是正确的程序。我很沮丧。请帮助大家。 这是代码-

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

【问题讨论】:

    标签: c pthreads semaphore


    【解决方案1】:

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

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

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

    我希望这会有所帮助。

    【讨论】:

    • 它的工作。但是如果我们放置 sem_wait(&shared.mutex) 和 sem_post(&shared.mutex); 为什么它不起作用而不是 pthread_mutex_lock(&shared.mutex);和 pthread_mutex_unlock(&shared.mutex);???请解释一下。
    • 你必须决定是使用信号量还是互斥量,然后你必须使用 sem_init 而不是 pthread_mutex_init 并将初始值设置为 1,因为 wait_sem 会减小信号量的值,如果 Value is > 0 否则它会阻塞,直到 Value 变得 > 0。什么都不会发生。
    【解决方案2】:

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

    index = *(int*)arg;
    

    而且,还要传递一个整数指针,如下:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多