Friday, February 25, 2011

关于多线程死锁

从CSDN上面看来的讨论,很有启发性:
---
A_lock()
B_lock()
do_something()
A_unlock()
B_unlock()

是否能产生死锁,
死锁的条件是什么?

#1 by zhangjingyuhua

这样看不出来。
但是考虑下面这种情况:

void f1()
{
    A_lock();
    do_something(); #P1
    A_unlock();
}

void f2()
{
    B_lock();
    f1(); #P2
    B_unlock();
}

void do_something()
{
    B_lock();
    B_unlock();
}

例如两个线程,线程A调用f1,线程B调用f2。如果线程A执行到P1位置,线程B执行到P2位置。那么就死锁了。

A进入do_something且A获得了A_lock,里面有B_lock(),但是线程B已经获得了B_lock,而线程B这时却在等待f1中的A_lock。
这样就死锁了。
 
#2 by Jinhao
 
别跑题,是在一个函数中。

func()
{
    lock(A)
    lock(b)
    do something()
    unlock(b)
    unlock(A)
}

加锁顺序是:A->b
解锁顺序是:b->A

把题看清再说话。
 
#3 by zhangjingyuhua
 
麻烦你看清楚。已经说了,看不出来。
我写那段代码是回答你“死锁的条件是什么”这个问题。这与是不是在一个函数中无关。明白不?

如果你懂了,那你还跑到这里来问什么?

func()
{
    lock(A)
    lock(b)
    do something()
    unlock(b)
    unlock(A)
}

你觉得这个没问题?光看这个有什么用?

如果存在另一个函数:

func2()
{
    lock(B)
    lock(A)
    do something()
    unlock(A)
    unlock(B)
}

那你认为你的func有没有问题?
 
#4 by Jinhao
 
我在用别人的时,别人不应该在等我。
满足这一条就不会死了。

A_lock()
B_lock()
do_something()
A_unlock()
B_unlock()

除非do_something有对A_lock操作。
 
#5 by lin_style
 
单纯地这么看,不会有死锁。
其次,如果do_something里面会调用A_lock,则要看A_lock的实现。
最后,要保证正确操作锁的顺序,后入的锁要先出。

A_lock()
B_lock()
do_something()
B_unlock()
A_unlock() 

#6 by Jinhao
---
来源:http://topic.csdn.net/u/20090429/19/fffd3f89-6cea-4859-a57b-bd84c04ead96.html。我觉得最有用的是以下这么两句。

一、我在用别人的时,别人不应该在等我。满足这一条就不会死了。
二、要保证正确操作锁的顺序,后入的锁要先出。

No comments:

Post a Comment