目录
pthread_cond_wait实现之中为什么要加锁和解锁
函数原型
int pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex);
pthread_cond_wait:调用其函数有三个步骤
1、对其传入的mutex进行解锁
2、等待pthread_cond_signal的唤醒(阻塞在这里)
3、唤醒后重新对其进行加锁
pthread_cond_wait出现的目的
如果不存在信号量,则生产者和消费者可能是这个样子(图片来自https://blog.csdn.net/shichao1470/article/details/89856443)
apue上这样解释:这就关闭了条件检查和线程进入休眠(休眠一段时间再次进行检查)状态等待这两个操作之间的时间通道,也就是说,条件一旦满足,直接就唤醒了消费者,不需要睡眠那段时间
pthread_cond_wait实现之中为什么要加锁和解锁
解锁:我的理解是,如果有两个线程,A线程是生产者线程,B线程是消费者线程如果B线程先到锁,执行到pthread_cond_wait,如果没有解锁,直接阻塞,那么A线程(生产者)永远也没有机会拿到锁,造成永久堵塞,因为锁一直没B线程(消费者)占用
加锁:我理解就是让线程A(生产者)thread_cond_signal ----->到unlock之间代码可以及时执行,因为只有unlock之后, B线程中pthread_cond_wait 内部才能够加锁成功, 还有一点就是返回前再次锁mutex是为了保证线程从pthread_cond_wait返回后到再次条件判断前不被改变, 就是A拿到锁了,消费过程中其他线程是不允许消费的
代码之中为什么要用while
lock(&mutex);
//一些操作
pthread_cond_signal(&cond);
//一些操作
unlock(&mutex);
上述为生产者代码,现在比如消费者线程有两个,分别为M,N,这两个消费者同时阻塞在pthread_cond_wait上(一个消费者线程pthread_cond_wait解锁后,锁被其他消费者线程拿到,也到了pthread_cond_wait函数),如果消费者pthread_cond_signal了,因为pthread_cond_signal只会唤醒pthread_cond_wait上的线程,那么M,N同时被唤醒,M先拿到锁,消费了,刚消费完解锁后,N线程后拿到了锁,此时没有什么可消费的了,条件不满足了,只能用while,重新等待,这也就是所谓的 惊群效应
https://blog.csdn.net/lyztyycode/article/details/78648798 (惊群效应比较好的文章)
代码还有一种写法是
lock(&mutex);
//一些操作
unlock(&mutex);
//一些操作
pthread_cond_signal(&cond);
这种写法在执行完unlock之后,还没来的及执行pthread_cond_signal,可能有一些空闲的线程直接消费了,那么之后唤醒的线程也不满足了,所以也要用while
参考博客:https://blog.csdn.net/shichao1470/article/details/89856443