1.简介
条件变量是一种线程同步机制,其核心作用是允许线程在特定条件未满足时进入休眠状态, 并在条件满足时被其他线程唤醒继续执行,通过“等待-通知”模式实现线程间的协调, 避免了忙等待(即不断轮询检查条件)带来的资源浪费,从而提高程序效率。 基于linux环境下或者windows的mingw环境(posix接口)。
2.条件变量时间轴分析
我们主要分析pthread_cond_wait()的使用
2.1 消费者线程示例
先以示例代码进行展示,使用方式
pthread_mutex_lock(&mutex); // [1] 消费者加锁成功
while (queue_empty) {
printf("准备进入wait...当前锁状态: 已锁定\n");
pthread_cond_wait(&cond, &mutex); // [2] 这个函数内部:
// - 先解锁mutex
// - 然后线程挂起等待
// - 等待期间mutex是解锁状态!
// - 被唤醒后,在返回前重新加锁
printf("从wait返回...当前锁状态: 已重新锁定\n");
}
// 消费数据...
pthread_mutex_unlock(&mutex); // [3] 消费者解锁
2.2 条件变量等待过程的时间线
pthread_cond_wait的时间流程,以及这个过程中,锁的状态。
//-----------------------------------时间线------------------
时间点 | 消费者线程 |消费者的锁状态 | 生产者线程
t1 pthread_mutex_lock() 锁定 可能被阻塞在pthread_mutex_lock()
t2 进入while(queue_empty) 锁定 同上
t3 调用pthread_cond_wait() 锁定->解锁
t4 --第一步,解锁 解锁
t5 --第二步,线程等待挂起 解锁
t6 解锁 pthread_mutex_lock()---成功,可以进行生成操作
t7 解锁 生产者,修改,正常生成,queue_empty=false
t8 解锁 生成完成,调用pthread_cond_signal() ,唤醒消费者
t9 消费者被唤醒 解锁
t10 pthread_cond_wait()内部 解锁->锁定
t11 --重新加锁 锁定 pthread_mutex_unlock(),生产者解锁
t12 pthread_cond_wait()返回 锁定
t13 消费数据。。。。 锁定
t14 pthread_mutex_unlock() 解锁
2.3 条件变量通知
上面讲的是条件变量pthread_cond_wait里面的锁的状态,现在在说条件变量的通知机制 pthread_cond_signal、pthread_cond_boardcast不同的系统上有不同的实现, 底层上pthread_cond_wait机制中,线程被加入到等待队列,然后进入内核态的等待状态,在 Linux 内核中, 实际的唤醒是通过 futex(Fast Userspace muTEX)系统调用。
- pthread_cond_signal
- 从等待队列中选择一个线程(通常是 FIFO)
- 通过 futex 系统调用唤醒该线程
- 只进行一次唤醒操作
- pthread_cond_broadcast
- 遍历整个等待队列
- 唤醒所有等待线程(或使用 INT_MAX 参数)
- 清空等待队列
您还没有登录,请您登录后发表评论。