20、多线程

2020-12-09  本文已影响0人  ChenL

一、线程、进程的定义

进程
1、 进程 指的是 在系统中 正在运行的一个应用程序
2、每个进程之间是独立的,每个进程均运行在其专用的且受保护的内存空间内
3、通过 活动监听器 可以查看mac系统中所开启的线程

线程
1、线程是进程的基本执行单元,一个进程的所有任务都在线程中进行
2、进程要想执行任务,必须有线程,进行至少要有一条线程
3、程序启动回默认开启主线程/UI线程

可以简单理解:进程为线程的容器,而线程用来执行任务。在iOS中是单进程开发,一个进程就是一个App,进程之间是相互对立的

二、进程与线程的关系

1、地址空间

2、资源拥有

两者之间的关系就相当于 工厂与流水线的关系,工厂与工厂是相互独立的,而工厂中的流水线是共享工厂的资源,即 进程 相当于一个工厂,线程 相当于一个流水线

注: 进程 & 线程
1、多进程要比多线程健壮
一个进程崩溃后,在保护模式下不会对其他进程产生影响,而一个线程崩溃整个进程就会死掉

2、使用场景:频繁操作、并发操作

进程切换时,消耗的资源大、效率高。所以涉及到频繁的切换 时,使用线程要好于进程。
同样如果要求 同时进行并且又要共享某些变量的并发操作,只能用线程 不能用进程

3、执行过程

每个独立的进程 有一个程序 运行的入口、顺序 执行序列 和 程序入口,但是 线程不能独立执行,必须依赖在应用中,由应用程序提供多个线程执行控制。

4、线程时处理器的基本单位,但进程不是

5、线程没有地址空间,线程包含在进程地址空间中

三、线程与RunLoop的关系

1、runloop 与线程是一一对应的,一个runloop对应一个核心的线程,为什么说是核心的,是因为runloop是可以嵌套的,但是核心的只能由一个,他们的关系保存在一个全局的字典里

2、runloop 是用来管理线程的,当线程的runloop被开启后,线程会在执行完任务后进入休眠状态,有了任务就会被唤醒去执行任务

3、runloop 在第一次获取时被创建,在线程结束时被销毁

4、对于主线程来说, runloop在程序一启动就默认创建好了

5、对于子线程来说,runloop是懒加载的,只是当我们使用的时候才会创建,所以在子线程用定时器要注意:确保子线程的runloop被创建,不然定时器不会回调

四、多线程原理

1、对于单核CPU,同一时间,CPU只能处理一条线程,即只有一条线程在工作

2、iOS 中的多线程同时执行的本质是 CPU在多个任务直接进行快速的切换,由于CPU调度线程的 时间足够快,就造成了 多线程的“同时”执行的效果。其中切换的时间间隔就是时间片

多线程的意义
优点:
1、能适当 提高程序的执行效率,
2、能适当 提高资源的利用率
3、线程上的任务执行完成后,线程会自动销毁

缺点:
1、开启线程需要占用一定的内存空间,默认情况下,每一个线程占用512KB
2、如果开启 大量线程,会占用大量的内存空间,降低程序的性能。
3、线程越多,CPU在调用线程上的开销就会越大
4、程序设计更加复杂,比如线程间的通信,多线程的数据共享

五、多线程的生命周期

image.png

新建:主要是实例化线程对象

就绪:线程对象 调用start方法,将线程对象加入调度线程池,等待CPU的调用 即调用start方法,并不会立即执行,进入就绪状态,需要等待一段时间,经CPU调度后才执行,也就是从就绪状态进入 运行状态

运行:CPU负责调度可调度线程中线程的执行,在线程执行完成之前,其状态可能会在就绪和运行之间来回切换,这个变化是 由CPU负责,开发人员不能干预。

阻塞:当满足某个预定条件时,可以 使用休眠,即sleep,或者同步锁,阻塞线程执行。当进入sleep时,会重新将 线程加入就绪中。下面关于休眠的时间设置,都是NSthread

死亡:分为两种情况:一、正常死亡:即线程执行完毕;二、非正常死亡:即当满足某个条件后,在线程内部/或者主线中 终止执行 [调用exit方法等退出]

简要说明
处于 运行中的线程 拥有一段可以执行的时间 (时间片)

线程的exit 和 cancel 说明:
exit: 一旦强行终止线程,后续的所有代码都不会执行
cancel :取消当前线程,但是不能取消正在执行的线程

问: 线程的优先级越高,是不是意味着任务的执行越快?

并不是,线程执行的快慢,除了要看优先级,还需要看 资源的大小(任务的复杂度)、以及 CPU调度 情况。在NSThread中,线程优先级threadPriority 已经被服务质量qualityOfService 取代。

六、线程池原理

image.png

第四步 做一下说明:

交给饱和策略去执行,主要有以下四种:
AbortPolicy: 直接抛出RejectedExecutionExeception异常来阻止系统正常运行
CallerRunsPolicy:将任务回退到调用者
DisOldestPolicy:丢掉等待最久的任务
DisCardPolicy:直接丢弃任务

image.png

七、线程安全问题

当多个线程同时访问一块资源时,容易引发数据错乱和数据安全问题,有以下两种解决方案:

互斥锁

需注意:

自旋锁

区别:
同:

在同一时间,保证了只有一条线程执行任务,即保证了相应同步的功能

不同:

场景:根据任务复杂度区分,使用不同的锁,但判断不全,更多是使用互斥锁去处理;当前任务状态比较 短小时,用自旋锁,反之用互斥锁

八、atomic 原子锁 & nonatomic 非原子锁

atomic 和 nonatomic 主要用于属性的修饰

atomic 是原子属性,是为了 多线程开发准备的,是默认属性

nonatomic :非原子属性

上一篇 下一篇

猜你喜欢

热点阅读