[九九Tips]- http://www.jianshu.com/users/bab86b3e8aa3/latest_articles
iOS多线程梳理
本篇文章主要梳理iOS多线程相关基础概念,使用方法,几种多线程方案对比.
进程和线程的区别
进程 是指在系统中正在运行的一个应用程序,是系统资源的基本分配单位.在内存中有完备的数据空间和代码空间,拥有完整的虚拟空间地址.
线程 是进程内相对独立的可执行单元,是操作系统进行任务调度的基本单元.与父进程的其他线程共享该进程所拥有的全部代码空间和全局变量.一个进程至少拥有一个主线程.
区别
1.系统开销:在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤消线程时的开销.
2.资源管理:进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响.但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉.所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。
3.通信方式:进程间通信主要包括管道、系统IPC(包括消息队列,信号量,共享存储)、SOCKET.但对应归于同一进程的不同线程来说,使用全局变量进行通信效率会更高。
iOS中几种多线程方案对比
iOS有以下四种解决方案:一个一个详细分析.
1.Pthreads
2.NSThread
3.GCD
4.NSOperationQueue
1.Pthreads
POSIX线程(POSIX threads),简称Pthreads,是线程的POSIX标准。该标准定义了创建和操纵线程的一整套API。在类Unix操作系统(Unix、Linux、Mac OS X等)中,都使用Pthreads作为操作系统的线程。Pthreads是一套纯C语言的,通用API,跨平台可移植性强.
缺点:需要手动处理线程的各个状态的转换即管理生命周期,比较麻烦.苹果不推荐使用.
2.NSThread
NSThread是苹果封装后的,直接面向对象操作.但是还需手动管理生命周期.
- [NSThread currentThread] 来获取当前线程。
- [NSThread mainThread] 来获取主线程.
NSThread使用方法简单,但是应用场景有限.
3.GCD
GCD为Grand Central Dispatch的缩写。Grand Central Dispatch (GCD)是Apple开发的一个多核编程的较新的解决方法。
GCD自动管理线程的生命周期(创建线程、调度任务、销毁线程).
GCD有两个很重要的概念:任务和队列.
-
任务 在 GCD 中就是一个 Block,任务有两种执行方式:同步执行 和 异步执行.
- 同步(sync) 操作,它会阻塞当前线程并等待 Block 中的任务执行完毕,然后当前线程才会继续往下运行。同步任务:不会另开线程.
- 异步(async)操作,当前线程会直接往下执行,它不会阻塞当前线程。异步任务:会另开线程.
-
队列 用于存放任务。一共有两种队列, 串行队列 和 并行队列。
- 串行队列,放到串行队列的任务,GCD 会 FIFO(先进先出) 地取出来一个,执行一个,然后取下一个,这样一个一个的执行。
- 并行队列,放到并行队列的任务,GCD 也会 FIFO的取出来,但不同的是,它取出来一个就会放到别的线程,然后再取出来一个又放到另一个的线程。这样由于取的动作很快,忽略不计,看起来,所有的任务都是一起执行的。不过需要注意,GCD 会根据系统资源控制并行的数量,所以如果任务很多,它并不会让所有任务同时执行。也就是说并行就是开很多线程一个一个执行
- 主队列: 这是一个特殊的 串行队列.它用于刷新 UI,任何需要刷新 UI 的工作都要在主队列执行.
- 创建队列
//第一个参数是标识符,用于 DEBUG 的时候标识唯一的队列,可以为空. /** 第二个参数用来表示创建的队列是串行的还是并行的. DISPATCH_QUEUE_SERIAL 或 NULL 表示创建串行队列; DISPATCH_QUEUE_CONCURRENT 表示创建并行队列. **/ dispatch_queue_t queue = dispatch_queue_create("tk.bourne.testQueue", NULL);
4.NSOperationQueue
NSOperation 是苹果公司对 GCD 的封装,完全面向对象.
NSOperation 和 NSOperationQueue 分别对应 GCD 的 任务 和 队列 .
- 1.NSOperationQueue不分并行和串行,NSOperationQueue 有一个参数 maxConcurrentOperationCount 最大并发数,用来设置最多可以让多少个任务同时执行。当你把它设置为 1 的时候,就是串行.
- 2.NSOperation添加依赖。可以使用 removeDependency 来解除依赖关系。这样就能控制任务的执行顺序.
//1.任务一:
NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
[NSThread sleepForTimeInterval:1.0];
}];
//2.任务二:
NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
[NSThread sleepForTimeInterval:1.0];
}];
//3.任务三:
NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{
[NSThread sleepForTimeInterval:1.0];
}];
//4.设置依赖
[operation2 addDependency:operation1]; //任务二依赖任务一
[operation3 addDependency:operation2]; //任务三依赖任务二
//5.创建队列并加入任务
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperations:@[operation3, operation2, operation1] waitUntilFinished:NO];
以上部分内容参考该博客:http://www.jianshu.com/p/0b0d9b1f1f19