生活随笔
收集整理的這篇文章主要介紹了
生产者与消费者模型
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
生產者消費者模型
簡單來說就是“321原則(并非某一規則,而是為了理解生產者消費者模型)”
“3”代表的是三種關系
生產者與消費者的互斥與同步關系
生產者與生產者的互斥(或競爭)關系
消費者與消費者的互斥(或競爭)關系
“2”代表兩種角色
生產者:往交易場所放東西(在計算機中一般都是數據)的人
消費者:從交易場所取東西的人
“1”代表一個交易場所
所謂交易場所就是內存中具有存儲數據的一段有界緩沖區
綜上,給出生產者消費者模型的描述:兩個進程共享一個緩沖區,一個進程稱為生產者向緩沖區中放數據,另一個稱為消費者從緩沖取中取數據,當緩沖區中被放時,生產者進程就必須可進入掛起狀態,直到消費者從緩沖中取走數據時,生產者才能繼續向緩沖區中存放數據,同樣當緩沖取中沒有數據時,消費者進程就必須進入掛起休眠狀態,直到生產者向緩沖區中放入數據時,消費者才能被喚醒繼續從緩沖區中取走數據。
圖示:
基于鏈表的生產者消費者模型
分析:當使用鏈表來模擬生產者消費者模型時,我們可以借助鏈表的插入來扮演生產者的角色,用鏈表的刪除來充當消費者的角色,為了便于實現,我們直接采用鏈表的頭插和鏈表的頭刪操作來模擬放數據和取數據這兩個過程。
(1)條件變量接口說明
[html]?view plaincopy
<span?style="font-family:Microsoft?YaHei;font-size:18px;">int??pthread_cond_wait(pthread_cond_t*?redtrist?cond?,??pthread_mutex_t*?redtrist?)//掛起等待</span>??
1、不滿足條件時必須進行休眠(釋放Mutex)
2、不能抱著鎖資源休眠(進行阻塞式等待)
3、能被喚醒(被喚醒時能夠重新獲得Mutex資源并等待)
[html]?view plaincopy
<span?style="font-family:Microsoft?YaHei;font-size:18px;">int??pthread_cond_signal(pthread_cond_t*?cond?)?????//喚醒</span>??
1、生產者生產好數據之后通知消費者來消費數據
2、消費者消費完數據后通知生產者前來生產
(2)鎖相關接口說明
[html]?view plaincopy
<span?style="font-family:Microsoft?YaHei;font-size:18px;">int?pthread_mutex_lock(pthread_mutex_t?*mutex);</span>??
阻塞式加鎖
[html]?view plaincopy
<span?style="font-family:Microsoft?YaHei;font-size:18px;">int?pthread_mutex_trylock(pthread_mutex_t?*mutex);</span>??
非阻塞式加鎖
[html]?view plaincopy
<span?style="font-family:Microsoft?YaHei;font-size:18px;">int?pthread_mutex_unlock(pthread_mutex_t?*mutex);</span>??
解鎖,無論是阻塞式的加鎖還是非阻塞式的加鎖都需要使用此函數進行解鎖
基于單鏈表的生產者消費者模型實現
[html]?view plaincopy
<span?style="font-family:Microsoft?YaHei;font-size:18px;">#include<stdio.h>?? #include<pthread.h>?? #include<stdlib.h>?? ?? typedef?struct?list?? {?? ????????int?data;?? ????????struct?list*?next;?? }list,*plist,**pplist;?? ?? plist?head;?? ?? pthread_cond_t?cond=PTHREAD_COND_INITIALIZER;?? ?? plist?alloc_node(int?d,plist?l)?? {?? ????????plist?tmp=(plist)malloc(sizeof(list));?? ????????if(!tmp){?? ????????????????perror("malloc");?? ????????????????exit(1);?? ????????}?? ????????tmp->data=d;?? ????????tmp->next=l;?? ????????return?tmp;?? }?? ?? void?initlist(pplist?l){?? ????????*l=alloc_node(0,NULL);?? }?? ?? int?isempty(plist?l){?? ????????return?l->next==NULL?1:0;?? }?? ?? void?free_node(plist?l){?? ????????if(l!=NULL){?? ????????????????free(l);?? ????????????????l=NULL;?? ????????}?? }?? ?? void?push_front(plist?l,int?d){?? ????????plist?tmp=alloc_node(d,NULL);?? ????????????????tmp->next=l->next;?? ????????????????l->next=tmp;?? ?}?? ?? void?pop_front(plist?l,int*?out)?? {?? ????????if(!isempty(l)){?? ????????????????plist?tmp=l->next;?? ????????????????l->next=tmp->next;?? ????????????????*out=tmp->data;?? ????????????????free_node(tmp);?? ????????}?? }?? ?? void?showlist(plist?l)?? {?? ????????plist?start=l->next;?? ????????while(start){?? ????????????????printf("%d?",start->data);?? ????????????????start=start->next;?? ????????}?? ????????printf("\n");?? }?? ?? void?destroy(plist?l){?? ????????int?data;?? ????????while(!isempty(l)){?? ????????????????pop_front(l,&data);?? ????????}?? ????????free_node(l);?? }?? ?? void*?consume(void*?arg){?? ????????pthread_mutex_t*?lockp=(pthread_mutex_t*)arg;?? ????????int?data=0;?? ????????while(1){?? ????????????????pthread_mutex_lock(lockp);?? ????????????????if(isempty(head)){?? ????????????????????????pthread_cond_wait(&cond,&lockp);?? ????????????????}?? ????????????????pop_front(head,&data);?? ????????????????printf("consum?done:?%d\n",data);?? ????????????????pthread_mutex_unlock(lockp);?? ????????????????pthread_cond_signal(&cond);?? ????????}?? }?? void*?product(void*?arg){?? ????????pthread_mutex_t*?lockp=(pthread_mutex_t*)arg;?? ????????int?data=0;?? ????????while(1){?? ????????????????pthread_mutex_lock(lockp);?? ????????????????data=rand()%1234;?? ????????????????push_front(head,data);?? ????????????????printf("product?done:?%d\n",data);?? ????????????????pthread_mutex_unlock(lockp);?? ?? ????????????????pthread_cond_signal(&cond);?? ????????}?? }?? ?? int?main()?? {?? ????????pthread_mutex_t?lock;?? ????????pthread_mutex_init(&lock,NULL);?? ?? ????????initlist(&head);?? ????????pthread_t?consumer,producter;?? ????????pthread_create(&consumer,NULL,consume,(pthread_mutex_t?*)&lock);?? ????????pthread_create(&producter,NULL,product,(pthread_mutex_t?*)&lock);?? ?? ????????pthread_join(consumer,NULL);?? ????????pthread_join(producter,NULL);?? ????????destroy(head);?? ????????pthread_mutex_destroy(&lock);?? ????????return?0;?? }</span>??
超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生
總結
以上是生活随笔為你收集整理的生产者与消费者模型的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。