生产者-消费者模型的两种实现方式
生活随笔
收集整理的這篇文章主要介紹了
生产者-消费者模型的两种实现方式
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
https://www.cnblogs.com/caolicangzhu/p/7086176.html
本文主要來總結生產者-消費者模型的代碼實現,至于其原理,請大家自行百度.
一、基于鏈表的生產-消費模型(條件變量)
我們以鏈表為例,生產者進行頭部插入,消費者進行頭部刪除,因此,先將鏈表相關操作封裝為LinkList.h,具體代碼如下:
| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 | //文件說明:LinkList.h//作者:高小調//創(chuàng)建時間:2017年06月27日 星期二 14時57分27秒//開發(fā)環(huán)境:Kali Linux/g++ v6.3.0#include<assert.h>#include<stdlib.h>#include<stdio.h>//鏈表節(jié)點typedef?struct?LinkListNode{????int?val;????struct?inkListNode *next;}Node,*pNode,**ppNode;//初始化鏈表void?InitLinkList(ppNode head){????assert(head);????*head = NULL;}//判斷鏈表是否為空int?IsEmpty(pNode head){????return?head==NULL;}//申請新節(jié)點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(*head==NULL){????????*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//作者:高小調//創(chuàng)建時間:2017年06月27日 星期二 14時56分13秒//開發(fā)環(huán)境:Kali Linux/g++ v6.3.0#include<stdio.h>#include<pthread.h>#include"LinkList.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?i=0; i<10; ++i){????????PushFront(&head,i);????????PrintLinkList(head);????}????for(int?i=0; i<10; ++i){????????PopFront(&head,&tmp);????????PrintLinkList(head);????}}pNode head;//生產者:每次向頭節(jié)點插入數據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);????????//條件變量,生產完成之后向消費者發(fā)出信號消費????????pthread_cond_signal(&cond);????????sleep(1);????}}//消費者:每次將頭節(jié)點數據取出void?*Consumer(void*arg){????int?val = 0;????while(1){????????//互斥鎖????????pthread_mutex_lock(&lock);????????while(head==NULL){????????????//鏈表中沒數據,阻塞等待生產者發(fā)消費信號????????????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;} |
?二、基于環(huán)形隊列的生產-消費模型(信號量)
| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859 | //文件說明:test2.c//作者:高小調//創(chuàng)建時間:2017年06月27日 星期二 16時29分30秒//開發(fā)環(huán)境:Kali Linux/g++ v6.3.0#include<stdio.h>#include<pthread.h>#include<semaphore.h>#include<stdlib.h>#define SIZE 1024//環(huán)形隊列int?arr[SIZE] = {0};sem_t sem_pro;??????//描述環(huán)形隊列中的空位置sem_t sem_con;??????//描述喚醒隊列中的數據//生產者,只要環(huán)形隊列有空位,便不斷生產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 = (proIndex+1)%SIZE;????????//供消費者消費的數據加1????????sem_post(&sem_con);????}}//消費者,只要環(huán)形隊列中有數據,就不斷消費void*consumer(void*arg){????int?data = 0;????int?conIndex = 0;????while(1){????????//環(huán)形隊列中存在數據則消費,不存在數據則阻塞,直到有數據為止????????sem_wait(&sem_con);????????data = arr[conIndex];????????printf("consume done %d\n",data);????????conIndex = (conIndex+1)%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;} |
?
總結
以上是生活随笔為你收集整理的生产者-消费者模型的两种实现方式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: p40pro拍摄视频用那个摄像头?
- 下一篇: 爱在下个秋天剧情介绍