iOS多线程(一)

首先了解单线程:
一、单线程的应用,整个应用中只有一个顺序执行流,
当执行流在执行某个耗时的操作,或者不能立即完成的任务时(比如网络通信、复杂的运行)该执行流就会被阻塞,整个应用就会卡在那里无法继续执行,因此单线程的程序功能往往是非常有限的.
我们可以这样理解,单线程程序如同只雇佣一个服务员的餐厅,他必须做完一件事情后才能做下一件的事情,多线程程序则如同雇用多个服务员的餐厅,他们可以同时进行多件事情。

二、线程和进程
所有运行中的任务通常对应一个进程Process (prəʊsɛsˈ),当一个程序进入内存运行后即变成了一个进程,进程是系统进行资源分配和调度的一个独立单位.当一个进程运行时,内部可能包含多个顺序执行流,每个顺序执行流就是一个线程.
一般而言进程包括如下三个特征:
1、独立性:进程是系统中的独立存在的实体,有自己独立的资源,每一个进程都有自己的私有地址空间,没有允许,其它用户进程不可以直接访问其它的进程空间。
2、动态性:进程与程序的区别在于,程序只是一个静态的指令集合,而进程是一个正在系统中活动的指令集合,在进程中加入了时间的概念,进程具有自己的生命周期和各种不同的状态,这些概念在程序中都是不具备的。
3、并发性:多个进程可以在单个处理器上并发执行。
4、并发性(concurrency kənˈkʌr(ə)ns)和 并行性(parallel ˈparəlɛl ) 是两个概念,
4.1、并发性:指在同一时刻只能有一条指令执行,但多个进程指定被快速轮换执行,使得在宏观上具有多个进程同时执行的效果。大部分操作系统都支持多线程并发运行,例如:一边写程序一边查看手册同时播放音乐等等……这些进程看上去像是在同时工作。对于一个CPU,它在某个时间点上只能执行一个程序,只能运行一个进程,CPU不断的在这些进程之间轮换执行,
4.2、并行性:指在同一时刻有多少指令在多个处理器上同时执行。

三、多线程和多进程
多线程则扩展了多进程的概念,使得同一个进程可以同时并发处理多个任务,
线程(Thread θrɛd )也被称作轻量级进程(Lightweight Process)
线程是进程的执行单元,线程在程序中是独立的、并发的执行流。
当进程被初始化后,主线程就被创建了,对于绝大多数的应用程序来说,通常仅要求有一个主线程,但我们可以在该程序内创建多条顺序执行流,这些顺序执行流就是线程 每条线程也是相互独立的。
操作系统可以同时执行多个任务,每个任务就是进程;进程可以同时执行多个任务,每个任务就是线程。一个程序运行后至少有一个进程,一个进程里可以有多个线程,但至少要包含一个线程。也就是说一个线程必须有一个父进程,线程是进程的组成部分,
线程可以拥有自己的堆栈,自己的程序计数器和自己的局部变量,但不再拥有系统资源。线程是独立运行的,线程的执行是抢占式的。也就是说当前运行的线程在任何时候都可能被挂起,以方便另外一个线程可以运行。一个线程可以创建和撤销另一个线程,线程的调度和管理有进程本身负责完成。

四、多线程
1、为什么要用多线程?
答: 每个iOS 应用程序都有专门的自己的用来更新显示UI界面或处理用户的触摸事件的-主线程,因此不能将其他太耗时的操作放在主线程中去执行,不然会造成主线程堵塞(出现卡机的现象),带来极坏的用户体验。
So 一般的解决方案就是将那些耗时的操作放到另外一个线程中去执行,
So 多线程编程是防止主线程堵塞,增加运行效率等等的最佳方法。而原始的多线程方法存在很多的毛病,包括线程锁死等。
例如: 用户上的某个按钮,该按钮需要执行的任务需要几秒甚至几十秒,如果直接在UI线程中完成这个任务,这个任务执行完成、返回之前,UI线程被该任务阻塞,无法响应用户的其他操作--在这个时间内,用户的iOS操作系统的操作将不会有任何反应(除非用户单击home键返回)这不是用户希望的结果,最好的做法是:将任何耗时的任务,(比如复杂的运算、从网络下载数据等操作)都放在非UI线程中完成,这样UI线程就不会被阻塞,IOS应用也不会失去响应。
2、多线程是什么?
答: 多线程是个复杂的概念,按字面意思是同步完成多项任务,提高了资源的使用效率,
1>从硬件、操作系统、应用软件不同的角度去看,多线程被赋予不同的内涵,对于硬件,现在市面上多数的CPU都是多核的,多核的CPU运算多线程更为出色;
2>从操作系统角度,是多任务,现在用的主流操作系统都是多任务的,可以一边听歌、一边写博客;
对于应用来说,多线程可以让应用有更快的回应,可以在网络下载时,同时响应用户的触摸操作。
3>在iOS应用中,对多线程最初的理解,就是并发,它的含义是原来先做烧水,再摘菜,再炒菜的工作,会变成烧水的同时去摘菜,最后去炒菜。
3、 多线程的底层实现?
1> 首先搞清楚什么是线程、什么是多线程?
2> Mach是第一个以多线程方式处理任务的系统,因此多线程的底层实现机制是基于Mach的线程
3> 开发中很少用Mach级的线程,因为Mach级的线程没有提供多线程的基本特征,线程之间是独立的
4> 开发中实现多线程的方案
4.1 C语言的POSIX接口:#include <pthread.h>
4.2 OC的NSThread
4.3 C语言的GCD接口(性能最好,代码更精简)
4.4 OC的NSOperation和NSOperationQueue(基于GCD)

