STL标准库之条件变量(condition_variable)

       std::condition_variable定义在头文件<condition_variable>。其用于进行线程间同步,可以阻塞一个或多个线程,直到一个线程修改了共享变量,并通知其它condition_variable唤醒其他线程。

      阻塞当前线程方法:

        注意:线程的阻塞需要结合锁来实现,通常使用std::unique_lock<std::mutex>,因为std::unique_lock可以灵活的进行lock和unlock。在进行wait阻塞操作时wait会把锁unlock掉然后自己睡眠,当被唤醒时,再把锁lock住执行之后操作。线程在阻塞的时会由于系统的不确定性造成伪唤醒(非调用notify_one/notify_all造成的唤醒),可以通过向三种阻塞方式的Predicate参数传递一个函数,当其返回false时就继续阻塞,返回true时则表示被真正唤醒。(采用lambda表达式最简单[](return ready;))。

        阻塞当前线程有三种方式:

        1. wait()方式一直阻塞直到其它线程对其唤醒,再继续执行;

        2. wait_for方式是阻塞设置的一段时间,当超时时便会唤醒当前线程继续执行,或者被其它线程唤醒;

        3. wait_until方式是阻塞到指定的某个时刻,当到达设定时刻或者被其它线程唤醒,则当前线程继续执行。

       函数原型如下代码所示:

//wait():阻塞当前线程,直到条件变量被唤醒,唤醒后当前线程继续向下运行。
void wait(unique_lock<mutex>& _Lck);
template<class _Predicate> void wait(
                     unique_lock<mutex>&_Lck,
                    _Predicate _Pred);

//wait_for():阻塞当前线程,直到条件变量被唤醒,或到达指定时间长度,唤醒后或时间到达后当前线程继续向下运行。
template<class _Rep,class _Preiod > _Cv_status wait_for(
                    unique_lock<mutex>& _Lck,
                    const chrono::duration<_Rep,_Period>&_Rel_time);
template<class _Rep,class _Preiod ,class _Predicate>bool wait_for(
                    unique_lock<mutex>& _Lck,
                    const chrono::duration<_Rep,_Period>&_Rel_time,
                    _Predicate _Pred);

//wait_until():阻塞当前线程,直到条件变量被唤醒,或到达指定时间点,唤醒后或到达指定时间点后当前线程继续向下运行。
template<class _Clock,class _Duration>_Cv_status wait_until(
                    unique_lock<mutex>& _Lck,
                    const chrono::time_point<_Clock,_Duration>& _Abs_time);
template<class _Clock,class _Duration ,class _Predicate>bool wait_until(
                    unique_lock<mutex>& _Lck,
                    const chrono::time_point<_Clock,_Duration>&_Rel_time,
                    _Predicate _Pred);
