我的消费者线程没有正确读取我的生产者线程的产品

时间:2013-12-04 04:38:51

标签: c multithreading unix

所以我正在做一个涉及创建两个pthread的学校项目,一个充当生产者,一个充当消费者,通过共享的有界缓冲区进行通信。我投入了一些调试行,每次生产者创建一个新的int放入缓冲区时在控制台上打印一个语句,并在消费者读取数字时显示另一行。看起来他们保持同步前两个,制作人制作一个项目,消费者阅读一个项目等,然后制作人制作一切,消费者只读取最终产品,忽略中间的产品。这是我的代码:

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

pthread_cond_t empty;
pthread_cond_t full;
int done = 0;
pthread_mutex_t lock;
int in = 0;
int out = 0;
int BUFFER_SIZE = 5;
int buffer[5];

void *consumer();
void *producer();

int main() {
pthread_t tidC;
pthread_t tidP;

pthread_cond_init(&empty, NULL);
pthread_cond_init(&full, NULL);

pthread_create(&tidP, NULL, &producer, NULL);
pthread_create(&tidC, NULL, &consumer, NULL);

pthread_join(tidC, NULL);
pthread_join(tidP, NULL);

return 0;
}

void * producer() {
int seed = 6;
int reps = 7;
int num = 0;
int i = 0;

srand(seed);
printf("Producer in for\n");/*DEBUG*/   
for(i; i<reps; i++) {
    printf("Producer making item %d\n", i);
    num = rand();

    while(pthread_cond_signal(&full))
    {
        pthread_cond_wait(&empty, &lock);
    }

    pthread_mutex_lock(&lock);/*entering critical section*/

    buffer[in] = num;

    pthread_cond_signal(&full);

    pthread_mutex_unlock(&lock);/*exiting critical section*/

    in++;

    if(in == BUFFER_SIZE) {
        in = 0;
    }
}

done = 1;
}

void * consumer() {
int num = 0;
int min=0;
int max=0;
int avg=0;
int numItems=0;
int first=1;
int reps = 3;
int sum = 0;    

printf("Consumer Entering While\n");/*DEBUG*/

while(!done) {
    while(pthread_cond_signal(&empty)){
        pthread_cond_wait(&full, &lock);    
    }

    printf("Consumer reading item %d\n", numItems);

    pthread_mutex_lock(&lock); /*enter critical section*/

    num = buffer[out];

    pthread_cond_signal(&empty);

    pthread_mutex_unlock(&lock); /*exit critical section*/  

    out++;

    if(out == BUFFER_SIZE)
        out = 0;

    /*processing*/

    if(first) {
        min = num;
        max = num;
        sum = num;
        first = 0;
        numItems = 1;
    }
    else {
        if(num < min)
            min = num;

        sum =+ num;

        if(num>max)
            max = num;

        numItems++;
    }
}


avg = sum/numItems;/*calc avg*/

/*report stats*/
printf("Minimum: %d\n", min);
printf("Maximum: %d\n", max);
printf("Average: %d\n", avg);
printf("Items Produced: %d\n", numItems);
 }

我的输出是:

Producer in for
Consumer Entering While
Producer making item 0
Consumer reading item 0
Producer making item 1
Producer making item 2
Producer making item 3
Producer making item 4
Producer making item 5
Producer making item 6
Consumer reading item 1
Minimum: 2726
Maximum: 25069
Average: 12534
Items Produced: 2

任何建议???

1 个答案:

答案 0 :(得分:0)

  

现在我的输出显示了生产者,消费者   读一些(异步),它只读了5个项目(它是#   应该阅读6)。

由于您使用了变量done - 生产者在制作第6项后立即设置done = 1,并且消费者在读取之前测试!done item,所以它可能会退出while循环,而不会读取和处理最后的项目。请参阅下面的可能解决方案。

  

当我向函数添加返回void时,我收到错误,&#34;预期   在&#39; void&#39;之前的主要表达。

当然 - 我们不能归类;即G。 return NULL是正确的。

此处有producer()consumer()的版本,其中包含多项改进(请注意,我已将条件变量emptyfull重命名为nonfullnonempty分别准确描述其含义):

void *producer()
{
    int seed = 6;
    int reps = 7;
    int num;
    int i = 0;
    srand(seed);
    printf("Producer in for\n");/*DEBUG*/   
    for (; i<reps; i++)
    {
        num = rand();
        pthread_mutex_lock(&lock);/*entering critical section*/
        if (in == out+BUFFER_SIZE)  // buffer full?
            pthread_cond_wait(&nonfull, &lock); // if so, wait
        printf("Producer making item %d\n", i);
        buffer[in++%BUFFER_SIZE] = num;
        pthread_cond_signal(&nonempty);
        pthread_mutex_unlock(&lock);/*exiting critical section*/
    }
    done = i;
    return NULL;
}

void *consumer()
{
    int num;
    int min;
    int max;
    int avg;
    int numItems = 0;
    int first = 1;
    int sum = 0;    
    printf("Consumer Entering While\n");/*DEBUG*/
    while (!done || numItems < done)
    {   // loop as long as not all produced items are consumed
        pthread_mutex_lock(&lock); /*enter critical section*/
        if (out == in)  // buffer empty?
            pthread_cond_wait(&nonempty, &lock);    // if so, wait
        printf("Consumer reading item %d\n", numItems);
        num = buffer[out++%BUFFER_SIZE];
        pthread_cond_signal(&nonfull);
        pthread_mutex_unlock(&lock); /*exit critical section*/  
        /*processing*/
        if (first)
        {
            min = num;
            max = num;
            first = 0;
        }
        if (num < min) min = num;
        sum =+ num;
        if (num > max) max = num;
        numItems++;
    }
    avg = sum/numItems;/*calc avg*/
    /*report stats*/
    printf("Minimum: %d\n", min);
    printf("Maximum: %d\n", max);
    printf("Average: %d\n", avg);
    printf("Items Produced: %d\n", numItems);
    return NULL;
}