std::unique_lock与std::lock_guard

std::lock_guard

std::lock_guard是RAII模板类的简单实现,功能简单。

bool try_pop(T& value)
    {
        std::lock_guard lk(mut);
        if(data_queue.empty())
        {
            return false;
        }
        return True;      //析构时自动解锁
    }

std::unique_lock

std::unique_lock为锁管理模板类,是对通用mutex的封装。std::unique_lock对象以独占所有权的方式(unique owership)管理mutex对象的上锁和解锁操作,即在unique_lock对象的声明周期内,它所管理的锁对象会一直保持上锁状态;而unique_lock的生命周期结束之后,它所管理的锁对象会被解锁。unique_lock具有lock_guard的所有功能,而且更为灵活。虽然二者的对象都不能复制,但是unique_lock可以移动(movable),因此用unique_lock管理互斥对象,可以作为函数的返回值,也可以放到STL的容器中。

std::condition_variable 对象通常使用 std::unique_lock 来等待,如果需要使用另外的 lockable 类型,可以使用std::condition_variable_any类.

void get(int id)
{
    std::unique_lock  lk(mtx);

    while (!ready) // 如果标志位不为 true, 则等待...

        cv.wait(lck); // 当前线程被阻塞, 当全局标志位变为 true 之后,线程被唤醒, 继续往下执行

}
void put()

{
    std::unique_lock  lck(mtx);

    ready = true; // 设置全局标志位为 true.

    cv.notify_one(); // 唤醒一个线程.
}

关于notify()和notifyAll()

notify()和notifyAll()都是Object对象用于通知处在等待该对象的线程的方法。
void notify(): 唤醒一个正在等待该对象的线程。
void notifyAll(): 唤醒所有正在等待该对象的线程。
两者的最大区别在于:
notifyAll使所有原来在该对象上等待被notify的线程统统退出wait的状态,变成等待该对象上的锁,一旦该对象被解锁,他们就会去竞争。
notify他只是选择一个wait状态线程进行通知,并使它获得该对象上的锁,但不惊动其他同样在等待被该对象notify的线程们,当第一个线程运行完毕以后释放对象上的锁,此时如果该对象没有再次使用notify语句,即便该对象已经空闲,其他wait状态等待的线程由于没有得到该对象的通知,继续处在wait状态,直到这个对象发出一个notify或notifyAll,它们等待的是被notify或notifyAll,而不是锁。

std::condition_variable.wait

std::condition_variable提供了两种 wait() 函数。当前线程调用 wait() 后将被阻塞(此时当前线程应该获得了锁(mutex),不妨设获得锁 lck),直到另外某个线程调用 notify_* 唤醒了当前线程。

在线程被阻塞时,该函数会自动调用 lck.unlock() 释放锁,使得其他被阻塞在锁竞争上的线程得以继续执行。另外,一旦当前线程获得通知(notified,通常是另外某个线程唤醒了当前线程),wait()函数也是自动调用 lck.lock(),使得lck的状态和 wait 函数被调用时相同。

在第二种情况下(即设置了 Predicate),只有当 pred 条件为false 时调用 wait() 才会阻塞当前线程,并且在收到其他线程的通知后只有当 pred 为 true 时才会被解除阻塞。因此第二种情况类似以下代码:

data_cond.wait(lk, [this]{
            return !data_queue.empty();
        })

自制RAII锁

class MutexLock{
 public:
    explicit MutexLock(Mutex* mu):_mutex(mu){ lock(_mutex) } //构造时自动上锁 explicit:显示调用构造函数
    ~MutexLock(){ unlock(_mutex) }

 private:
    Mutex* _mutex;  //Mutex 为mutex封装类
};

你可能感兴趣的:(std::unique_lock与std::lock_guard)