多线程之GCD


概念

Queue 队列获取方法:
1.自己创建;
2.GCD提供的现有的队列;

串行队列

dispatch_queue_t serial_queue = dispatch_queue_create(“com.jiji.serialQueue”, DISPATCH_QUEUE_SERIAL);

dispatch_get_main_queue() // 主队列,UI队列

并发队列

diapatch_queue_t concurrent_queue = dispatch_queue_create(“com.jiji.concurrentqueue”, DISPATCH_QUEUE_CONCURRENT);

dispacth_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);  //全局队列    默认优先级

经常会有人这样问:说说串行和并发,同步与异步的区别。其实串行和并发,同步和异步,是站在不同角度对多线程的解释。

串行和并发:已经加到队列中的任务,这些任务之间执行的同步关系。(任务之间的关系)

同步和异步:调用线程是否等待任务队列中的任务执行完再继续执行。(调用线程与执行任务/线程之间的关系)

创建任务

GCD是一种轻量级的创建多线程任务的API,这里一共有六种组合创建方式。但是关于这几种方式,讨论比较多的也就三点:
1.是否需要新建线程;
2.是串行还是并发执行;
3.死锁(特殊情况);

是否新建的判断:

1).同步不新建线程,或者说没有必要新建。站在调度系统的角度考虑,同步执行意味着调用线程等待,等待是一种浪费,所以调度系统一般会直接用调用线程去执行队列中的任务。
2).异步可以新建,但不一定会新建。异步调用时,调用线程不用等待,所以一般会创建新线程去执行任务。但有一种特殊队列,主队列中的任务必须在主线程执行。

是串行还是并发的判断:

一般来说,如果只有一个线程来执行队列中的任务,那么就是串行执行,否则就是并发执行。

GCD死锁问题

这里只说一种比较普遍的情况,主线程同步执行主队列的任务会造成死锁。

为什么会这样?

1.调用线程是主线程,主线程任务是在主队列中的,而待执行的任务也要添加到主队列中;
2.同步调用,主线程任务等待待执行任务完成,
3.串行执行决定队列中的待执行任务要等待同一队列中的主线程任务完成。
4.主线程任务和待执行任务之间相互等待;

CGD通信

通常GCD队列中的任务执行线程调度都有系统根据自身资源状况决定,主队列比较特殊,其中的任务只能在主线程(UI线程)中执行。所以在其他线程执行完耗时任务,要想回到主线程,只需要将任务添加到主队列。

几个方法

1.栅栏方法 diapatch_barrier_async
将异步执行的任务分成两组。diapatch_barrier_async会等到前边追加的异步任务执行完之后,再将指定的栅栏任务追加到队列中,该追加的栅栏任务执行完成之后,异步队列恢复一般动作,开始将后续任务追加到并发队列并开始执行。

2.延迟:dispatch_after
严格说来,这个函数并不是绝对准确的延迟,因为diapatch_after并不是在指定的时间之后开始执行任务,而是在指定的时间将任务添加到主队列中。(如果并不需要精确的延迟,这个函数还是很不错的)

3.dispatch_once

4.快速迭代:dispatch_apply
串行队列中同步串行执行;并发队列中,异步并发执行。

5.队列组: diaptch_group

它山之石

GCD详尽总结:https://bujige.net/blog/iOS-Complete-learning-GCD.html

知识共享许可协议本作品采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可。
本站文章除注明转载/出处外,均为本站原创或翻译,请务必在遵守许可协议的前提下转载。
发布时间:2019-06-24 16:25:11 阅读:228 标签:iOS技术多线程