1. 基于单链表的生产者与消费者模型
生产者—消费者模型的321原则:
3种关系:生产者-生产者 ***互斥*** 消费者-消费者 ***互斥*** 生产者-消费者 ***互斥,同步***
2种角色:
消费者 生产者
1个交易场所:
临界资源
实现321的方法:
1个交易场所:创建一个带头节点的链表:
typedef struct _head //结构体声明
{
int data;
struct _head *next;
}Node,*Node_p,**Node_pp;
Node_p head; //头指针声明
void InitList(Node_pp _h) //初始化带头节点链表
{
*_h =(Node_p)malloc(sizeof(Node));
(*_h)->next = NULL;
}
void PushFrond(Node_p _h,int K)//
{
Node_p tmp = _h->next;
_h->next =(Node_p)malloc(sizeof(Node));
_h = _h->next;
_h->data = K;
_h->next = tmp;
}
Node_p PopFrond(Node_p _h)
{
if(_h->next == NULL)
return NULL;
Node_p tail = _h->next;
_h->next = tail->next;
return tail;
}
两个角色:我们需要创建两个线程:
void *consume(void *arg) // 用于消费,即调用PopFrond
void &product(void *arg) //用于生产,即调用PushFrond
互斥:函数consume与product不能运行临界区,即消费者,生产者不能同时访问临界资源(不能同时改变链表head):
我们可以用互斥锁
pthread_mutex_t mutex_lock = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_lock(&mutex_lock);//加锁
pthread_mutex_unlock(&mutex_lock);//解锁
同步:消费者不能超过生产者消费,当消费者发现没有资源时,就挂起等待,当生产者放入资源后发送信号唤醒消费者消费;
可以用条件变量即同时满足同步:
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_cond_wait(&cond,&mutex_lock);//等待
pthread_cond_signal(&cond);//发信号
信号的功能:
1.释放锁 //让其他线程访问临界区
2. 阻塞等待/
3. 唤醒时重新获得锁
消费者-生产者模型编写:
void* product(void *arg)
{
while(1){
int n = rand()/12123;
pthread_mutex_lock(&mutex_lock); //解锁访问
PushFrond(head,n);
printf("product done! %d\n",n);
pthread_mutex_unlock(&mutex_lock);//解锁
pthread_cond_signal(&cond);//生产完成,发送信号,消费者消费
sleep(2);
}
return NULL;
}
void *consum(void *arg)
{
while(1){
pthread_mutex_lock(&mutex_lock);//加锁访问
Node_p tmp = PopFrond(head);
while(tmp == NULL)//当没有资源时,则阻塞等待
{
pthread_cond_wait(&cond, &mutex_lock);
tmp = PopFrond(head);
}
printf("consum done! %d\n",tmp->data);
pthread_mutex_unlock(&mutex_lock);//解锁
}
return NULL;
}