前序:按顺序阅读更好面试
iOS 多线程之GCD服务器
进程:进程是指在系统中正在运行的一个应用程序,如微信、QQ等app都是一个进程.markdown
线程:线程是进程的基本执行单元,处理器调度的基本单位. 一个进程的全部任务都在线程中执行.进程至少要有一条线程,程序启动会默认开启一条线程,这条线程被成为主线程或UI线程网络
任务: 就是执行操做的意思,换句话说就是你在线程中执行的那段代码(在 GCD 中是放在 block 中的)。执行任务有两种方式:同步执行 和 异步执行。二者的主要区别是:是否等待队列的任务执行结束,以及是否具有开启新线程的能力。多线程
同步执行(sync):并发
异步执行(async):app
在io等待的时候,同步不会切走,浪费了时间。 若是都是独占cpu 的业务, 在单核状况下 多线和单线 没有区别。异步
队列:(Dispatch Queue):这里的队列指执行任务的等待队列,即用来存听任务的队列。队列是一种特殊的线性表,采用 FIFO(先进先出)的原则。GCD 中有两种队列串行队列和并发队列。二者都符合 FIFO(先进先出)的原则。二者的主要区别是:执行顺序不一样,以及开启线程数不一样。
串行队列(Serial Dispatch Queue):每次只有一个任务被执行。让任务一个接着一个地执行。(只开启一个线程,一个任务执行完毕后,再执行下一个任务)
并发队列(Concurrent Dispatch Queue):可让多个任务并发(同时)执行。(能够开启多个线程,而且同时执行任务)
因此任务和队列的组合方式有 4 种
队列/执行 | 并发队列 | 串行队列 | 主队列(特殊的串行队列) | 全局队列(特殊的并发队列) |
---|---|---|---|---|
同步(sync) | 没有开启新线程,串行执行任务 | 没有开启新线程,串行执行任务 | 死锁卡住不执行 | 没有开启新线程,串行执行任务 |
异步(async) | 有开启新线程,并发执行任务 | 有开启新线程,串行执行任务 | 没有开启新线程,串行执行任务 | 有开启新线程,并发执行任务 |
注意
并发队列的并发功能只有在异步(dispatch_async)方法下才有效。
主队列是特殊的串行队列, 全局队列是特殊的并发队列(系统提供的)
主队列的实质上就是一个普通的串行队列,主线程 中调用 主队列+同步执行 会致使死锁问题。 这是由于 主队列中追加的同步任务 和 主线程自己的任务 二者之间相互等待,阻塞了主队列,最终形成了主队列所在的线程(主线程)死锁问题.
并发(concurrency):把任务在不一样的时间点交给处理器进行处理。在同一时间点,任务并不会同时运行。
并行(parallelism):把每个任务分配给每个处理器独立完成。在同一时间点,任务必定是同时运行
单核处理器,多线程只能并发执行(并发原理就是cpu快速来回切换);
多核处理器能够实现真正的并行,也就是真正的同时运行
既然单核处理器不能实现真正的并行,那么单核cpu有必要多线程吗?
一般一个任务不光 cpu 上要花时间,io上也要花时间(例如去数据库查数据,去抓网页,读写文件等)。一个进程在等 io 的时候,cpu 是闲置的,另外一个进程正好能够利用 cpu 进行计算。 多个进程一块儿跑,能够把 io 和 cpu 都跑满了。
若是都是独占cpu 的业务,在单核状况下多线程和单线程没有区别
如今通常都是虚拟资源,资源有弹缩机制,因此通常该跑多线程的时候就能够跑多线程
1.在多核处理器上,将要执行的任务分红多个可并行执行的线程,就能够提升执行效率。
2.在单核处理器上,多线程只能并发执行,而不是并行,并发原理,其实就是cpu快速来回切换,在特定的时间执行特定的某一个任务,并发执行存在这线程间上下文切换的问题,会消耗必定的时间。若是不考虑阻塞,多线程并发执行其实比单线程执行更加耗费时间,线程过多也会形成cpu负荷过大,而且线程占用内存资源,建立销毁线程也都是须要开销的。
多线程经过提升cpu利用率来提升效率。数据库访问、磁盘io等操做的速度比cpu执行代码的速度慢不少,单线程环境下,这些操做会阻塞程序的执行,致使cpu空转,等待着上述操做完成,所以对于会产生这些阻塞的程序来讲,使用多线程能够避免在等待期间cpu的空转,提升cpu的利用率。
考虑到多线程存在的一些缺点,如今的网络服务器为了支持大量并发多不是靠多线程或多进程,而采用其余的技术如异步i/o