------------锁------------------------------------------------------------------------------------------<mutex>
lock_guard
产生的原因和智能指针差不多,为了解决传统的mutex上锁后,用户忘记解锁导致程序异常阻塞的问题,实现了作用域持续结束后自动解锁的功能;
创建过程:
std::mutex mtx;
std::lock_guard<std::mutex>lg(mtx);//默认构造模式
即刻创建对象lg对mtx进行上锁,在做用户结束后会自动解锁;
缺点:期间无法调用unlock()手动提前解锁;
unique_lock
lock_guard的升级版本,保持原有自动解锁的功能后,解决其缺点,提供手动解锁的功能;
创建过程:
std::mutex mtx;
std::unique_lock<std::mutex> ul (mtx);//默认构造模式,创建+上锁
即可创建对象ul对mtx进行上锁;
改进:unlock方法可以在作用域结束之前提前解锁
----------条件变量-------------------------------------------------------------------------------------<condition_variable>
condition_variable
搭配锁进行使用的一种变量,提供某些功能;
声明:
std::mutex mtx;
std::condition_variable cv;
std::unique_lock<std:: mutex>ul (mtx);
wait()用法:
cv.wait(mtx);
#wait功能,释放当前已获取到的锁mtx,再次尝试获取锁,若获取成功则继续执行,反之阻塞;
#为了控制线程执行的次序
wait_for()用法:
cv.wait_for(mtx, std::chrono::second(20);
#解锁,让别的线程获取到锁,等待20s;
#在20s期间,若别的线程释放锁,并执行notify()通知,该线程会提前唤醒;
#在20s期间,若别的线程释放锁,但没有执行nofify()通知,该线程不会被唤醒,会在20s之后自己尝试上锁,上锁成功则退出等待阻塞状态;
返回值:该变量的返回值是枚举类型:enum class cv_status{ no_timeout; timeout}
#只有在等待结束后,获取到锁的时候,根据当前是否超时,返回是否超时的返回值
warning:等待时间是相对计时而非绝对计时;若等待触发后,系统时间被改变,则等待时间也会被改变
具体介绍在:QNX 修改系统时间对程序的影响 - xinchongyang - Confluence
重载用法:cv.wait_for(mtx, std::chrono::second(20), pre())
#相当于if(!pre()) {cv.wait_for (mtx,std::chrono::second (20));
#即pre的值为false则执行wait_for;
返回值:不强制使用枚举类型,返回bool值:0表示未超时,1表示超时
wait_unitl用法:
cv.wait_until(mtx, now+std::chrono::second(20));
#效果与上述一致,等待到指定时间点
重载用法:也是增加pre()谓词,提供判断后是否执行wait;
|