GCD死锁现象解释前了解
1.核心概念
- 1.1任务:要执行的代码块
1.2队列:存放任务
2.GCD中要实现多线程编程步骤- 2.1定制任务
- 2.2把任务添加到队列中(同步函数/异步函数)
3.函数
3.1同步函数:
- 3.1.1不具备开线程能力,只能在当前线程中执行任务(会等待主线程)
- 3.1.2执行任务方式:同步
3.2异步函数:
- 3.2.1具备开线程能力,不一定开线程(不等待主线程)
3.2.2执行任务方式:异步
4.队列- 4.1并发队列:队列中多个任务并发执行
- 4.2串行队列:一个接一个执行.必须等待前一个任务执行完毕后才执行后面的任务
- 4.3主队列:
- 4.3.1和主线程相关联的串行队列
- 4.3.2凡是放在主队列中的任务都必须在主线程中执行
- 4.3.3当主队列中有任务时,会安排主线程前来执行任务,执行前检查主线程状态(主线程忙:暂停调度,直到主线程空闲为止)
死锁解释
1.一般死锁发生的情况在于主线程正在等待队列中的任务执行完毕
- 1.1而由于该队列使用的是同步函数
- 1.2同步函数是只能在当前线程中执行并且会等待前方的任务(主线程)
2.简单来说就是相互等待
- 2.1主队列等待主线程空闲
- 2.2同步函数中的任务等待主线程完成执行
死锁解决
示例一 :主队列+同步函数(死锁) –>把同步函数改成异步函数即可
- (void)viewDidLoad {
[super viewDidLoad];
//主队列
dispatch_queue_t queue = dispatch_get_main_queue();
//异步函数
dispatch_async(queue, ^{
NSLog(@"d1---%@",[NSThread currentThread]);
});
}
示例二:快速迭代+同步函数(死锁)–>再外层套个异步函数
//for循环
for (int i = 0 ; i < 5 ; i++) {
NSLog(@"%@",[NSThread currentThread]);
}
/**
* 快速迭代:根据队列自动判断是否开启线程
*
* @param iterations#> 遍历的次数 description#>
* @param queue#> 队列 description#>
* @param size_t 传入的参数(与for循环的i类似)
*
* 注意:
* 1.和主队列搭配会死锁
* 2.与串行队列搭配串行执行任务,不开启线程(与for循环一样)
* 3.与并发队列\全局并发搭配,开启线程并且与主线程一起并发执行任务
*/
//串行队列
dispatch_queue_t queue = dispatch_queue_create("gg", DISPATCH_QUEUE_SERIAL);
//套异步函数
dispatch_async(queue, ^{
//快速迭代+主队列
dispatch_apply(5, dispatch_get_main_queue(), ^(size_t i) {
NSLog(@"%@",[NSThread currentThread]);
});
});
总结:
- 1.把同步函数直接修改成异步函数
- 2.在外层套异步函数
- 2.1套异步函数使用并发队列和串行队列都不会发生死锁
- 2.2套异步函数不要使用主队列