std::condition_variable::wait()

std::condition_variable::wait()使用记录:

std::condition_variable::wait()有两个重载函数:

unconditional (1)
void wait (unique_lock<mutex>& lck);
predicate (2)
template <class Predicate>
  void wait (unique_lock<mutex>& lck, Predicate pred);

第一种形式只有一个参数unique_lock<mutex>&,调用wait时,若参数互斥量lck被锁定,则wait会阻塞。

第二种形式除了unique_lock<mutex>&参数外,第二个参数pred,即函数指针。当函数运行到该wait()函数时,若互斥量lck被锁定(?存疑),或者pred()返回值为false,满足两个条件之一,则wait阻塞。其等同于下面的形式:

while (!pred()) wait(lck);

何时激活线程:

对于第一种形式void wait (unique_lock<mutex>& lck);

只要其它线程调用notify_one()或者notify_all()函数,wait()就会结束阻塞。

对于第二种形式,除了需要调用其它线程调用notify_one()或者notify_all()函数外,还需要pred()为true才会解除阻塞。

很显然,先设置pred()为true再调用任一notify函数,wait ( lck, pred)函数是可以结束阻塞的。假如先调用了notify函数,再将pred()置为true,这样wait (lck,  pred)会结束阻塞吗,通过下面的验证,是可以的。

#include <iostream>
#include <chrono>
#include <thread>
#include <condition_variable>
#include <mutex>

std::mutex mutex;
std::condition_variable cond;
bool value = false;

void fun(int a)
{
    int b=0;
    std::unique_lock<std::mutex> lock(mutex);
    while(!value)
    {
        std::cout << "thread wait before\n";
        cond.wait(lock, [](){std::cout << "pred\n"; return value;});
        b=888;
        std::cout << "thread wait after\n";
    }
    std::cout << "thread number = " << a << " value = " << value << " b = " << b << " line = " << __LINE__ << std::endl;
}
 
int main()
{
 
    std::thread th;
    th = std::thread(fun, 999);
 
    std::this_thread::sleep_for(std::chrono::seconds(1));//防止主线程先锁定mutex
    {
        std::unique_lock<std::mutex> lock(mutex);
 
        std::this_thread::sleep_for(std::chrono::seconds(1));
        cond.notify_one();
        std::this_thread::sleep_for(std::chrono::seconds(1));
        std::cout << "after notify_one(), value = " << value <<std::endl;
 
        std::this_thread::sleep_for(std::chrono::seconds(1));
        std::cout << "sleep 1 seconds, value = " << value <<std::endl;
 
        value = true;
        std::cout << "aaa value = " << value <<std::endl;
        std::this_thread::sleep_for(std::chrono::seconds(1));
        std::cout << "bbb value = " << value <<std::endl;
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
    std::cout << "ccc value = " << value <<std::endl;
 
    th.join();
 
    std::this_thread::sleep_for(std::chrono::seconds(60));
    return 0;
}

输出:

thread wait before
after notify_one(), value = 0
sleep 1 seconds, value = 0
thread wait after
thread number = 999 value = 1 b = 888 line = 22

经评论区同学提醒补充:调用notify函数后,wait先去获取锁是否释放,若锁被释放接着去判断pred()是否为true,等pred()为true时则解除阻塞。

  • 4
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值