本文重点:理解条件变量和生产者消费者模型
同步是在保证数据安全的情况下,让我们的线程访问资源具有一定的顺序性
条件变量cond
当一个线程互斥地访问某个变量时,它可能发现在其它线程改变状态之前,它什么也做不了,就是申请锁失败了,它就要添加到一个队列中等待,这个队列叫做等待队列,把这个等待队列可以叫做条件变量,也就是说申请锁失败,进行等待是在条件变量下等的,这样它们排好队,就有顺序性。
条件变量依赖于锁的实现
那我怎么知道几时要在条件变量下等呢?
一定是临界资源不就绪,没错,临界资源也是有状态的!!
你怎么知道临界资源是就绪还是不就绪的?
你判断出来的!判断是访问临界资源吗?必须是的,也就是判断必须在加锁之后!!
条件变量接口
初始化接口和锁是一样的
pthread_cond_t: 系统提供的类型
cond:要初始化的条件变量
attr:条件变量的属性,设为nullptrpthread_cond_t cond = PTHREAD_COND_INITIALIZER;
全局的条件变量,自动初始化和销毁
等待条件满足
cond:要在这个条件变量上等待
mutex:锁,后面详细解释
唤醒等待
signal是唤醒一个线程,broadcast是唤醒条件变量下的全部线程
下面通过代码来理解上面的问题
注意函数接口的位置,想想为什么函数是在这?
#include<iostream>
#include<unistd.h>
#include<pthread.h>
using namespace std;
int cnt=0;
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond=PTHREAD_COND_INITIALIZER;
void* Count(void* args)
{
pthread_detach(pthread_self());//分离线程
uint64_t number=(uint64_t)args;
cout<<"pthread: "<<number<<",create success"<<endl;
while(1)
{
pthread_mutex_lock(&mutex);
// 我们怎么知道我们要让一个线程去休眠了那?一定是临界资源不就绪,没错,临界资源也是有状态的!!
// 你怎么知道临界资源是就绪还是不就绪的?你判断出来的!判断是访问临界资源吗?必须是的,也就是判断必须在加锁之后!!!
pthread_cond_wait(&cond,&mutex);
//为什么这个函数在这里?因为临界资源不就绪,就要等待
//为什么还要一个锁的参数?因为这个线程在前面的时候申请了锁,此时线程持有锁
//1.pthread_cond_wait让线程等待的时候,会自动释放锁!2.唤醒而返回的时候,重新持有锁
cout<<"pthread: "<<number<<