码迷,mamicode.com
首页 > 其他好文 > 详细

生产者-消费者 模型

时间:2016-04-23 07:49:40      阅读:278      评论:0      收藏:0      [点我收藏+]

标签:生产者-消费者模型

一、相关概念:

    同步和互斥是进程间很重要的交互模式,而生产者和消费者问题则是同步和互斥的一个经典模型。

    同步是一种时序关系。如规定了进程1 处理完事情A后,进程2 才能处理事情 B,经典的同步问题是生产者和消费者间的同步。

    互斥描述的是一种独占关系。如任一时刻,进城1 和进程2 中只能有一个写文件C。


    生产者-消费者问题

       1、在同一个进程地址空间内执行的两个线程生产者线程生产物品,然后将物品放置在一个空缓冲区中供消费者线程消费。消费者线程从缓冲区中获得物品,然后释放缓冲区。当生产者线程生产物品时,如果没有空缓冲区可用,那么生产者线程必须等待消费者线程释放出一个空缓冲区。当消费者线程消费物品时,如果没有满的缓冲区,那么消费者线程将被阻塞,直到新的物品被生产出来。

       2、生产者中先同步再互斥,而消费者先互斥再同步,或反之;以及生产者和消费者都先互斥再同步这几种情况都不会死锁,因为它们间并没有交叉关系,就更不可能形成死锁环。之所以先同步,再互斥,是为了更好的并发性:并发性的瓶颈是互斥区,先同步再互斥,使得互斥区代码更短。


二、单 生产者-消费者模型:

    输入时,输入线程(插入等)是生产者,而计算线程是消费者;

    输出时,计算线程(删除等)是生产者,而打印线程是消费者。

    //链表:头进 尾出

#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>

typedef int data_type;
typedef int* data_type_p;

typedef struct _node
{
	data_type data;
	struct _node *next;
}node_t,*node_p,**node_pp;

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
node_p head=NULL;

static node_p buy_node(data_type _data)
{
	node_p tmp=malloc(sizeof(node_p));
	if(tmp)
	{
		tmp->data=_data;
		tmp->next=NULL;
		return tmp;
	}
	return NULL;
}
void init_list(node_pp _phead)
{
	*_phead=buy_node(0);
}

void delete_node(node_p tmp)
{
	if(tmp)
	{
		free(tmp);
		tmp=NULL;
	}
}
int pop_node(node_p list,data_type_p _data_p)
{
	if(list->next == NULL)
	{
		*_data_p=-1;
		return -1;
	}
	node_p tmp=list->next;
	list->next=tmp->next;
	*_data_p=tmp->data;
	delete_node(tmp);
	return 0;
}

void push_node(node_p list,data_type _data)
{
	node_p tmp=buy_node(_data);
	tmp->next=list;
	list->next=tmp;
}

void show_list(node_p list)
{
	node_p cur=list;
	while(cur)
	{
		printf("%d ",cur->data);
		fflush(stdout);
		cur=cur->next;
	}
}

void *product(void *arg)
{
	int i=0;
	while(1)
	{
		pthread_mutex_lock(&lock);
		printf("product data:%d\n",i++);
		push_node(head,i++);
		printf("product done ... wakeup consumer\n");
		pthread_mutex_unlock(&lock);
		pthread_cond_signal(&cond);
		sleep(1);
	}
}
void *consumer(void *arg)
{
	data_type _data;
	while(1)
	{
		pthread_mutex_lock(&lock);
		while(-1 == pop_node(head,&_data));
		{
			pthread_cond_wait(&cond,&lock);
		}
		printf("consumer data:%d\n",_data);
		pthread_mutex_unlock(&lock);
		sleep(1);
	}
}

int main()
{
        pthread_cond_t cond;
	pthread_cond_init(&cond,NULL);
	
	pthread_t tid1,tid2;
	pthread_create(&tid1,NULL,product,NULL);
	pthread_create(&tid2,NULL,consumer,NULL);
	pthread_join(tid1,NULL);
	pthread_join(tid2,NULL);
	pthread_cond_destroy(&cond);
	return 0;
}


    //链表的更改:尾进 头出 

    ... ...
int pop_node(node_p list,data_type_p _data_p)
{
	if(list->next == NULL)
	{
		*_data_p=-1;
		return -1;
	}
	node_p tmp=list;
	list=list->next;
	delete_node(tmp);
	return 0;
}
void push_node(node_p list,data_type _data)
{
        node_p tmp=buy_node(_data);
	while(list->next)
	{
		list=list->next;
	}
	list->next=tmp;
	tmp->data=_data;
	tmp->next=NULL;
}
    ... ...


三、多生产者-消费者模型:

// 其余代码见上 
int main()
{
        pthread_cond_t cond;
	pthread_cond_init(&cond,NULL);
	
	pthread_t tid1,tid2,tid3,tid4;
	pthread_create(&tid1,NULL,product,NULL);
	pthread_create(&tid2,NULL,product,NULL);
	pthread_create(&tid3,NULL,consumer,NULL);
	pthread_create(&tid4,NULL,consumer,NULL);
	pthread_join(tid1,NULL);
	pthread_join(tid2,NULL);
	pthread_join(tid3,NULL);
	pthread_join(tid4,NULL);
	pthread_cond_destroy(&cond);
	return 0;
}

   注意 :生产者消费者问题,是同步和互斥的一个经典模型。但需要注意死锁问题,需要先同步再互斥。

本文出自 “花开彼岸” 博客,请务必保留此出处http://zxtong.blog.51cto.com/10697148/1766832

生产者-消费者 模型

标签:生产者-消费者模型

原文地址:http://zxtong.blog.51cto.com/10697148/1766832

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!