GCD:Grand Central Diapath
GCD多线程中的几组概念:
- 任务:即操作,你想要干什么,说白了就是一段代码,在GCD中的一个block就是一个任务。
任务的执行方式有两种:
同步执行和异步执行,两者的区分在于是否会阻塞当前线程
直到block中的任务执行完毕。
同步执行(sync)
:会阻塞当前线程
并等待 Block 中的任务执行完毕,然后当前线程才会继续往下运行。
异步执行(async)
,不会阻塞当前线程
,当前线程会直接往下执行,同时需要异步执行的任务需要开启新的线程执行
- 队列:用于存放任务,分为
串行队列
和并行队列
两种。
串行队列
:放入串行队列中的任务,GCD 会按照 FIFO(先进先出)的规则,先取出来一个,执行一个,然后取下一个,这样一个一个的执行。
并行队列
:放到并行队列的任务,GCD 也会按照 FIFO(先进先出)的规则取出来,但不同的是,它取出来一个就会放到别的线程,然后再取出来一个又放到另一个的线程。这样由于取的动作很快,忽略不计,看起来,所有的任务都是一起执行的。不过需要注意,GCD 会根据系统资源控制并行的数量,所以如果任务很多,它并不会让所有任务同时执行。
//主队列main是一个特殊的串行队列,用于刷新UI,耗时工作一般不在main线程做,避免界面卡顿
dispatch_queue_t queue = dispatch_get_main_queue();
//全局队列global是系统提供的一个并行队列,一般需要放入并行队列中的任务可以放入全局队列中
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
=========== | 同步执行 | 异步执行 |
---|---|---|
串行队列 | 当前线程,一个一个执行 | 其他线程,一个一个执行 |
并行队列 | 当前线程,一个一个执行 | 开很多线程,一起执行 |
iOS四套多线程方案的使用
参见文章:关于iOS多线程,你看我就够了
另外一篇博客:
iOS中GCD的使用小结
这篇博客中介绍了一下内容:
- 多线程相关概念
- 多线程编程技术的优缺点比较?
- GCD中的三种队列类型
- The main queue(主线程串行队列)
- Global queue(全局并发队列)
- Custom queue (自定义队列)
- Group queue (队列组)
- GCD中一些系统提供的常用dispatch方法
博客三:
iOS开发系列–并行开发其实很容易
博客四:
猫猫学iOS(五十)多线程网络之GCD简单介绍(任务,队列)
这些博客都写得很好。。。各种不懂,可以看看,忘记了,可以再看看。。。
多线程死锁的问题
看一下文章吧:
GCD 之线程死锁
摘了一段话:
发生死锁的情况一般是两个对象的锁相互等待造成的。那么为什么会产生死锁呢?
有3个原因:
第一,因为系统资源不足;第二,进程运行推进的顺序不合适;
第三,资源分配不当。
产生死锁的条件有四个:
- 互斥条件:所谓互斥就是进程在某一时间内独占资源。
- 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
- 不剥夺条件:进程已获得资源,在末使用完之前,不能强行剥夺。
- 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。死锁通常是一个线程锁定了一个资源A,而又想去锁定资源B;在另一个线程中,锁定了资源B,而又想去锁定资源A以完成自身的操作,两个线程都想得到对方的资源,而不愿释放自己的资源,造成两个线程都在相互等待,造成了无法执行的情况。
避免死锁的一个通用的经验法则是:当几个线程都要访问共享资源A、B、C时,保证使每个线程都按照同样的顺序去访问它们,比如都先访问A,再访问B和C。
GCD中线程,任务,队列的关系
看了这么些文章,对线程、任务、队列这三者的关系有点糊涂,尤其是线程与队列的关系。
首先,任务的执行方式有同步执行和异步执行,由是否阻塞当前线程来区分,**任务是放到线程中执行**
的吧,以同步或者异步的方式(至于到底在哪个线程中执行,看具体情况吧)、
然后,**任务都是存放在队列中**
的吧,可能存放在串行队列也可能存放在并行队列,要先从队列中取出然后再放入到线程中执行的。
最后,我就不知道线程跟队列到底是个怎样的关系了。
所以我也百度了一些文章:
线程与队列的关系:
ios初级 (线程与队列的关系,傻瓜学线程)
进程,线程等一些概念:
iOS编程–GCD相关(进程、线程/多线程、并行/串行队列、同步/异步任务)