最近解了一些死锁的bug。问题代码如下:
lock.enter();
//do something with so much code
lock.leave();
然后,“do something”代码块抛出异常,导致锁没有被释放。这里的问题是上面的代码在持有锁的时候做了太多的事情,我们使用锁的原则应该是快进快出。
最初,我的解决方法如下,但我后来发现就算这么实现,如果“do something”抛出异常,锁还是不会被释放。try-catch不一定能捕捉到所有的异常,比如写空指针就不行。
bool lock_in_use = false;
void my_function()
{
bool flag = false;
lock.enter();
if (lock_in_use == false) {
lock_in_use = true;
flag = true;
}
lock.leave();
if (flag) {
//do something
}
else {
return;
}
lock.enter();
if (flag == true)
lock_in_use = false;
lock.leave();
}
所以我觉得可能需要有一个后台线程不断扫描死锁,一旦找到线程持有锁不释放就杀死这个线程,或者发现持有锁的线程已经死了就打log报错,但是这样依然会造成资源的泄露或者无法回收,所以实际上是没有完美解法的。我们所能做的是,多加log,让代码变得容易调试。