关注我,连载进行中....
iOS 当中的多线程方案. 总结如下图:
我平时使用最多的是 gcd. 不论是 GCD .NSThread,NSOperation,底层都是 pthread. 我更倾向于 GCD.
GCD 中有两个可以用来执行任务的函数
同步方式: 在当前线程,在一条线上执行任务
dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);
queue:队列
block:任务
异步方式: 开启新的线程
dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
GCD 队列
并发队列(Concurrent Dispatch Queue)
可以让多个任务并发(同时)执行(自动开启多个线程同时执行任务)
并发功能只有在异步(dispatch_async)函数下才有效
串行队列(Serial Dispatch Queue)
让任务一个接着一个地执行(一个任务执行完毕后,再执行下一个任务)
总结:
如果并发队列在同步方式中也是任务一个一个的执行. 并且不会开启新的线程. 串行队列使用异步方式,会开启多条线程,同步执行. 异步,同步决定了是否开启新的线程
比较容易混淆的概念: 同步,异步,并发,串行
同步和异步主要影响:能不能开启新的线程
同步:在当前线程中执行任务,不具备开启新线程的能力
异步:在新的线程中执行任务,具备开启新线程的能力. 如果传入的是主队列, 将不会开启新的线程
并发和串行主要影响:任务的执行方式
并发:多个任务并发(同时)执行
串行:一个任务执行完毕后,再执行下一个任务
各种队列执行的效果如下:
只要是同步 sync.就一定不会开启新的线程, 不会开启新的线程就一定是串行执行
只有异步+并发 才是并发执行任务,其他都是串行执行任务
在串行任务中使用同步执行,会造成死锁
队列的特点: 排队 FIFO 概念 先进先出
问题:以下代码是在主线程执行的,会不会产生死锁?会!
dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_sync(queue, ^{
NSLog(@"执行任务2");
});
NSLog(@"执行任务3");
// dispatch_sync立马在当前线程同步执行任务
分析: 为什么上面的代码会造成死锁
此任务是添加在主队列里面的,说明是添加在主线程. 那么根据 FIFO 的原则. 当前任务 2 的任务执行的条件是等到上一个任务执行完. 而主线程里面的上一个任务就是要执行当前这段代码(任务 1). 也就是说它需要等到任务 3执行完毕才能去执行任务 2.因为是同步执行,执行完当前的任务才能处理下一个任务. 当前代码是执行完任务 2 才能执行任务 3 . 所以任务 2 和任务 3 相互等待. 所以造成了死锁
iOS高级进阶之多线程 (二 )
网友评论