【Linux】Linux 条件变量 为什么要配合互斥锁

官方:

A condition variable must always be associated with a mutex,  to  avoid
       the race condition where a thread prepares to wait on a condition vari‐
       able and another thread signals the condition  just  before  the  first
       thread actually waits on it.

条件变量必须始终与互斥锁配合,以避免竞争状态:其中线程准备等待一个条件,另一个线程刚好在第一个线程 真正等待 之前发出条件信号。

网友:

pthread_cond_wait总和一个互斥锁结合使用。在调用pthread_cond_wait前要先获取锁。pthread_cond_wait函数执行时先自动释放指定的锁,然后等待条件变量的变化。

 来看一个例子(你是否能理解呢?):

In Thread1:

pthread_mutex_lock(&m_mutex);   
pthread_cond_wait(&m_cond,&m_mutex);   
pthread_mutex_unlock(&m_mutex);  

 

In Thread2:

pthread_mutex_lock(&m_mutex);   
pthread_cond_signal(&m_cond);   
pthread_mutex_unlock(&m_mutex);  

 


为什么要与pthread_mutex 一起使用呢? 这是为了应对 线程1在调用pthread_cond_wait()但线程1还没有进入wait cond的状态的时候,此时线程2调用了 cond_singal 的情况。 如果不用mutex锁的话,这个cond_singal就丢失了。

加了锁的情况是,线程2必须等到 mutex 被释放(也就是 pthread_cod_wait() 释放锁并进入wait_cond状态 ,此时线程2上锁) 的时候才能调用cond_singal.

http://blog.chinaunix.net/uid-27164517-id-3282242.html

我的理解:

为了将条件判断和wait变成一个原子操作。

void function_2() {
    int data = 0;
    while ( data != 1) {
        std::unique_lock<std::mutex> locker(mu);
        while(q.empty())
            cond.wait(locker); // Unlock mu and wait to be notified
        data = q.back();
        q.pop_back();
        locker.unlock();
        std::cout << "t2 got a value from t1: " << data << std::endl;
    }
}
 while(q.empty())
      cond.wait(locker); // Unlock mu and wait to be notified

如果不加锁,在线程2判断q.empty()后(如果为true),然后跳过这一步准备下一步cond.wait, 如果此时线程1修改q,然后发出notify,结果因为线程2还没进入cond.wait,这个notify就被线程2给错过了,然后线程2完成进入cond.wait,只能等下一个notify了,如果没有下一个notify或者下一个notify依赖于线程2,那就一直卡在那里。

而如果加了锁,那判断q.empty()和cond.wait就变成一个原子操作,线程2在完成cond.wait之前,线程1是改不了q的。

 

参考:https://blog.csdn.net/zrf2112/article/details/52287915

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值