_Cv_status wait_until(unique_lock<mutex>& _Lck,const xtime *_Abs_time);
template<class _Predicate>bool wait_until(
                    unique_lock<mutex>& _Lck,
                    const xtime *_Abs_time,
                    _Predicate _Pred>;

      唤醒等待线程方法:

//notify_one():通知一个等待的线程,将其唤醒继续执行。
void notify_one()noexcept;
//notify_all():通知所有等待线程,并将其唤醒继续执行。
void notify_all()noexcept;

      wait方法的使用方式:

void thread_wait()
{
    std::cout<<"thread wait start."<<std::endl;
    std::unique_lock<std::mutex> lk(g_mutex);
    std::cout<<"thread wait  waiting."<<std::endl;
    g_cv_test. wait(lk,[](){return g_btest;});
    std::cout<<"thread wait continue."<<std::endl;
}
void thread_notify_one()
{
    std::cout<<"thread notify one start."<<std::endl;
    std::this_thread::sleep_for(std::chrono::seconds(5));
    std::cout<<"thread notify one notify wait thread continue."<<std::endl;
    std::unique<std::mutex>lk(g_mutex);
    g_btest=true;
    g_cv_test.notify_one();
}
void main_test_wait()
{
    std::thread trd_cvtest_wait(thread_wait);
    std::thread trd_cvtest_notifyone(thread_notify_one);
    trd_cvtest_wait.join();
    trd_cvtest_notifyone.join();
}

结果:
       thread_wait线程先执行,打印thread wait start.然后线程thread_notify_one执行打印thread notify one start. 接着线程thread_wait打印thread wait waiting.后调用wait()方法进入阻塞状态等待被唤醒;线程thread_notify_one等待5s后打印thread notify one notify wait thread continue.接着调用notify_one()方法唤醒阻塞线程。

thread wait start. 
thread notify one start. 
thread wait waiting. 
thread notify one notify wait thread continue. 
thread wait continue. 

      wait_for方法的使用方式:

void thread_wait_for()
{
    std::cout<<"condition variable wait_for function test."<<std::endl;
    std::unique<std::mutex>lk(g_mutex);
    while(!g_cv_test.wait_for(lk,std::chrono::seconds(5)),[](){return g_btest;})
    {
        std::cout<<"wait_for thread waiting……"<<std::endl;
    }
    std::cout<<"wait_for continue."<<std::endl;
}

void main_test_wait_for()
{
    std::thread trd_wait_for(thread_wait_for);
    std::thread trd_cvtest_notifyone(thread_notify_one);
    trd_wait_for. join();
    trd_cvtest_notifyone. join();
}

结果:

     修改thread_notify_one线程的等待时间为15s。thread_wait_for线程先执行打印condition variable wait_for function test. 然后线程thread_notify_one线程启动打印thread notify one start. 线程thread_wait_for每5s会出现阻塞超时,然后进入循环体打印wait_for thread waiting……,当打印两边后,在阻塞十五秒时被thread_notify_one线程唤醒并继续执行。

condition variable wait_for function test. 
thread notify one start. 
wait_for thread waiting……
wait_for thread waiting……
thread notify one notify wait thread continue. 
wait_for continue. 

      wait_until方法使用方式:

void thread_wait_until()
{
    std::cout<<"condition variable wait_until function test."<<std::endl;
    std::unique<std::mutex>lk(g_mutex);
    auto now_time = std::chrono::system_clock::now();
    std::time_t ntime = std::chrono::system_clock::to_time_t(now_time);
    std::cout<<"current time:"<<std::put_time(std::localtime(&ntime),"%F %T")<<std::endl;
    g_cv_test.wait_until(lk,now_time+std::chrono::seconds(10),[](){return g_btest;});

    now_time = std::chrono::system_clock::now();
    ntime = std::chrono::system_clock::to_time_t(now_time);
    std::cout<<"wait_until continue."<<std::endl;
    std::cout<<"current time:"<<std::put_time(std::localtime(&ntime),"%F %T")<<std::endl;
}
void main_test_wait_until()
{
    std::thread trd_wait_until(thread_wait_until);
    std::thread trd_cvtest_notifyone(thread_notify_one);
    trd_wait_until. join();
    trd_cvtest_notifyone. join();
}

  结果:

          thread_wait_until线程先执行并打印condition variable wait_until function test.然后thread_notify_one线程启动并打印thread notify one start. 接着线程thread_wait_until线程打印当前时间。

情况一:wait_until中设置的阻塞时间在唤醒时间之,则先打印wait_until continue.然后打印结束时间。

情况二:wait_until中设置的阻塞时间在唤醒时间之后,则打印如下显示结果。

condition variable wait_until function test. 
thread notify one start. 
current time : xxxx-xx-xx xx:xx:xx
thread notify one notify wait thread continue. 
wait_until continue.
current time: xxxx-xx-xx xx:xx::xx

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++ STL标准模板)是C++标准的一部分,提供了一组通用的数据结构和算法。STL标准中文文档涵盖了STL的各个部分,包括容器(container)、迭代器(iterator)、算法(algorithm)等。 STL中文文档可以帮助开发者更好地理解和使用STL,具体内容包括: 1. 容器:STL提供了多种容器类型,如vector、list、map等,这些容器提供了不同的数据存储和操作方式。文档会介绍每种容器的特点、用法和示例代码。 2. 迭代器:迭代器是与容器配合使用的一种机制,通过迭代器可以访问和遍历容器中的元素。文档会介绍迭代器的种类、使用方法以及常见操作。 3. 算法:STL提供了众多的算法,如排序、查找、复制等,可以在不同的容器上进行操作。文档会详细介绍每个算法的功能、参数和使用示例。 4. 函数对象:STL提供了函数对象机制,可以将函数或函数对象作为算法的参数,用于执行特定的操作。文档会介绍函数对象的定义和使用方式。 STL标准中文文档的作用主要有两个方面:一是帮助新手学习和理解STL的使用方法,提供了丰富的示例和解释;二是方便开发者在实际项目中使用STL,对于算法和容器的选择和使用提供了参考和指导。 总之,STL标准中文文档是一份重要的资料,对于学习和使用C++的开发者来说都具有很大的价值。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值