环保油 东莞网站建设,动易学校网站管理系统,住建网站需多少钱,程序员客栈https://www.cnblogs.com/caolicangzhu/p/7086176.html本文主要来总结生产者-消费者模型的代码实现,至于其原理,请大家自行百度.
一、基于链表的生产-消费模型(条件变量)我们以链表为例,生产者进行头部插入,消费者进行头部删除,因此,先将链表相关操作封装为LinkList.h,具体代码…https://www.cnblogs.com/caolicangzhu/p/7086176.html本文主要来总结生产者-消费者模型的代码实现,至于其原理,请大家自行百度.
一、基于链表的生产-消费模型(条件变量)我们以链表为例,生产者进行头部插入,消费者进行头部删除,因此,先将链表相关操作封装为LinkList.h,具体代码如下:
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980//文件说明:LinkList.h//作者:高小调//创建时间:2017年06月27日 星期二 14时57分27秒//开发环境:Kali Linux/g v6.3.0#includeassert.h#includestdlib.h#includestdio.h//链表节点typedef struct LinkListNode{ int val; struct inkListNode *next;}Node,*pNode,**ppNode;//初始化链表void InitLinkList(ppNode head){ assert(head); *head NULL;}//判断链表是否为空int IsEmpty(pNode head){ return headNULL;}//申请新节点pNode BuyNewNode(int val){ pNode ret (pNode)malloc(sizeof(Node)); ret-val val; ret-next NULL; return ret;}//头插void PushFront(ppNode head,int val){ assert(head); if(*headNULL){ *head BuyNewNode(val); return ; } pNode newNode BuyNewNode(val); newNode-next *head; *head newNode;}//头删void PopFront(ppNode head,int *val){ assert(head); if((*head) NULL){ return ; } if((*head)-next NULL){ *val (*head)-val; free(*head); *head NULL; return ; } pNode del *head; *head del-next; *val del-val; free(del);}//销毁链表void Destory(ppNode head){ assert(head); pNode cur *head; pNode del NULL; while(cur!NULL){ del cur; cur cur-next; free(del); } *head NULL;}//打印链表void PrintLinkList(pNode head){ pNode cur head; while(cur!NULL){ printf(%d ,cur-val); cur cur-next; } printf(\n);}然后进入我们线程的生产消费模型:
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071//文件说明:test.c//作者:高小调//创建时间:2017年06月27日 星期二 14时56分13秒//开发环境:Kali Linux/g v6.3.0#includestdio.h#includepthread.h#includeLinkList.h//互斥锁pthread_mutex_t lock PTHREAD_MUTEX_INITIALIZER;//条件变量pthread_cond_t cond PTHREAD_COND_INITIALIZER;//测试链表void TestLinkList(){ pNode head; InitLinkList(head); int tmp; for(int i0; i10; i){ PushFront(head,i); PrintLinkList(head); } for(int i0; i10; i){ PopFront(head,tmp); PrintLinkList(head); }}pNode head;//生产者:每次向头节点插入数据void *Productor(void*arg){ int val 0; while(1){ //互斥锁加锁:确保生产时不会消费,消费时不会生产 pthread_mutex_lock(lock); val rand()%100; PushFront(head,val); printf(Productor push %d\n,val); //互斥锁解锁 pthread_mutex_unlock(lock); //条件变量,生产完成之后向消费者发出信号消费 pthread_cond_signal(cond); sleep(1); }}//消费者:每次将头节点数据取出void *Consumer(void*arg){ int val 0; while(1){ //互斥锁 pthread_mutex_lock(lock); while(headNULL){ //链表中没数据,阻塞等待生产者发消费信号 printf(wait for data\n); pthread_cond_wait(cond,lock); } PopFront(head,val); printf(Consumer pop %d\n,val); pthread_mutex_unlock(lock); sleep(1); }}int main(){ InitLinkList(head); pthread_t cid1,cid2; pthread_create(cid1,NULL,Productor,NULL); pthread_create(cid2,NULL,Consumer,NULL); pthread_join(cid1,NULL); pthread_join(cid2,NULL); return 0;}二、基于环形队列的生产-消费模型(信号量)
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859//文件说明:test2.c//作者:高小调//创建时间:2017年06月27日 星期二 16时29分30秒//开发环境:Kali Linux/g v6.3.0#includestdio.h#includepthread.h#includesemaphore.h#includestdlib.h#define SIZE 1024//环形队列int arr[SIZE] {0};sem_t sem_pro; //描述环形队列中的空位置sem_t sem_con; //描述唤醒队列中的数据//生产者只要环形队列有空位,便不断生产void*productor(void*arg){ int data 0; int proIndex 0; while(1){ //有空位便生产,没空位便阻塞等消费者消费 sem_wait(sem_pro); data rand()%1234; arr[proIndex] data; printf(product done %d\n,data); proIndex (proIndex1)%SIZE; //供消费者消费的数据加1 sem_post(sem_con); }}//消费者,只要环形队列中有数据,就不断消费void*consumer(void*arg){ int data 0; int conIndex 0; while(1){ //环形队列中存在数据则消费,不存在数据则阻塞,直到有数据为止 sem_wait(sem_con); data arr[conIndex]; printf(consume done %d\n,data); conIndex (conIndex1)%SIZE; //最后,消费了一个数据,空位加1 sem_post(sem_pro); }}int main(){ pthread_t pro,con; sem_init(sem_pro,0,SIZE-1); //一开始有很多空位置 sem_init(sem_con,0,0); //但并没有数据 pthread_create(pro,NULL,productor,NULL); pthread_create(con,NULL,consumer,NULL); pthread_join(pro,NULL); pthread_join(con,NULL); sem_destroy(sem_pro); sem_destroy(sem_con); return 0;}