所以我正在做一个学校项目,涉及创建两个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 NULL
和producer()
包含了一些改进(请注意,我将条件变量consumer()
和empty
分别重命名为full
和nonfull
,以准确描述它们的含义):
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/