Consumer/Producer pthreads 有等待时间

Consumer/Producer with pthreads having waiting times

我正在尝试使用我在 Internet 上选择的代码来实现 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 个时间间隔生产一个新项目。但是在这种情况下,它似乎在等待消费者完成,我似乎无法弄清楚为什么。

消费者在等待的整个过程中都持有互斥量,因此不允许生产者运行。

改变消费循环如下

    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 */

您将收到预期的结果。