开发者

Deadlocks and Livelocks issues using @synchronized directive in objective c

from the apple's "Threading Programming Guide" I've read that "The best way to avoid both deadlock and livelock situations is to take 开发者_运维知识库only one lock at a time". If I prefer to use the @synchronized directive in my code, this means that I should do something like this:

@synchronized(aObj) {

@synchronized(bObj) {

    // do sth with the aObj and bObj here     
} 

}

instead of this:

@synchronized(aObj, bObj) {

 // do sth with the aObj and bObj here

}

?? if not, what it means by "One lock at a time?". Thank you...


The best way to avoid deadlock is to ensure that all threads try to lock and unlock objects in the same order. That's it, really.

By following that one simple rule, the chance of deadlocks is zero.

It doesn't matter whether you try to allocate all the needed locks in one hit or over a significant timeframe, as long as the order is consistent. In other words, don't ever do:

Thread A        Thread B
========        ========
lock a          lock b
lock b          lock a

This can lead to the sequence:

  • A locks a.
  • B locks b.
  • A tries to lock b, stops and waits.
  • B tries to lock a, stops and waits.

Now both threads are waiting on the other to release their needed resource, hence deadlock.

If you change thread B so that it locks a and b in that order, deadlock becomes impossible.


Holding multiple locks at the same time immediately raises the specter of deadlock.if two threads acquire the same locks in a different order, they can end up waiting on each other forever. This problem can be used to solved enforcing the lock order.

 @synchronized(MIN(a, b))
    {
        @synchronized(MAX(a, b))
        {
            // do stuff, safely
        }
    }

This works with other locking constructs as well. like:

 NSLock *a = [[NSLock alloc] init];
    NSLock *b = [[NSLock alloc] init];

    [MIN(a, b) lock];
    [MAX(a, b) lock];

    [MAX(a, b) unlock];
    [MIN(a, b) unlock];


Both versions of your code are equally evil and an invitation to a deadlock. What the advice meant is you should write

@synchronized (obj1) { ... }
@synchronized (obj2) { ... }

You have a potential deadlock if one thread performs nested locks (using one lock, then another) in a different order from another thread. One simple rule to avoid this is to never have two nested locks.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