线程同步和互斥(条件变量控制生产者消费者模型)
条件变量
有关函数:
当向条件变量发送一个信号时,如果没有线程等待在条件变量,那么该信号会丢失。
生产者消费者模型:
关系:
同步
生产者<—————>消费者
互斥
互斥
生产者<—————>生产者
互斥
消费者<—————>消费者
场所:
缓冲区,下文以链表方式实现
1.单个生产者,单个消费者,且生产者和消费者访问链表的顺序是LIFO的
代码实现:
#include<stdio.h>#include<pthread.h>pthread_mutex_t_mutex_lock=PTHREAD_MUTEX_INITIALIZER;pthread_cond_tneed_product=PTHREAD_COND_INITIALIZER;typedefstructListList;structList{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("callconsumer!productsuccess,valis:%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("consumerhasgetprotect:%d\n",p->_var);free((void*)p);p=NULL;}}intmain(){interr;pthread_tp;pthread_tc;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);return0;}
运行结果:
==================================================================
2.单个生产者,单个消费者,且生产者和消费者访问链表的顺序是FIFO的
代码实现:
fifo_cond.c
#include<stdio.h>#include<pthread.h>#include<stdlib.h>pthread_mutex_tlock=PTHREAD_MUTEX_INITIALIZER;//pthread_cond_tneed_product=PTHREAD_COND_INITIALIZER;pthread_cond_tneed_product;typedefintdatatype;typedefstructnode{datatype_val;structnode*_next;}node,*node_p,**node_pp;typedefstructlist_info{node_p_head;node_p_tail;}list_info,*list_info_p;voidinit_list(node_pphead,node_pplast){*head=NULL;*last=*head;}node_pbuy_node(datatypedata){node_pp=(node_p)malloc(sizeof(node));p->_val=data;p->_next=NULL;if(p==NULL){returnNULL;}returnp;}intpush(node_pplist,node_pplast,datatypedata){node_pp=buy_node(data);if(p==NULL){return-1;}if(*last==NULL){*last=p;*list=p;}else{(*last)->_next=p;(*last)=(*last)->_next;}returndata;}node_pdestroy_node(node_pplist,node_pplast){if((*list)!=NULL){node_ptmp=*list;*list=(*list)->_next;returntmp;}*last=NULL;returnNULL;}intpop(node_pplist,node_pplast){node_pp=destroy_node(list,last);if(p==NULL)return-1;intdata=p->_val;free(p);p=NULL;returndata;}intshow_list(node_plist,node_plast){while(list!=last){printf("%d->",list->_val);list=list->_next;}if(last!=NULL)printf("%d\n",last->_val);}void*product(void*arg){while(1){datatypedata=rand()%100;pthread_mutex_lock(&lock);push(&(((list_info_p)arg)->_head),&(((list_info_p)arg)->_tail),data);printf("Productsuccess,val:%d\n",data);pthread_mutex_unlock(&lock);sleep(2);pthread_cond_signal(&need_product);}}void*consumer(void*arg){while(1){intret=-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("consumersuccess,val:%d\n",ret);}}intmain(){pthread_cond_init(&need_product,NULL);node_phead,tail;init_list(&head,&tail);list_info_list_info;_list_info._head=head;_list_info._tail=tail;pthread_ttid1,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);//intdata=0;//while(data<10){//push(&head,&last,data);//show_list(head,last);//data++;//}////while(data>0){//pop(&head,&last);//show_list(head,last);//data--;//}return0;}
运行结果:
consumer()有sleep(4);
运行结果:
consumer()函数中没有sleep(4)这条语句
从以上两次结果可以看出消费者是按找生产产品的顺序来消费的,如果生产者生产的慢,消费者会等待
==================================================================
3.多个生产者,多个消费者
实现代码:
include<stdio.h>#include<pthread.h>#include<stdlib.h>pthread_mutex_tlock=PTHREAD_MUTEX_INITIALIZER;//pthread_cond_tneed_product=PTHREAD_COND_INITIALIZER;pthread_cond_tneed_product;typedefintdatatype;typedefstructnode{datatype_val;structnode*_next;}node,*node_p,**node_pp;node_phead,tail;typedefstructlist_info{node_p_head;node_p_tail;int_flag;}list_info,*list_info_p;voidinit_list(node_pphead,node_pplast){*head=NULL;*last=*head;}node_pbuy_node(datatypedata){node_pp=(node_p)malloc(sizeof(node));p->_val=data;p->_next=NULL;if(p==NULL){returnNULL;}returnp;}intpush(node_pplist,node_pplast,datatypedata){node_pp=buy_node(data);if(p==NULL){return-1;}if(*last==NULL){*last=p;*list=p;}else{(*last)->_next=p;(*last)=(*last)->_next;}returndata;}node_pdestroy_node(node_pplist,node_pplast){if((*list)!=NULL){node_ptmp=*list;*list=(*list)->_next;//if(*list==NULL)//###########error###############//*last==NULL;returntmp;}*last=NULL;returnNULL;}intpop(node_pplist,node_pplast){node_pp=destroy_node(list,last);if(p==NULL)return-1;intdata=p->_val;free(p);p=NULL;returndata;}intshow_list(node_plist,node_plast){while(list!=last){printf("%d->",list->_val);list=list->_next;}if(last!=NULL)printf("%d\n",last->_val);}void*product(void*arg){while(1){datatypedata=rand()%100;pthread_mutex_lock(&lock);push(&head,&tail,data);printf("Product%dputsuccess,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){intret=-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%dtakesuccess,val:%d\n",(int)arg,ret);}}intmain(){init_list(&head,&tail);pthread_ttid1,tid2;pthread_create(&tid1,NULL,product,(void*)1);pthread_create(&tid2,NULL,product,(void*)2);pthread_ttid3,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);return0;}
运行结果:
以上有2个生产者,3个消费者 生产者生产出的数据放入同一链表中,消费者也都从该链表取数据,任何一刻对象对改链表进行操作时,别的对象都不能对该链表进行操作,实现了互斥功能。
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。