std::condition_variable在std::thread中的应用

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

      阻塞当前线程方法:

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

        阻塞当前线程有三种方式wait方式一直阻塞直到其它线程对其唤醒,再继续执行;wait_for方式是阻塞设置的一段时间,当超时时便会唤醒当前线程继续执行,或者被其它线程唤醒;wait_until方式是组射到某个时刻,当到达设定时刻或者被其它线程唤醒,则当前线程继续执行。

wait():阻塞当前线程,直到条件变量被唤醒,唤醒后当前线程继续向下运行。
    void wait(unique_lock& _Lck);
    template void wait(unique_lock&_Lck,_Predicate _Pred);
wait_for():阻塞当前线程,直到条件变量被唤醒,或到达指定时间长度,唤醒后或时间到达后当前线程继续向下运行。
    template _Cv_status wait_for(unique_lock& _Lck,const chrono::duration<_Rep,_Period>&_Rel_time);
    templatebool wait_for(unique_lock& _Lck,const chrono::duration<_Rep,_Period>&_Rel_time,_Predicate _Pred);
wait_until():阻塞当前线程,直到条件变量被唤醒,或到达指定时间点,唤醒后或到达指定时间点后当前线程继续向下运行。
    template_Cv_status wait_until(unique_lock& _Lck,const chrono::time_point<_Clock,_Duration>& _Abs_time);
    templatebool wait_until(unique_lock& _Lck,const chrono::time_point<_Clock,_Duration>&_Rel_time,_Predicate _Pred);
_Cv_status wait_until(unique_lock& _Lck,const xtime *_Abs_time);
    templatebool wait_until(unique_lock& _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."< lk(g_mutex);
    std::cout<<"thread wait  waiting."<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."<lk(g_mutex);
    while(!g_cv_test.wait_for(lk,std::chrono::seconds(5)),[](){return g_btest;})
    {
        std::cout<<"wait_for thread waiting……"<

结果:

     修改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."<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:"<

  结果:

          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

 

你可能感兴趣的:(C++,c++11)