GCD死锁
2019-06-07 本文已影响0人
分流替躺欧阳克
同步异步串行并发表格
同步,异步:只是对是否开启新线程有影响
- 同步dispatch_sync(queue,^{}):在当前线程中执行任务,不具备开启新线程的能力
- 异步dispatch_asyn(queue,^{}):在新的线程中执行任务,具备开启新线程的能力
并发,串行:任务的执行方式
-
并发:可以多个任务执行
-
串行:一个个的执行任务
-
例1
//死锁1
- (void)task{
dispatch_queue_t queue = dispatch_get_main_queue();
NSLog(@"执行任务1");
dispatch_sync(queue, ^{
NSLog(@"执行任务2");
});
NSLog(@"执行任务3");
}
上面代码,dispatch_sync添加的任务,需要里面执行,又因为主队列也是串行队列,所以添加的任务先进队列先执行。任务2是在task这个函数任务加入住线程队列之后才加入主队列,所以需要先等task任务执行后才能执行任务2,但是task任务又要等任务2与任务3执行完才算执行完task。互相等待,导致两个任务都永远不会执行。所以会造成死锁。
- 例2
//死锁2
- (void)task {
dispatch_queue_t queue = dispatch_queue_create("串行队列", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
NSLog(@"执行任务2");
dispatch_sync(queue, ^{
NSLog(@"执行任务3");
});
NSLog(@"执行任务4");
});
NSLog(@"执行任务5");
}
因为在queue里先加入了外层block里的任务,这个任务中又往queue里同步加入了一个任务3,,因为是同步加入,所以任务3和block任务在一个线程里,任务3需要马上执行,但是得因为任务3后于外层block任务,所以需要等外层block任务执行完后,才能执行,任务3在外层block任务里面,任务3不执行,外层block任务就执行不完,相互等待,造成死锁
总结:
现象:使用dispatch_sync()往当前串行队列中添加任务,会卡住当前的串行队列(产生死锁)
原因:串行队列中上一个任务包含下一个需要马上执行的任务时,上一个任务等待下一个任务执行完才能执行,下一个任务又需要上一个任务执行完,才能执行,互相等待就会造成死锁。