关于条件变量的理解

一般情况下,如果互斥量保护的对象不呈现多种状态值,那么用互斥量进行保护就足够了。

但是,假如保护的对象呈现多种状态值(即条件),而且某线程不仅仅需要等到该对象并且还要检测该对象当前是某个状态值,该线程才继续向下执行,在这种情况下,该线程就不得不周期性的加锁、判断对象状态值、解锁(不能一直加锁,因为总得给其它线程机会以改变对象状态值),这个动作显然是无谓的浪费资源。

条件变量就是为解决这个问题设计的。

补:

要弄懂条件变量的工作原理,关键在于弄懂pthread_cond_wait()以及典型的用法。

pthread_cond_wait()内部执行步骤是:
(1)unlock the mutex specified by mutex;
(2)block the calling thread until another thread signals the condition variable
cond; 
(3)relock mutex.

典型用法:
pthread_mutex_lock(&lock);
while (条件是否满足) {
    pthread_cond_wait(&cond, &lock);
}
pthread_mutex_unlock(&lock);

用法可以概括为:
A.The thread locks the mutex in preparation for checking the state of the shared
variable.
B.The state of the shared variable is checked.
C.If the shared variable is not in the desired state, then the thread must unlock
the mutex (so that other threads can access the shared variable) before it goes
to sleep on the condition variable.
D.When the thread is reawakened because the condition variable has been sig-
naled, the mutex must once more be locked, since, typically, the thread then
immediately accesses the shared variable.

关键在这句话:sleep on the condition variable,即阻塞在条件变量上,pthread_cond_wait只有阻塞在条件变量上才能够得到信号态通知。

就是说,在使用条件变量时,肯定要首先拿到锁,保证别人不再更改条件值了,然后检查条件,假如条件满足,则终止while,释放锁,继续执行就可以了,假如条件不满足,则我们需要继续等,也就是阻塞住(C),但阻塞住之前还得把锁释放掉(C),要不然别人拿不到锁改不了条件值,然后我们继续等(C),一旦条件变量有信号了(D),则再次锁住(D),然后再一次检查条件是否满足.....

另外,还有个问题,如上述第C步中,假如条件不满足,则我们会再一次调用pthread_cond_wait,那么它首先会释放锁(1),然后阻塞在条件变量上(2)等信号,那么会不会发生这种情况:它刚释放完锁,在阻塞等待信号之前,别人恰好拿到锁并且改了条件值然后置了信号态(pthread_cond_signal),但是由于它现在还没来得及等信号呢,从而造成它拿不到这次的信号。这个问题pthread_cond_wait考虑到了,它在(1)和(2)上使用的是原子操作,保证不会发生这种情况:
In the third step, releasing the mutex and blocking on the condition variable are performed atomically. 
In other words, it is not possible for some other thread to acquire the mutex and signal
the condition variable before the thread calling pthread_cond_wait() has blocked
on the condition variable.


另外,为什么条件变量要附加一个mutex呢,其实这个mutex的意义跟普通mutex一样,它不是保护条件变量本身的,而是保护我们的条件的,我们既然用到了所谓“条件”,那么必然它是在业务逻辑上需要共享保护的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值