条件变量不是锁,但是条件变量能够阻塞线程
通常和互斥量一起使用:互斥量用来保护一段共享数据,而条件变量用来引起阻塞
条件变量的俩个动作:
当条件不满足时,阻塞线程
当条件满足,通知阻塞的线程开始工作
主要函数
条件变量的类型:
Pthread_cond_t cond;
初始化一个条件变量--condtion
Pthread_cond_init(
Pthread_cond_t*restrict cond,
Constpthread_condattr_t *restrict attr
);
销毁一个条件变量
Pthread_cond_destroy(pthread_cont_t *cond);
阻塞一个条件变量
Pthread_cond_wait( pthread_cond_t *restrictcond,pthread_mutex_t *restrict mutex);
限时等待一个条件变量
Pthread_cond_timedwait(
Pthread_cond_t*restrict cond,
Pthread_mutex_trestrict mutex,
Conststruct timespec *restrict abstime
);
唤醒至少一个阻塞在条件变量上的线程
Pthread_cond_signal(pthread_cond_t *cond);
唤醒全部阻塞在条件变量上的线程
Pthread_cond_broadcast(pthread_cond_t*cond);
解决生产者和消费者问题
如烧饼问题,生产者在一直的生产烧饼,而消费者不断的消费烧饼,如果烧饼没有了,则消费者会等待生产者生产,生产过后会通知消费者进行消费其中mutex的值的会发生改变
加入消费者开始消费,此时mutex值为1,当pthread_mutex_lock加锁后,mutex值变为0,如果没有烧饼,执行pthread_cond_wait发生阻塞,因为这个函数中也有mutex参数,此时将mutex值变为1,相当于解锁,那么生产者就会加锁成功,开始生产,生产后,pthread_mytex_unlock会使mutex值变为1,执行pthread_cond_signal函数,这个函数会唤醒阻塞在条件变量上的线程,也就是pthread_cond_wait此时解除了阻塞,同时加锁,mutex变为0
用无头节点的链表来实现生产者消费者问题(生产用头插法,消费用头删法)#include <stdio.h> #include <unistd.h> #include <pthread.h> #include <string.h> #include <stdlib.h> //节点结构 typedef struct node { int data; struct node *next; }Node; //永远指向链表头部的指针 Node *head=NULL; //生产者 //线程同步--互斥锁 pthread_mutex_t mutex; //阻塞线程--条件变量类型的变量 pthread_cond_t cond; void *producer(void *sig) { while(1) { //创建一个链表的节点 Node *pnew=(Node *)malloc(sizeof(malloc)); //节点的初始化 pnew->data=rand()%1000; //0-999 //使用互斥锁保护共享数据 pthread_mutex_lock(&mutex); //指针域 pnew->next=head; head=pnew; printf("===== produce:%x,%d\n",(unsigned int)pthread_self(),pnew->data); //解锁 pthread_mutex_unlock(&mutex); //通知阻塞x的消费者线程,解除阻塞 pthread_cond_signal(&cond); sleep(rand()%3); } return NULL; } void *customer(void *arg) { while(1) { //加锁 pthread_mutex_lock(&mutex); if(head==NULL) { //线程阻塞 //该函数会对互斥锁进行解锁 pthread_cond_wait(&cond,&mutex); //解除阻塞后,会对互斥锁做加锁操作 } //链表不为空,删掉一个节点,删除头节点 <当作消费者> Node *pdel=head; head=head->next; printf("-----customer %x ,%d\n",(unsigned int)pthread_self(),pdel->data); free(pdel); //解锁 pthread_mutex_unlock(&mutex); } return NULL; } int main() { //初始化 pthread_mutex_init(&mutex,NULL); pthread_cond_init(&cond,NULL); pthread_t p1,p2; //创建生产者线程 pthread_create(&p1,NULL,producer,NULL); //创建消费者线程 pthread_create(&p2,NULL,customer,NULL); //阻塞回收d子线程 pthread_join(p1,NULL); pthread_join(p2,NULL); //销毁 pthread_mutex_destroy(&mutex); pthread_cond_destroy(&cond); return 0; }
可以看出生产者和消费者之间的一个同步