admin管理员组文章数量:1599904
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
本文标签: 变量条件标准stlconditionvariable
版权声明:本文标题:STL标准库之条件变量(condition_variable) 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/dianzi/1728322849a1154052.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论