cv.wait() 函数在等待条件变量时会自动释放互斥量的锁
斥锁(std::mutex)的所有权是排他的,也就是说,在任意时刻只能有一个线程拥有互斥锁的所有权。一旦一个线程获得了互斥锁的所有权,其他线程必须等待该线程释放互斥锁后才能获得所有权。在同一时刻,只能有一个线程拥有互斥锁的所有权,这是互斥锁的基本特性之一,用于确保在同一时间内只有一个线程可以访问共享资源,从而防止数据竞争和并发访问问题。因此,两个线程不能同时拥有互斥锁的所有权。如果一个线程已经获得了互斥锁的所有权,那么其他线程必须等待该线程释放锁后才能获取。
std::unique_lock
和 std::lock_guard
都是 C++ 标准库提供的用于管理互斥量的 RAII 封装类,它们的主要区别在于灵活性和功能上的不同:
所有权和灵活性:
std::lock_guard
:它是一个简单的 RAII 封装类,用于在构造时锁定互斥量,在析构时解锁互斥量。一旦被构造,std::lock_guard
对象就会拥有互斥量的所有权,直到其析构为止。因此,std::lock_guard
对象的生命周期与其锁定的互斥量的范围一致。std::unique_lock
:它比 std::lock_guard
更加灵活,可以在任意时刻手动锁定和解锁互斥量,而不受构造和析构函数的限制。这意味着你可以在 std::unique_lock
对象的生命周期内多次锁定和解锁互斥量,也可以选择延迟锁定或手动解锁互斥量。延迟锁定和条件变量:
std::unique_lock
支持延迟锁定(deferred locking)和条件变量(condition variables)。延迟锁定意味着可以在构造时不立即锁定互斥量,而是在后续某个时刻手动调用 lock
函数来锁定互斥量。条件变量是一种用于线程间通信的机制,通常与 std::unique_lock
一起使用。因此,总的来说,std::unique_lock
更加灵活,适用于需要更多控制权和功能的场景,而 std::lock_guard
则更加简单,适用于简单的互斥量保护场景。