问题描述
一组生产者线程和一组消费者线程共享一个初始为空、大小为n的缓冲区,只有缓冲区没满时,生产者才能把消息放入到缓冲区,否则必须等待;只有缓冲区不空时,消费者才能从中取出消息,否则必须等待。由于缓冲区是临界资源,它只允许一个生产者放入消息,或者一个消费者从中取出消息。
问题分析
-
关系分析。生产者和消费者对缓冲区互斥访问是互斥关系,同时生产者和消费者又是一个相互协作的关系,只有生产者生产之后,消费者才能消费,他们也是同步关系。
-
整理思路。这里比较简单,只有生产者和消费者两种线程,正好是多个线程存在着互斥关系和同步关系。那么需要解决的是互斥和同步PV操作的位置。
-
模拟问题。使用队列模拟缓冲区,生产者与消费者用独立线程模拟。
-
实现同步。锁mutex,用于控制互斥访问缓冲池以及与条件变量配合使用;条件变量cond用于消费者记录当前缓冲池中是否非空。条件变量cond1用于生产者记录当前缓冲池中是否已满。
核心代码
void *producer(void *a)
{
while(1){
pthread_mutex_lock(&mutex);
while(full(&pc)==1){
printf("生产者%ld等待中\n",pthread_self());
pthread_cond_wait(&cond,&mutex);
}
produce(&pc);
printf("生产者%ld生产%d\n",pthread_self(),pc.tail->date);
if(pc.len==1){
pthread_cond_signal(&cond);
}
pthread_mutex_unlock(&mutex);
sleep(1);
}
}
void *consumer(void *a)
{
while(1){
pthread_mutex_lock(&mutex);
while(empty(&pc)==1){
printf("\t\t\t消费者%ld等待中\n",pthread_self());
pthread_cond_wait(&cond,&mutex);
}
printf("\t\t\t消费者%ld消费%d\n",pthread_self(),pc.head->date);
consume(&pc);
if(pc.len==5){
pthread_cond_signal(&cond1);
}
pthread_mutex_unlock(&mutex);
sleep(1);
}
}