Posix线程 - (互斥和条件变量)问题,

时间:2014-01-23 11:55:26

标签: c++ pthreads mutex

以下是我使用posix线程尝试生产者消费者问题的代码。 在我的代码中,我使用条件变量来等待并发出互斥信号。我的代码允许我配置生产者和消费者线程的数量。

但是当消费者线程数超过生产者线程数时,我的程序挂起并且没有完成。

我认为,生产者线程函数已经在消费者线程函数之前通过将最大值放入队列来完成。等待的消费者线程没有收到信号。虽然在完成之前,生产者线程已为它添加到队列中的每个值生成信号。

需要帮助来识别代码中的问题,以便它可以针对生产者和消费者线程计数的任何组合运行。

#include<iostream>
#include<queue>
#include<pthread.h>

using namespace std;

pthread_cond_t c=PTHREAD_COND_INITIALIZER;
pthread_mutex_t m=PTHREAD_MUTEX_INITIALIZER;

long max_item=50000;
long produced=0;
long consumed=0;

const long producer_count=5;
const long consumer_count=15;

queue<long>q;

void * producer(void *)
{
    long i=1;
    while(true)
    {
        pthread_mutex_lock(&m);
        if(produced==max_item)
        {pthread_mutex_unlock(&m);break;} 

        q.push(i++);++produced;
        pthread_cond_signal(&c);
        pthread_mutex_unlock(&m);
    }
    pthread_mutex_lock(&m);
    cout<<"Producer produced:"<<i-1<<endl;
    pthread_mutex_unlock(&m);

}
void *consumer(void *)
{
    long i=1;
    long val=0;
    while(true)
    {
        pthread_mutex_lock(&m);
        if(consumed==max_item){pthread_mutex_unlock(&m);break;}    
        while(q.empty())
           {pthread_cond_wait(&c,&m);}
        val=q.front();q.pop();
        ++i,consumed++;
        pthread_mutex_unlock(&m);
    }
    pthread_mutex_lock(&m);
    cout<<"Consumer consumed:"<<i-1<<endl;
    pthread_mutex_unlock(&m);
}
int main()
{
   pthread_t p[producer_count],c[consumer_count];

   for(int i=0;i<producer_count;++i)
    pthread_create(&p[i],NULL,producer,NULL);

   for(int i=0;i<consumer_count;++i)
    pthread_create(&c[i],NULL,consumer,NULL);

   for(int i=0;i<producer_count;++i)
    pthread_join(p[i],NULL);

   for(int i=0;i<consumer_count;++i)
    pthread_join(c[i],NULL);

   cout<<"Total produced:"<<produced<<endl;
   cout<<"Total consumed:"<<consumed<<endl;
   cout<<"Queue size at end:"<<q.size()<<endl;

   pthread_mutex_destroy(&m);
    return 0;
}


Output:
$ ./a.out
Producer produced:12740
Consumer consumed:3351
Producer produced:16948
Consumer consumed:2512
Consumer consumed:3383
Producer produced:4892
Producer produced:7417
Consumer consumed:5374
Consumer consumed:4550
Producer produced:8003
Consumer consumed:5229
Consumer consumed:2023
Consumer consumed:1366
Consumer consumed:3346
Consumer consumed:2231

--Program hangs here-----


Output from different run when both producer and consumer thread count are set to 15.
$ ./a.out
Producer produced:1276
Producer produced:2162
Producer produced:1401
Producer produced:505
Producer produced:455
Producer produced:1900
Producer produced:2522
Producer produced:901
Producer produced:308
Producer produced:1461
Producer produced:755
Producer produced:102
Producer produced:21332
Consumer consumed:514
Consumer consumed:1335
Consumer consumed:4219
Consumer consumed:1422
Consumer consumed:644
Consumer consumed:231
Producer produced:14191
Consumer consumed:621
Consumer consumed:541
Consumer consumed:1505
Consumer consumed:32234
Consumer consumed:1985
Producer produced:729
Consumer consumed:2723
Consumer consumed:1012
Consumer consumed:69
Consumer consumed:945
Total produced:50000
Total consumed:50000
Queue size at end:0

---Program completes here after showing produced and consumed count are equal and queue is fully consumed.

1 个答案:

答案 0 :(得分:1)

消费者循环直到获得所有生产的商品,但是对于更多的消费者,商品会被分割,因此您需要另外检查以查看消费者何时完成。生产者可以设置一个完成的布尔值,并使用pthread_cond_broadcast与相同的条件变量发出信号,因此消费者应该在等待空队列之前在锁定的互斥锁中检查它。