网上关于多线程的文章太多了,但是我发现好多存在不正确或者不规范的地方
参考文章链接
https://juejin.im/post/59c13d5cf265da0669085a52#heading-10
并行和并发
网上好多文章都混淆了并行和并发的概念,其实这两者有本质区别: 并行是真正的多线程,并发是伪多线程.
这里引用一下别人博客的截图
同一时刻,一个CPU只能处理一个操作,只有多核CPU才能处理多个操作,也就是说只有多核CPU才是并行的
我们平时开发中,基本上都是并发
任务 ,队列, 线程
任务:
即,operation,就是一段代码块,在 GCD 中就是一个 Block
任务分两种:同步执行 任务 和 异步执行任务,
二者区别: 此任务是否会阻塞当前线程(系统是否会为任务创建新的线程)
至于开一条,还是开多条线程,是由 任务和队列 综合因素决定的
队列:
队列是 保存 和 管理任务的;队列本身是线程安全的.
队列分为 串行队列(serial) 和 并发队列(concurrent),所有队列都遵循FIFO(先进先出)的原则;将任务加到队列中,任务会按照加入到队列中先后顺序依次执行。
注意:
1.在队列中,任务的取出都是FIFO的,但是出了队列任务的执行就不一定了
2.放到串行队列的任务,GCD 会 FIFO(先进先出) 地取出来一个,执行一个,然后取下一个,这样一个一个的执行
3.放到并发队列的任务,GCD 也会 FIFO的取出来(也就是说,它也是伪并行的,同一时刻它也只能取出一个任务)
但不同的是,它取出来一个就会放到别的线程,然后再取出来一个又放到另一个的线程。这样由于取的动作很快,忽略不计,看起来,所有的任务都是一起取出的。
不过需要注意,GCD 会根据系统资源控制并行的数量,所以如果任务很多,它并不会让所有任务同时取出.
线程:
线程的创建、维护和销毁由操作系统管理的
如何分析 线程和任务的执行情况
先看任务是阻塞还是非阻塞,在看对列是串行还是并发的
任务和队列排列组合有四种情况
1.同步任务,串行队列
这里要注意很容易造成死锁,例如
- (void)viewDidAppear:(BOOL)animated {
dispatch_sync(dispatch_get_main_queue(), ^(void){
NSLog(@"这里死锁了");
});
}
新版XCode编译器直接报错了,来分析一下原因:
viewDidAppear这个方法是在主线程运行的,方法里block是个是个同步任务会阻塞当前线程,主线程是存放在主队列中,block也是在主队列中,由于是同步任务当程序执行到这个block这行代码时要立刻执行这个block,但是由于是在串行队列中,任务是一个一个取出的,viewDidAppear函数还没有返回,所以这个block是不会从对列取出的,所以就造成死锁了