条件变量与互斥锁
1.std::lock_guard类的构造函数禁用拷贝构造,且禁用移动构造。std::lock_guard类除了构造函数和析构函数外没有其它成员函数。
在std::lock_guard对象构造时,传入的mutex对象(即它所管理的mutex对象)会被当前线程锁住。在lock_guard对象被析构时,它所管理的mutex对象会自动解锁,不需要程序员手动调用lock和unlock对mutex进行上锁和解锁操作。lock_guard对象并不负责管理mutex对象的生命周期,lock_guard对象只是简化了mutex对象的上锁和解锁操作,方便线程对互斥量上锁,即在某个lock_guard对象的生命周期内,它所管理的锁对象会一直保持上锁状态;而lock_guard的生命周期结束之后,它所管理的锁对象会被解锁。程序员可以非常方便地使用lock_guard,而不用担心异常安全问题。
2.std::unique_lock为锁管理模板类,是对通用mutex的封装。std::unique_lock对象以独占所有权的方式(unique owership)管理mutex对象的上锁和解锁操作,即在unique_lock对象的声明周期内,它所管理的锁对象会一直保持上锁状态;而unique_lock的生命周期结束之后,它所管理的锁对象会被解锁。unique_lock具有lock_guard的所有功能,而且更为灵活。虽然二者的对象都不能复制,但是unique_lock可以移动(movable),因此用unique_lock管理互斥对象,可以作为函数的返回值,也可以放到STL的容器中。
两种初始化方式
<1>需要手动加锁
<2>初始化即加锁
3.条件变量的使用
https://blog.csdn.net/c_base_jin/article/details/89741247
m_cvStartProcRec.wait(cvStartProcRecMutexLock, [this] { return m_eStartProcRecorded; });
cvStartProcRecMutexLock:互斥锁
[this]:线程
return m_eStartProcRecorded:条件变量满足的条件
因为互斥量是一种锁,只有两种状态,加锁和未加锁,一旦某个共享资源区被加锁之后,另一个线程想要访问该资源区,如果没有条件变量的辅助,那么它就不得不频繁的去尝试申请访问,这回形成一种自旋锁的状态,他会占用 cpu 的资源。然而有了条件变量之后,条件变量会让另外的线程休眠等待,直到资源区被解锁之后直接通知另外的线程,这就节省了CPU的资源,条件变量的优势也更好的弥补了互斥锁的不足。
信号量和互斥锁也能实现线程同步,为什么通常使用条件变量?
最大区别,信号量不能一次性唤醒所有等待线程,而条件变量可以一次性的唤醒。
互斥锁使用案例