std::unique_lock 支持的特性之一就是递归锁定机制,也称可重入锁。这允许使用同一个线程在不解除锁定情况下多次锁定互斥锁。
在递归锁定期间,线程可以继续尝试重新获取同个互斥锁。如果在这种情况下,通过 std::unique_lock 在第一次请求时已经锁定了该互斥锁,则该锁只会增加其内部计数器,以记住要释放几次互斥锁。
递归锁的基本语法如下:
#include <mutex>
void func(std::mutex& m)
{
std::unique_lock<std::mutex> lk(m);
/* do some work */
func(m); // 递归调用(或调用其他函数)并再次锁定互斥量
}
在上面的代码中,func 函数使用 std::unique_lock 锁定了一个互斥量,然后执行一些工作,最重要的是该函数通过递归调用来再次锁定互斥量。
当 func 函数再次被调用时,它将尝试重复锁定互斥量。但由于该互斥量已经被锁定,因此只会将其内部状态计数器值增加 1(即使是在另一个线程中)。然后它会执行该函数的其他操作。再次调用其他操作将重复并递归锁定互斥锁。
在递归锁定情况下,需要注意锁的释放次数。每个 std::lock() 或 unlock() 的调用都必须与之前的调用相同数量,以确保在相应数量的锁定和解锁操作之后,因此才能准确的解除所有的锁定。
需要注意的是,在使用递归锁时要小心,因为过多的循环可能导致程序死锁、性能抖动等问题。因此,只有在充分理解可重入锁概念和隐式锁机制的前提下,才能安全地使用递归锁定机制来编写多线程代码。