具有等待时间的pthreads的消费者/生产者

时间:2015-03-28 13:55:13

标签: c multithreading pthreads mutex

我正在尝试用我在互联网上挑选的代码实现一个稍微修改过的Consumer / Producer程序版本。以下是我自己的修改:

   /*
 *  Solution to Producer Consumer Problem
 *  Using Ptheads, a mutex and condition variables
 *  From Tanenbaum, Modern Operating Systems, 3rd Ed.
 */

/*
 In this version the buffer is a single number.
 The producer is putting numbers into the shared buffer
 (in this case sequentially)
 And the consumer is taking them out.
 If the buffer contains zero, that indicates that the buffer is empty.
 Any other value is valid.
 */

#include <stdio.h>
#include <pthread.h>

#define MAX 3       /* # of item  to produce */
pthread_mutex_t the_mutex;
pthread_cond_t condc, condp;
int consumeTimes[MAX] = { 1, 4, 3 };
int toConsume = 0;

void* producer(void *ptr) {
    int i;

    for (i = 0; i < MAX; i++) {
        pthread_mutex_lock(&the_mutex); /* protect buffer */
        /*while (buffer != 0)              /* If there is something in the buffer then wait
         pthread_cond_wait(&condp, &the_mutex);*/
        printf("Producer: Produced item %d \n", i);
        toConsume++;
        pthread_cond_signal(&condc); /* wake up consumer */
        pthread_mutex_unlock(&the_mutex); /* release the buffer */
        sleep(3);

    }
    pthread_exit(0);
}

void* consumer(void *ptr) {
    int i;
    for (i = 0; i < MAX; i++) {
        pthread_mutex_lock(&the_mutex); /* protect buffer */
        while (toConsume <= 0) /* If there is nothing in the buffer then wait */
            pthread_cond_wait(&condc, &the_mutex);
        sleep(consumeTimes[i]);
        printf("Consumer: Consumed item %d\n", i);
        toConsume--;
        //pthread_cond_signal(&condp);  /* wake up consumer */
        pthread_mutex_unlock(&the_mutex); /* release the buffer */

    }
    pthread_exit(0);
}

int main(int argc, char **argv) {
    pthread_t pro, con;

    // Initialize the mutex and condition variables
    /* What's the NULL for ??? */
    pthread_mutex_init(&the_mutex, NULL);
    pthread_cond_init(&condc, NULL); /* Initialize consumer condition variable */
    pthread_cond_init(&condp, NULL); /* Initialize producer condition variable */

    // Create the threads
    pthread_create(&con, NULL, consumer, NULL);
    pthread_create(&pro, NULL, producer, NULL);

    // Wait for the threads to finish
    // Otherwise main might run to the end
    // and kill the entire process when it exits.
    pthread_join(&con, NULL);
    pthread_join(&pro, NULL);

    // Cleanup -- would happen automatically at end of program
    pthread_mutex_destroy(&the_mutex); /* Free up the_mutex */
    pthread_cond_destroy(&condc); /* Free up consumer condition variable */
    pthread_cond_destroy(&condp); /* Free up producer condition variable */

}

这就是我想要做的事情:

基本上,每个项目都有消耗和生产时间。

consumeTimes数组中的每个项目指示消耗时间。

因此,例如 consumeTimes [0] = 1 ,这意味着消费第一项只需要一个时间单位。

对于制作,我使用一个恒定的时间值 sleep(3),因此制作每个项目应该需要3个时间单位。

当我运行代码时,我总是得到以下输出:

Producer: Produced item 0 
Consumer: Consumed item 0
Producer: Produced item 1 
Consumer: Consumed item 1
Producer: Produced item 2 
Consumer: Consumed item 2

但是,考虑到生产和消费时间,它应该是这样的:

Producer: Produced item 0 (t=0)
Consumer: Consumed item 0 (t=1)
Producer: Produced item 1 (t=3)
Producer: Produced item 2 (t=6)
Consumer: Consumed item 1 (t=7)
Consumer: Consumed item 2 (t=9)

简而言之,生产者必须每隔3个时间间隔生产一个新项目。但在这种情况下,它似乎在等待消费者完成,我似乎无法弄清楚原因。

1 个答案:

答案 0 :(得分:2)

消费者在整个等待期间持有互斥锁,因此不允许生产者运行。

按如下方式更改消费循环

    pthread_mutex_lock(&the_mutex); /* protect buffer */
    while (toConsume <= 0) /* If there is nothing in the buffer then wait */
        pthread_cond_wait(&condc, &the_mutex);
    pthread_mutex_unlock(&the_mutex); /* release the buffer */

    sleep(consumeTimes[i]);

    pthread_mutex_lock(&the_mutex); /* protect buffer */
    printf("Consumer: Consumed item %d\n", i);
    toConsume--;
    pthread_mutex_unlock(&the_mutex); /* release the buffer */

您将收到预期的结果。