五、iOS中有哪些多线程编程?
iOS中的多线程,是Cocoa框架下的多线程,通过Cocoa的封装,可以让我们更为方便的使用线程,做过C++的同学可能会对线程有更多的理解,比如线程的创立,信号量、共享变量有认识,Cocoa框架下会方便很多,它对线程做了封装,有些封装,可以让我们创建的对象,本身便拥有线程,也就是线程的对象化抽象,从而减少我们的工程,提供程序的健壮性。
iOS支持-多个-层次的-多线程编程,提供了如下三种多线程编程的技术:
1.NSThread 每个 NSThread对象 对应一个线程,量级较轻(真正的多线程)
2.以下两点是苹果专门开发的“并发”技术,使得程序员可以不再去关心线程的具体使用问题
1> NSOperation/NSOperationQueue 面向对象的线程技术
2> GCD —— Grand Central Dispatch(派发) 是基于C语言的框架,可以充分利用多核,是苹果推荐使用的多线程技术
//使用NSThread实现多线程,(θrɛd )
//使用NSOperation与 NSOperationQueue 实现多线程
//使用GCD实现多线程(Grand Central Dispatch)
以上这三种编程方式从上到下,抽象度层次是从低到高的,抽象度越高的使用越简单,也是Apple最推荐使用的,在项目中很多框架技术分别使用了不同多线程技术。

六、三种多线程技术的对比

  1. NSThread:
    –优点:NSThread比其他两种多线程方案较轻量级,更直观地控制线程对象(θred )
    –缺点:需要自己管理线程的生命周期、线程同步、加锁、睡眠以及唤醒等。线程同步对数据的加锁会导致一定的性能开销
    2.NSOperation:
    –NSOperation是面向对象的 (Cocoa Operations 是基于OC实现的)
    NSOperation 是以-面向对象-的方式-封装了-需要执行的操作,–不需要关心线程管理,数据同步的事情,可以把精力放在自己需要执行的操作上
    NSOperation是一个抽象基类,iOS提供了两种默认实现:
    NSInvocationOperation (ɪnvəˈkeɪʃn) 和 NSBlockOperation,当然也可以自定义NSOperation
    3.GCD:
    -Grand Central Dispatch (grænd sentrəl dɪˈspætʃ 简称GCD,iOS4.0+才能使用,基于C语言的)
    –GCD是由苹果开发的一个多核编程的解决方案。是替代NSThread, NSOperation的高效和强大的技术 提供了一些新特性、运行库来支持多核并行编程-,它的关注点更高:如何在多个cpu上提升效率
    GCD从系统级别提供的一个易用的多线程类库,具有运行时的特点,能充分利用多核心硬件。
    GCD的API接口为C语言的函数,函数参数中多数有Block,关于Block的使用为我们提供强大的“接口”

