您好,登錄后才能下訂單哦!
條件變量
有關函數:
當向條件變量發送一個信號時,如果沒有線程等待在條件變量,那么該信號會丟失。
生產者消費者模型:
關系:
同步
生產者<—————>消費者
互斥
互斥
生產者<—————>生產者
互斥
消費者<—————>消費者
場所:
緩沖區,下文以鏈表方式實現
1.單個生產者,單個消費者,且生產者和消費者訪問鏈表的順序是LIFO的
代碼實現:
#include<stdio.h> #include<pthread.h> pthread_mutex_t _mutex_lock=PTHREAD_MUTEX_INITIALIZER; pthread_cond_t need_product=PTHREAD_COND_INITIALIZER; typedef struct List List; struct List { int _var; List *_next; }*head=NULL; //head=NULL; void* product(void *arg) { while(1){ pthread_mutex_lock(&_mutex_lock); List* p=(List*)malloc(sizeof(List)); p->_var=(rand()%2000); p->_next=head; head=p; printf("call consumer! product success,val is :%d\n",p->_var); pthread_mutex_unlock(&_mutex_lock); sleep(rand()%3); pthread_cond_signal(&need_product); } } void* consumer(void *arg) { while(1){ pthread_mutex_lock(&_mutex_lock); if(head==NULL){ pthread_cond_wait(&need_product,&_mutex_lock); } List *p=head; head=head->_next; p->_next=NULL; pthread_mutex_unlock(&_mutex_lock); printf("consumer has get protect:%d\n",p->_var); free((void*)p); p=NULL; } } int main() { int err; pthread_t p; pthread_t c; err=pthread_create(&p,NULL,product,NULL); if(err!=0){ printf("%s\n",strerror(err)); } err=pthread_create(&c,NULL,consumer,NULL); if(err!=0){ printf("%s\n",strerror(err)); } void *status; pthread_join(p,&status); printf("%s\n",status); pthread_join(c,&status); printf("%s\n",status); pthread_cond_destroy(&need_product); pthread_mutex_destroy(&_mutex_lock); return 0; }
運行結果:
==================================================================
2.單個生產者,單個消費者,且生產者和消費者訪問鏈表的順序是FIFO的
代碼實現:
fifo_cond.c
#include <stdio.h> #include <pthread.h> #include <stdlib.h> pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER; //pthread_cond_t need_product=PTHREAD_COND_INITIALIZER; pthread_cond_t need_product; typedef int datatype; typedef struct node{ datatype _val; struct node *_next; }node,*node_p,**node_pp; typedef struct list_info { node_p _head; node_p _tail; }list_info,*list_info_p; void init_list(node_pp head,node_pp last) { *head=NULL; *last=*head; } node_p buy_node(datatype data) { node_p p=(node_p)malloc(sizeof(node)); p->_val=data; p->_next=NULL; if(p==NULL){ return NULL; } return p; } int push(node_pp list,node_pp last,datatype data) { node_p p=buy_node(data); if(p==NULL){ return -1; } if(*last==NULL){ *last=p; *list=p; } else{ (*last)->_next=p; (*last)=(*last)->_next; } return data; } node_p destroy_node(node_pp list,node_pp last) { if((*list)!=NULL){ node_p tmp=*list; *list=(*list)->_next; return tmp; } *last=NULL; return NULL; } int pop(node_pp list,node_pp last) { node_p p=destroy_node(list,last); if(p==NULL) return -1; int data=p->_val; free(p); p=NULL; return data; } int show_list(node_p list,node_p last) { while(list!=last){ printf("%d->",list->_val); list=list->_next; } if(last!=NULL) printf("%d\n",last->_val); } void *product(void *arg) { while(1){ datatype data=rand()%100; pthread_mutex_lock(&lock); push(&(((list_info_p)arg)->_head),&(((list_info_p)arg)->_tail),data); printf("Product success,val:%d\n",data); pthread_mutex_unlock(&lock); sleep(2); pthread_cond_signal(&need_product); } } void *consumer(void *arg) { while(1){ int ret=-1; // sleep(4); pthread_mutex_lock(&lock); while(-1==(ret=pop(&(((list_info_p)arg)->_head),&(((list_info_p)arg)->_tail)))){ pthread_cond_wait(&need_product,&lock); } pthread_mutex_unlock(&lock); printf("consumer success,val:%d\n",ret); } } int main() { pthread_cond_init(&need_product,NULL); node_p head,tail; init_list(&head,&tail); list_info _list_info; _list_info._head=head; _list_info._tail=tail; pthread_t tid1,tid2; pthread_create(&tid1,NULL,product,(void*)(&_list_info)); pthread_create(&tid2,NULL,consumer,(void*)(&_list_info)); pthread_join(tid1,NULL); pthread_join(tid2,NULL); pthread_cond_destroy(&need_product); pthread_mutex_destroy(&lock); // int data=0; // while(data<10){ // push(&head,&last,data); // show_list(head,last); // data++; // } // // while(data>0){ // pop(&head,&last); // show_list(head,last); // data--; // } return 0; }
運行結果:
consumer()有sleep(4);
運行結果:
consumer()函數中沒有sleep(4)這條語句
從以上兩次結果可以看出消費者是按找生產產品的順序來消費的,如果生產者生產的慢,消費者會等待
==================================================================
3.多個生產者,多個消費者
實現代碼:
include <stdio.h> #include <pthread.h> #include <stdlib.h> pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER; //pthread_cond_t need_product=PTHREAD_COND_INITIALIZER; pthread_cond_t need_product; typedef int datatype; typedef struct node{ datatype _val; struct node *_next; }node,*node_p,**node_pp; node_p head,tail; typedef struct list_info { node_p _head; node_p _tail; int _flag; }list_info,*list_info_p; void init_list(node_pp head,node_pp last) { *head=NULL; *last=*head; } node_p buy_node(datatype data) { node_p p=(node_p)malloc(sizeof(node)); p->_val=data; p->_next=NULL; if(p==NULL){ return NULL; } return p; } int push(node_pp list,node_pp last,datatype data) { node_p p=buy_node(data); if(p==NULL){ return -1; } if(*last==NULL){ *last=p; *list=p; } else{ (*last)->_next=p; (*last)=(*last)->_next; } return data; } node_p destroy_node(node_pp list,node_pp last) { if((*list)!=NULL){ node_p tmp=*list; *list=(*list)->_next; // if(*list==NULL) //###########error############### // *last==NULL; return tmp; } *last=NULL; return NULL; } int pop(node_pp list,node_pp last) { node_p p=destroy_node(list,last); if(p==NULL) return -1; int data=p->_val; free(p); p=NULL; return data; } int show_list(node_p list,node_p last) { while(list!=last){ printf("%d->",list->_val); list=list->_next; } if(last!=NULL) printf("%d\n",last->_val); } void *product(void *arg) { while(1){ datatype data=rand()%100; pthread_mutex_lock(&lock); push(&head,&tail,data); printf("Product%d put success,val:%d\n",(int)arg,data); pthread_mutex_unlock(&lock); sleep(1); // pthread_cond_signal(&need_product); pthread_cond_broadcast(&need_product); } } void *consumer(void *arg) { while(1){ int ret=-1; sleep(2); pthread_mutex_lock(&lock); while(-1==(ret=pop(&head,&tail))){ pthread_cond_wait(&need_product,&lock); } pthread_mutex_unlock(&lock); sleep(1); printf("consumer%d take success,val:%d\n",(int)arg,ret); } } int main() { init_list(&head,&tail); pthread_t tid1,tid2; pthread_create(&tid1,NULL,product,(void*)1); pthread_create(&tid2,NULL,product,(void*)2); pthread_t tid3,tid4,tid5; pthread_create(&tid3,NULL,consumer,(void*)3); pthread_create(&tid4,NULL,consumer,(void*)4); pthread_create(&tid5,NULL,consumer,(void*)5); pthread_join(tid1,NULL); pthread_join(tid2,NULL); pthread_join(tid3,NULL); pthread_join(tid4,NULL); pthread_join(tid5,NULL); pthread_cond_destroy(&need_product); pthread_mutex_destroy(&lock); return 0; }
運行結果:
以上有2個生產者,3個消費者 生產者生產出的數據放入同一鏈表中,消費者也都從該鏈表取數據,任何一刻對象對改鏈表進行操作時,別的對象都不能對該鏈表進行操作,實現了互斥功能。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。