iOS 多线程之基础

在开始之前,先理解以下几点
一、进程和线程的区别和联系:
1、地址资源:进程有自己的内存地址,进程内的线程可以共享进程的内存地址
2、资源分配和调度:进程是系统进行资源分配和拥有的基本单位,同一个进程内的线程可共享进程的资源
3、线程是CPU调度的基本单位。
4、二者都可以并发执行
二、多线程的意义
优点:
1、提高资源(CPU和内存)利用率
2、提高程序的执行效率
3、线程上的任务执行完后,线程会自动销毁
缺点:
1、开辟线程需要占用一定的内存空间(默认每个线程占用512kb)
2、线程越多,CPU调度的开销越大
三、多线程原理
多线程的并发执行其实并不是同时执行,而是CPU在不同的线程间频繁切换,达到的“伪同时”效果。这是由于每一个分得CPU的任务都会有一个时间片,它执行完时间片的时间,CPU就不属于它们了,要等待再次分配。

抛出问题

问题1、主线程是做什么的?
答:主线程是iOS程序运行后开辟的第一个线程,也叫UI线程,用来显示/刷新UI界面和处理UI事件。
问题2、UI为什么要在主线程更新?
答:苹果为了性能考虑,UIKit不是线程安全的,试想如果UI可以在子线程更新,那么如果有多个线程同时修改某个资源时将会出现很多莫名其妙的错误。
问题3、能不能把渲染放到子线程?怎么渲染
遗留问题。

线程和Runloop的关系

1、Runloop和线程是一一对应的关系
2、Runloop是来管理线程的,当线程的runloop被开启后,线程执行完任务会休眠,等下次有任务时再执行任务。
3、线程在第一次创建是被开启,在线程结束时销毁
3、Runloop在子线程中默认不开启,需要手动操作才能开启。注意NSTImer

线程池工作原理

系统中的线程属于宝贵资源,合理运用线程池,可以减少创建和销毁线程的次数,使得每个线程可以重复利用。

  • corePoolSize:线程池基本大小(核心线程数量)
  • maximumPoolSize:线程池允许的最大线程数
  • keepAliveTime:当线程池的线程数量大于corePoolSize时,空闲线程的最大存活时间
  • workQueue:存放任务的工作队列
  • handler:超出线程范围和队列容量的任务的处理程序

线程池的工作流程:当提交一个任务时,线程池会做出如下判断
1、如果正在运行的线程数量小于corePoolSize,马上创建线程执行任务。
2、如果正在运行的线程数量大于等于corePoolSize,则放入工作队列中。
3、如果不巧,工作队列也满了,而且正在运行的线程数量小于maximumPoolSize,那么还是要创建线程立刻运行这个任务。
4、如果正在运行的线程数量大于等于maximumPoolSize,则交给饱和策略处理。
如图所示

线程池工作原理 .png

当线程池的线程执行完任务以后,会从工作队列取下一个任务执行。
当一个线程空闲,且正在运行的线程数大于corePoolSize,则计时超过keepAliveTime线程就会被kill掉,所以当线程池中任务都完成后,它最终会缩小到corePoolSize大小。

饱和策略

当任务提交线程池失败时,即当前提交的任务数超过maxmumPoolSizeworkQueue之和时,就会交给饱和策略处理。
饱和策略有四种,AbortPolicyCallerRunsPolicyDiscardPolicyDiscardOldestPolicy

策略 Description
AbortPolicy 中止策略,属于默认的饱和策略,该策略将抛出未检查的RejectedExecutionException。调用者可以捕获这个异常,然后根据需要编写自己的处理代码。
DiscardPolicy 抛弃策略,当新提交的任务无法保存到队列中等待执行时,“抛弃(Discard)”策略会悄悄抛弃该任务。
DiscardOldestPolicy 抛弃下一个将被执行的任务,然后尝试重新提交新的任务。(如果工作队列是一个优先队列,那么“抛弃最旧的”策略将导致抛弃优先级最高的任务,因此最好不要将“抛弃最旧的”饱和策略和优先队列放在一起使用。)
CallerRunsPolicy 调用者策略,策略实现了一种调度机制,该策略既不会抛弃任务,也不会抛出异常,而是将某些任务回退到调用者,从而降低新任务的流量。它不会在线程池的某个线程中执行新提交的任务,而是在一个调用了execute的线程中执行该任务。如果采用有界队列和“调用者运行”饱和策略,当线程池中的所有线程都被占用,并且工作队列被填满后,下一个任务会在调用execute时在主线程中执行。由于执行任务需要一定的时间,因此主线程至少在一段时间内不能提交任何任务,从而使得工作者线程有时间来处理完正在执行的任务。在此期间,主线程不会调用accept,因此到达的请求将被保存在TCP层的队列中而不是在应用程序的队列中。如果持续过载,那么TCP层将最终发现它的请求队列被填满,因此同样会开始抛弃请求。当服务器过载时,这种过载情况会逐渐向外蔓延开来——从线程池到工作队列到应用程序再到TCP层,最终达到客户端,导致服务器在高负载下实现一种平缓的性能降低。

线程的生命周期

线程生命周期的每一步如下所示:

  • 1、新建:实例化线程对象
  • 2、就绪:调用start将线程加入可调度线程池,等待CPU调度(分配时间片)。
  • 3、运行:CPU从可调度线程池中分配时间片给线程,线程在未执行完毕情况下可能会在就绪运行之间不断切换,程序员无法干预。
  • 4、阻塞:线程有时会因为同步、锁、sleep等方式阻塞。
  • 5、死亡:分为正常死亡(线程结束)和非正常死亡(线程终止)。
线程生命周期.png
多线程的四种技术方案

多线程有四种技术方案分别是pthread、NSThread、GCD和NSOperation,如下图所示


多线程的几种方式

我们一般使用比较多的是GCD,因为开发者只需要告诉 GCD 想要执行什么任务,不需要编写任何线程管理代码,但这也是GCD的不够灵活的地方,我们无法监控线程的各个状态,这也是很多大框架中使用NSOperation的原因,NSOperation相比GCD更加灵活,开发者可以通过KVO监测Operation的状态,自定义NSOperation等。

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

推荐阅读更多精彩内容

  • iOS多线程编程 基本知识 1. 进程(process) 进程是指在系统中正在运行的一个应用程序,就是一段程序的执...
    陵无山阅读 6,043评论 1 14
  • 又来到了一个老生常谈的问题,应用层软件开发的程序员要不要了解和深入学习操作系统呢? 今天就这个问题开始,来谈谈操...
    tangsl阅读 4,124评论 0 23
  • 多线程 在iOS开发中为提高程序的运行效率会将比较耗时的操作放在子线程中执行,iOS系统进程默认启动一个主线程,用...
    郭豪豪阅读 2,597评论 0 4
  • 首先了解单线程:一、单线程的应用,整个应用中只有一个顺序执行流,当执行流在执行某个耗时的操作,或者不能立即完成的任...
    蓝白七七阅读 572评论 1 8
  • 走亲串友深山行, 山雨欲来风云涌。 惊叹遇上鬼天气, 频遭数袭黑旋风。 急返失足溺水里, 有幸得救乃郎中。 平时功...
    太阳哥月亮妹阅读 399评论 3 16