(1)条件变量的引出:
各个线程访问共享资源,比如说共享资源是一个空资源,那么,各线程的访问其实都是无效访问,因此需要一个机制,首先阻塞线程,以免其错误访问,待条件满足时(比如 共享资源不为空了),告知各线程开始访问共享资源即,在不满足某种条件下,我希望代码阻塞一会,待满足某种条件后,再让各线程工作,所谓某种条件就是条件变量。
(2)条件变量不是锁!但条件变量能够阻塞线程。
(3)如何实现线程同步 :
与锁配合使用:条件变量(引起阻塞)+ 互斥锁(保护一块共享数据)。
(4)条件变量的两个动作:
条件不满足,阻塞线程;
条件满足,通知阻塞的线程开始工作 。
(5)条件变量的经典模型:生产者和消费者模型
条件变量函数的返回值都是:成功返回 0, 失败直接返回错误号
pthread_cond_t cond; // 定义一个条件变量(condtion)
(1)初始化一个条件变量
函数说明:
int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);
使用:
pthread_cond_init ( & cond, NULL);//参数 2 条件变量的属性,一般传 NULL
(2)阻塞等待一个条件变量
函数说明:
int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
使用:
pthread_cond_t cond // 初始化后的条件变量 pthread_mutex_t mutex; // 初始化后的互斥锁 pthread_cond_wait(&cond, &mutex);
作用:
1)阻塞等待条件变量 cond(参数 1)满足
2.)释放已掌握的互斥锁,相当于 pthread_mutex_unlock(&mutex);
注意:前 2 步是原子操作
3)当被唤醒,pthread_cond_wait 函数返回时,解除阻塞
重新申请获取互斥锁 pthread_mutex_lock(&mutex);
此处的 3 个作用,其实本质是着“生产者消费者模型”的工作流程。如下图所示:
消费者去消费,即访问头结点,因此在访问头结点前,先加互斥锁,发现头结点为空,此时由于条件变量,消费者被阻塞在此(等待生产者生产) 【pthread_cond_wait() 作用 1】,
此时,生产者生产,但遇到了消费者加的互斥锁,按理说无法生产,因此,这里涉及【pthread_cond_wait() 作用 2】,会将消费者已掌握的互斥锁解开,这样就可以生产了,生产后,将互斥锁饥解开,提醒消费者,已解除阻塞,但此时,消费者所加的互斥锁已经解开了,因此,涉及【pthread_cond_wait() 作用 3】,当 pthread_cond_wait()被唤醒后,重新为消费者回复原上锁状态,解除阻塞后,消费者开始消费,当消费结束后,解锁,让其他消费者抢锁。
(3)解除阻塞,唤醒线程
int pthread_cond_signal(pthread_cond_t *cond); //唤醒 至少一个 阻塞在条件变量上的线程
int pthread_cond_broadcast(pthread_cond_t *cond); //唤醒 全部 阻塞在条件变量上的线程
(4)销毁条件变量
int pthread_cond_destroy(pthread_cond_t *cond);