死锁就是队列引发的循环等待异步
一、一个比较常见的死锁例子:主队列同步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