所以我正在做一个学校项目,涉及创建两个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

有什么建议吗???

最佳答案

现在我的产出显示生产商生产了一些,消费者
读一些(异步的),它只读5个项目(它是
应该是6)。
这是由于使用变量done生产者在项目6之后不久就设置了cc>,并且消费者在读取一个项目之前测试了done = 1,因此它可以在不读取和处理最后的项目的情况下退出!done循环。请参阅下面的可能解决方案。
当我向函数添加返回void时,会得到一个错误
“void”之前的主表达式。
当然-我们不能返回类型;例如,while将是正确的。
这里有一个版本的return NULLproducer()包含了一些改进(请注意,我将条件变量consumer()empty分别重命名为fullnonfull,以准确描述它们的含义):

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

关于c - 我的使用者线程未正确读取生产者线程的产品,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20366966/

10-15 03:12