条件变量(condition variable)
线程间的同步与互斥技术,主要以互斥锁和条件变量为主,条件变量和互斥所的配合使用可以很好的处理对于条件等待的线程间的同步问题。举个例子:消费者和生产者问题。
消费者与生产者最基本的关系是服务与被服务的关系,但是在线程同步与互斥中强调的是两者访问资源的关系。首先生产与消费的关系为:同步与互斥,生产与生产的关系为:互斥,消费与消费的关系为:互斥。所以维护这三种关系的有两类人:生产者与消费者。并且生产数据与消费数据必须有场所。
所以将其简述为三种关系两类人一个场所(当然这里的场所并不是只能有一个,可以是多样的)。
介绍条件变量的几个函数:
1.定义一个条件变量
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
2.初始化条件变量(当定义没初始化时)
int pthread_cond_init(pthread_cond_t *restrict cond,
const pthread_condattr_t *restrict attr);
3.销毁条件变量
int pthread_cond_destroy(pthread_cond_t *cond)
举一个单个消费者与单个生产者问题:
1 #include<stdio.h> 2 #include<pthread.h> 3 #include<assert.h> 4 #include<stdlib.h> 5 pthread_cond_t cond; 6 typedef int data_type; 7 pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER; 8 void push_node(data_type data); 9 int pop_node(); 10 void* producter(void* arg) 11 { 12 data_type i=0; 13 while(1) 14 { 15 pthread_mutex_lock(&lock); 16 i++; 17 push_node(i); 18 sleep(2); 19 pthread_mutex_unlock(&lock); 20 printf("product done......\n"); 21 sleep(2); 22 pthread_cond_signal(&cond); 23 sleep(2); 25 } 26 27 } 28 void *consumer(void* arg) 29 { 30 data_type res=-1; 31 while(1) 32 { 33 pthread_mutex_lock(&lock); 34 while(-1==pop_node(&res)) 35 { 36 pthread_cond_wait(&cond,&lock); 37 } 38 res=pop_node(&res); 39 printf("consumer data: %d\n",res); 40 sleep(2); 41 pthread_mutex_unlock(&lock); 44 pthread_cond_signal(&cond); 45 sleep(2); 46 47 } 48 49 } 50 51 typedef struct _node 52 { 53 data_type _data; 54 struct _node* _next; 55 }node, *node_p,**node_pp; 56 57 node_p head=NULL; 58 static node_p buy_node(data_type data) 59 { 60 node_p tmp=malloc(sizeof(node)); 61 if(tmp==NULL) 62 { 63 printf("malloc failed\n"); 64 65 } 66 tmp->_data=data; 67 tmp->_next=NULL; 68 return tmp; 69 } 71 void init_list(node_pp phead) 72 { 73 *phead=buy_node(0); 74 } 75 76 void push_node(data_type data) 77 { 78 79 if(head->_next==NULL) 80 head->_next=buy_node(data); 81 else{ 82 node_p tmp=buy_node(data); 83 tmp->_next=head->_next; 84 head->_next=tmp; 85 } 86 } 87 88 89 int pop_node(data_type *data) 90 { data_type ret=0; 91 92 if(head->_next==NULL) 93 return *data; else{ 95 node_p tmp=head->_next; 96 head->_next=tmp->_next; 97 *data=tmp->_data; 98 free(tmp); 99 } 100 return *data; 101 } 102 int main() 103 { 104 105 init_list(&head); 106 pthread_cond_init(&cond,NULL); 107 pthread_mutex_init(&lock,NULL); 108 pthread_t tid1,tid2; 109 pthread_create(&tid1,NULL,producter,NULL); 110 pthread_create(&tid2,NULL,consumer,NULL); 111 pthread_join(tid1,NULL); 112 pthread_join(tid2,NULL); 113 pthread_cond_destroy(&cond); 114 pthread_mutex_destroy(&lock); 115 return 0; }
运行结果:
结果分析:
生产者生产出一个数据之后消费者才能消费,当链表里没有数据时,消费者就等待对应的条件变量和锁,直到他们被释放消费者才能进去消费。
扩展:多消费者与多生产者问题
10 pthread_mutex_t plock=PTHREAD_MUTEX_INITIALIZER; 11 pthread_mutex_t conlock=PTHREAD_MUTEX_INITIALIZER; 12 void push_node(data_type data); 13 int pop_node(); 14 void* producter(void* arg) 15 { 16 data_type i=0; 17 while(1) 18 { sem_wait(&sem_product); 19 pthread_mutex_lock(&plock); 20 i++; 21 push_node(i); 22 sleep(2); 23 pthread_mutex_unlock(&plock); 24 sem_post(&sem_consume); 25 printf("product done......\n"); 26 sleep(2); 27 pthread_cond_signal(&cond); 28 sleep(2); 29 30 } 31 32 } 33 void *consumer(void* arg) 34 { 35 data_type res=-1; 36 while(1) 37 { 38 sem_wait(&sem_consume); 39 pthread_mutex_lock(&conlock); 40 while(-1==pop_node(&res)) 41 { 42 pthread_cond_wait(&cond,&plock); 43 } 44 res=pop_node(&res); 45 printf("consumer data: %d\n",res); 46 sleep(2); 47 pthread_mutex_unlock(&conlock); 48 49 sem_post(&sem_product); 50 51 pthread_cond_signal(&cond); 52 53 sleep(2); 54 55 }
时间: 2024-11-09 13:27:18