ios 面试题之多线程死锁

死锁

死锁就是队列引发的循环等待异步

一、一个比较常见的死锁例子:主队列同步async

- (void)viewDidLoad {
    [super viewDidLoad];
    
    dispatch_sync(dispatch_get_main_queue(), ^{
       
        NSLog(@"deallock");
    });
    // Do any additional setup after loading the view, typically from a nib.
}

在主线程中运用主队列同步,也就是把任务放到了主线程的队列中。
同步对于任务是马上执行的,那么当把任务放进主队列时,它就会立马执行,只有执行完这个任务,viewDidLoad才会继续向下执行。
而viewDidLoad和任务都是在主队列上的,因为队列的先进先出原则,任务又需等待viewDidLoad执行完毕后才能继续执行,viewDidLoad和这个任务就造成了相互循环等待,就形成了死锁。
想避免这种死锁,能够将同步改为异步dispatch_async,或者将dispatch_get_main_queue换成其余串行或并行队列,均可以解决。函数

二、一样,下边的代码也会形成死锁:spa

dispatch_queue_t serialQueue = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL);

dispatch_async(serialQueue, ^{
       
        dispatch_sync(serialQueue, ^{
            
            NSLog(@"deadlock");
        });
    });

外面的函数不管是同步仍是异步都会形成死锁。
这是由于里面的任务和外面的任务都在同一个serialQueue队列内,又是同步,这就和上边主队列同步的例子同样形成了死锁
解决方法也和上边同样,将里面的同步改为异步dispatch_async,或者将serialQueue换成其余串行或并行队列,均可以解决线程

dispatch_queue_t serialQueue = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL);
    
    dispatch_queue_t serialQueue2 = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL);
    
    dispatch_async(serialQueue, ^{
       
        dispatch_sync(serialQueue2, ^{
            
            NSLog(@"deadlock");
        });
    });

这样是不会死锁的,而且serialQueue和serialQueue2是在同一个线程中的。code

相关文章
相关标签/搜索