七、一般的面试问题:

  1. 线程间怎么通信?
    1> performSelector:onThread:withObject:waitUntilDone:
    2> NSMachPort
  1. 网络图片处理问题中怎么解决一个相同的网络地址重复请求的问题?
    利用字典(图片地址为key,下载操作为value)
  1. 谈谈多线程安全的几种解决办法及多线程安全怎么控制?
    1> 只在主线程刷新访问UI
    2> 如果要防止资源抢夺,得用@synchronized [ˈsɪŋkrəˌnaɪzd]进行加锁保护
    3> 如果异步操作要保证线程安全等问题,尽量使用GCD(有些函数默认就是安全的) 《你可以看一下之前的文章单例的创建,采用GCD的方式创建的》
  2. 你用过NSOperationQueue么?为什么要使用NSOperationQueue,实现了什么? 以及描述它和GCD的区别和类似的地方?(提示:可以从两者的实现机制和适用范围来描述)。
    1> GCD是纯C语言的API,NSOperationQueue是基于GCD的OC版本封装
    2> GCD只支持FIFO的队列,NSOperationQueue可以很方便地调整执行顺序、设置最大并发数量
    3> NSOperationQueue可以在轻松在Operation间设置依赖关系,而GCD需要写很多的代码才能实现
    4> NSOperationQueue支持KVO,可以监测operation是否正在执行(isExecuted)、是否结束(isFinished),是否取消(isCanceld)
    5> GCD的执行速度比NSOperationQueue快
    任务之间不太互相依赖使用:GCD
    任务之间有依赖\或者要监听任务的执行情况使用:NSOperationQueue
  1. 在使用GCD以及block时要注意些什么?它们两是一回事儿么?block在ARC中和传统的MRC中的行为和用法有没有什么区别,需要注意些什么?
    Block的使用注意:
    1> block的内存管理
    2> 防止循环retian
    λ 非ARC(MRC):__block
    λ ARC:__weak__unsafe_unretained
    使用block是要注意,若将block做函数参数时,需要把它放到最后,GCD是Grand Central Dispatch,是一个对线程开源类库,而Block是闭包,是能够读取其他函数内部变量的函数。

6.在异步线程中下载很多图片,如果失败了,该如何处理?请结合RunLoop来谈谈解决方案.(提示:在异步线程中启动一个RunLoop重新发送网络请求,下载图片)
1> 重新下载图片
2> 下载完毕, 利用RunLoop的输入源回到主线程刷新UIImageVIUew

7.在项目什么时候选择使用GCD,什么时候选择NSOperation?
使用NSOperationQueue用来管理子类化的NSOperation对象,控制其线程并发数目。GCD和NSOperation都可以实现对线程的管理,区别是 NSOperation和NSOperationQueue是多线程的面向对象抽象。
项目中使用NSOperation的优点是: NSOperation是对线程的高度抽象,在项目中使用它,会使项目的程序结构更好,子类化NSOperation的设计思路,是具有面向对象的优点(复用、封装),使得实现是多线程支持,而接口简单,建议在复杂项目中使用。
项目中使用GCD的优点是GCD本身非常简单、易用,对于不复杂的多线程操作,会节省代码量,而Block参数的使用,会是代码更为易读,建议在简单项目中使用

8、您是否做过异步的网络处理和通讯方面的工作?如果有,能具体介绍一些实现策略么?
使用NSOperation发送异步网络请求,使用NSOperationQueue管理线程数目及优先级,底层是用NSURLSession

9、OC中有线程池(线程队例)吗?NSOperationQueue是如何管理线程的:
1>、NSPOperationQueue是OC中的线程池,线程可以存放多个线程
2>、NSPOperationQueue可以管理线程的并发数,还可以管理线程之间的优先级。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,108评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,699评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,812评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,236评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,583评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,739评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,957评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,704评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,447评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,643评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,133评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,486评论 3 256
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,151评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,889评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,782评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,681评论 2 272

推荐阅读更多精彩内容

  • Object C中创建线程的方法是什么?如果在主线程中执行代码,方法是什么?如果想延时执行代码、方法又是什么? 1...
    AlanGe阅读 1,664评论 0 17
  • 在说多线程之前,首先要明白线程,进程 线程和进程 进程: 系统中正在运行的程序,称为一个进程 每个进程,都在自己独...
    时来运不转阅读 548评论 0 3
  • 多线程 在iOS开发中为提高程序的运行效率会将比较耗时的操作放在子线程中执行,iOS系统进程默认启动一个主线程,用...
    郭豪豪阅读 2,518评论 0 4
  • .一.进程 进程:是指在系统中正在运行的一个应用程序,每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空...
    IIronMan阅读 4,429评论 1 33
  • 欢迎大家指出文章中需要改正或者需要补充的地方,我会及时更新,非常感谢。 一. 多线程基础 1. 进程 进程是指在系...
    xx_cc阅读 7,118评论 11 69