什么是多线程,进程和线程的区别:
*进程:
* 正在进行中的程序被称为进程,负责程序运行的内存分配;
* 每一个进程都有自己独立的虚拟内存空间.
*线程:(主线程最大占1M的栈区空间,每条子线程最大占512K的栈区空间)
* 线程是进程中一个独立的执行路径(控制单元);
* 一个进程中至少包含一条线程,即主线程;
* 可以将耗时的执行路径(如网络请求)放在其他线程中执行;
线程不能被杀掉,但是可以暂停/休眠一条线程.
*创建线程的目的:
* 开启一条新的执行路径,运行指定的代码,与主线程中的代码实现同时运行.
*多任务调度系统:
* 每个应用程序由操作系统分配的短暂的时间片(Timeslice)轮流使用CPU,由于CPU对每个时间片的处理速度非常快,因此,用户看来这些任务好像是同时执行的.
*并发:
* 指两个或多个任务在同一时间间隔内发生,但是,在任意一个时间点上,CPU只会处理一个任务.
*多线程的优势:
* 1> 充分发挥多核处理器优势,将不同线程任务分配给不同的处理器,真正进入"并行运算"状态;
* 2> 将耗时的任务分配到其他线程执行,由主线程负责统一更新界面会使应用程序更加流畅,用户体验更好;
* 3> 当硬件处理器的数量增加,程序会运行更快,而程序无需做任何调整.
*多线程的弊端:
新建线程会消耗内存空间和CPU时间,线程太多会降低系统的运行性能.
一、iOS的三种多线程技术特点
*1.NSThread:
* 1> 使用NSThread对象建立一个线程非常方便;
* 2> 但是!要使用NSThread管理多个线程非常困难,不推荐使用;
* 3> 技巧!使用[NSThread currentThread]跟踪任务所在线程,适用于这三种技术.
*2.NSOperation/NSOperationQueue:
* 1> 是使用GCD实现的一套Objective-C的API;
* 2> 是面向对象的多线程技术;
* 3> 提供了一些在GCD中不容易实现的特性,如:限制最大并发数量,操作之间的依赖关系.
*3.GCD---Grand Central Dispatch:
* 1>是由苹果开发的一个多核编程的解决方案,是基于C语言的底层API,iOS4.0+才能使用,是替代NSThread, NSOperation的高效和强大的技术;
* 2> 用Block定义任务,使用起来非常灵活便捷;
* 3> 提供了更多的控制能力以及操作队列中所不能使用的底层函数.
二、GCD:
当一段代码被花括号包裹并放在尖号时,我们称之为块(block)。
Dispatch Queue函数会将block执行的内容放入到指定的Queue内,这个操作是异步的,意味着它会立即返回数据不管block是否结束,也就是说我们可以在block内执行一些耗时操作,如(网络请求),而同时不会阻塞UI线程。
dispatch_get_global_queue 会获取一个全局队列,我们姑且理解为系统为我们开启的全局线程。我们用priority指定队列的优先级,而flag作为保留字段备用(一般为0)。
dispatch_get_main_queue 会返回主队列,它一般用于在其它队列中异步完成了一些工作后,需要在UI队列中更新界面。
1、GCD设计理念:
GCD的工作原理是:让程序平行排队的特定任务,根据可用的处理资源,安排他们在任何可用的处理器核心上执行任务。
一个任务可以是一个函数(function)或者是一个block。 GCD的底层依然是用线程实现,不过这样可以让程序员不用关注实现的细节。
GCD中的FIFO[ First -In-First-Out]队列称为dispatch queue,它可以保证先进来的任务先得到执行。
提示:FIFO(first_in_first_out)原则,先进先出。
2、任务和队列:
*GCD中有2个核心概念
*(1)任务:执行什么操作【block】
*(2)队列:用来存放任务【串行还是并发,系统将自动放到相应的队列中】。
*GCD的使用2个步骤:
*(1)定制任务
*(2)确定想做的事情
*将任务添加到队列中,GCD会将自动将队列中的任务取出,放到对应的线程中执行;
*提示:任务的取出遵循队列FIFO(first_in_first_out)原则。
说明:把右边的参数(任务)提交给左边的参数(队列)进行执行。
*执行任务:
*1、GCD中有2个用来执行任务的函数:
*(1)用同步的方式执行任务:dispatch_sync(dispatch_queue_t queue,dispatch_block_t block);参数说明:queue: 队列 block:任务
*(2)用异步的方式执行任务 dispatch_async(dispatch_queue_t queue,dispatch_block_block);
*2、同步和异步的区别
*同步:在当前线程中执行。
*异步:在另一条线程中执行。
*队列的类型:
*1、使用主队列(跟主线程相关的队列)
*主队列是GCD自带的一种特殊的串行队列,放到主队列中的任务,都会放到主线程中执行。用dispatch_quue_main函数获取主队列。
*示例:
dispatch_queue_t queue = dispatch_get_main_queue();
*2、串行队列:让任务一个接着一个执行(一个任务执行完毕后,再执行下一个任务。
*使用dispatch_queue_create函数创建串行队列
* 示例:dispatch_queue_t queue = dispatch_queue_create(“com.example.myqueue”,0);
*第一个参数:队列名称,自命名,苹果官方建议com.example.myqueue这种方式命名,调试程序时会非常有用,所有尽量不要重名;第二个参数队列属性,一般为空,也可以是DISPATCH_QUEUE_SERIAL(创建串行)、DISPATCH_QUEUE_CONCURRENT(并发)。
*注意:如果你部署的最低目标低于 iOS 6.0 or Mac OS X 10.8;你应该自己管理GCD对象,使用(dispatch_retain,dispatch_release),ARC并不会去管理它们。
*3、并发队列:任务按照FIFO移出队列,但是同时执行,。可以任何顺序完成
*(1)使用dispatch_queue_create函数创建并发队列
* 示例:dispatch_queue_t queue = dispatch_queue_create(“com.example.myqueue”, DISPATCH_QUEUE_CONCURRENT);
*(2)获取全局线程函数
*示例:dispatch_queue_t concurrentDefault = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
*CPU是按照等级来分配运行时间片,等级越高时间片分配越多,等级队列由高到低分别为:
DISPATCH_QUEUE_PRIORITY_HIGH,DISPATCH_QUEUE_PRIORITY_DEFAULT,DISPATCH_QUEUE_PRIORITY_LOW,DISPATCH_QUEUE_PRIORITY_BACKGROUND。
| 主线程 dispatch_get_main_queue | 串行队列 dispatch_queue_create(“com.example.myqueue”, DISPATCH_QUEUE_SERIAL);
| 全局并发队列 dispatch_queue_create(“com.example.myqueue”, DISPATCH_QUEUE_SERIAL);
|
同步 dispatch_sync | 1.没有开启新线程 2.串行执行任务 3.[线程嵌套时形成队列相互等待,死锁;形成队列等待] | 1.没有开启新线程 2.串行执行任务 3.[线程嵌套时形成队列相互等待,死锁;形成队列等待] | 1.没有开启新线程 2.串行执行任务 3.[形成队列等待] |
异步 dispatch_async | 1.没有开启新线程 2.串行执行任务 3.[把任务交给队列立即返回] | 1.开启新线程 2.串行执行任务 3.[把任务交给队列立即返回] | 1.开启新线程 2.并发执行任务 3.[把任务交给队列立即返回] |