【问题标题】:My consumer thread isn't reading my producer thread's products correctly我的消费者线程没有正确读取我的生产者线程的产品
【发布时间】:2013-12-20 10:38:54
【问题描述】:

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

有什么建议吗???

【问题讨论】:

  • 首先,修复编译时错误:for (i;。其次,我几乎可以肯定sum =+ num; 应该是sum += num;,并且任何合理的启用警告的编译都会对其进行标记。第三,您的线程程序不是return-ing 任何东西;他们需要。并且 none 涉及未受保护的谓词访问的 multiple 问题,未正确初始化的互斥体,在多个线程上播种 rand()(充其量是实现特定)等。
  • 是我还是您在进入 pthread_cond_wait() 之前没有锁定互斥锁?您应该在等待之前锁定互斥锁;另一方面,您最好在发出信号之前解锁。
  • @user16653 比这更糟糕。 OP 似乎认为条件变量是谓词,而不是用于通知谓词数据变量变化的信号机制。这是一座难以逾越的山丘,几乎每个第一次开始使用 pthreads 的人都会在第一次犯这个错误。
  • 我听从了@user16653 的建议,将互斥锁锁定后等待,解锁后放入信号。现在我的输出显示生产者制作了一些,消费者读取了一些(异步),并且它只读取了 5 个项目(它应该读取 6 个)。
  • @user198881 如果我有时间,我可以在这上面写一些东西。您对条件变量、它们的配对互斥体和谓词数据如何相互关联的一般概念是有缺陷的。它们不像你想象的那样工作。一个解释将是..涉及..展示这样做的正确方法,所以如果我有空闲时间,我会尝试写一些东西,除非有人打败我。

标签: c multithreading unix


【解决方案1】:

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

这是由于您使用了变量 done - 生产者在完成第 6 项后不久设置了 done = 1,而消费者在读取项目之前测试了 !done,因此它很可能会退出 @987654324 @循环没有读取和处理最后的项目。请参阅下文了解可能的解决方案。

当我向函数添加 return void 时,我得到一个错误,“预期 'void' 之前的主要表达式。

当然——我们不能返回类型; e. 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;
}

【讨论】:

    猜你喜欢
    • 2018-09-24
    • 2017-02-01
    • 2012-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-10
    • 1970-01-01
    相关资源
    最近更新 更多