近日在调试一个线程挂起的BUG,究其原因是该用递归锁的地方使用了普通的互斥锁,导致了死锁。
趁着这个机会也好好了解了一下很少用到的递归锁。
所谓递归锁,就是在同一线程上该锁是可重入的,对于不同线程则相当于普通的互斥锁。
例如:有互斥量LOCK
func A () {
LOCK.lock();
B();
LOCK.unlock();
}
func B() {
LOCK.lock();
LOCK.unlock();
}
则在同一线程上函数A是不会形成死锁的,但此时如果其他线程想要加锁,只有等待拥有锁的线程释放所有的锁。(加锁几次要释放几次)
递归锁与条件变量在一起使用的时候要特别小心,若线程A加了递归锁没有完全释放就进入了条件变量,等待唤醒。则线程B试图唤醒A时,由于A的递归锁没有完全释放,所以会导致死锁。
递归锁在JAVA中仅仅用一个关键字synchronized就能实现,而且该关键字可以选择锁的对象。
在C/C++中(linux下)就需要使用pthread库中提供的互斥锁,并且设置锁的属性为递归锁:
pthread_mutex_t Mutex;
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&Mutex, &attr);