线程iOS底层

iOS深入理解线程与锁

2021-07-04  本文已影响0人  野码道人

什么是线程

如图是线程在进程中的模型,有关内存存储分区可以看这篇文章:https://www.jianshu.com/p/ed84101e0efe
线程是执行流的最小单元,线程由以下几个部分组成

线程的共享空间
各个线程共享程序的代码段(装载到内存的可执行代码)、数据段(又称全局区)、堆区以及打开的文件

线程的私有空间
栈、线程局部存储(Thread Local Storage,简称TLS,容量有限仅用于存储线程状态机和线程控制流标识)、寄存器(操作系统会在CPU的高速缓存上申请一块内存,用于处理执行流的基本数据单元)

线程私有 多线程共享
局部变量 全局变量
函数的形参 静态变量
TLS数据 堆区数据
代码段
文件流

为何需要多线程

无论是单核处理器还是多核处理器,多线程都是充分利用资源的重要手段,而且主流手机基本都搭载了至少双核的处理器,多线程可以优雅的处理以下问题:

线程调度

单核CPU不存在真正意义上的并发,操作系统会切分很小的时间片分配给各个线程,通常几十到几百毫秒,使其轮流执行,看上去就像并发一样,这就是线程调度,每个线程都有各自的优先级,高优先级的线程总是被优先执行,低优先级的也一定会执行,如果高优先级的线程一直占用CPU,一段时间后操作系统会使其休眠,让低优先级的线程不至于饿死,线程一般有4种状态

线程状态流转
运行中的线程时间片用尽,会进入已就绪状态
运行中的线程执行到临界区时候会尝试获取资源,获取到资源会继续执行否则会进入阻塞中状态
运行中线程由于业务逻辑可主动进入等待中状态
已就绪线程被分配时间片,会进入运行中状态
等待中的线程等待结束,会进入已就绪状态
阻塞中的线程被分配时间片会检测临界区资源,如果获取到资源,则进入运行中状态否则继续阻塞

多线程的安全问题

多线程环境下,因为全局变量和堆区数据可能随时被其他线程改变而产生很大的不确定性,但是程序逻辑所希望的执行结果通常是固定的,如果数据一致性得不到保障,程序逻辑无法得到预期结果,程序将失去意义甚至crash,因此保证单条指令的执行是完整不能被打断的(原子性)尤为重要

锁的分类与性质

多线程访问同一个数据会造成不可以预知的结果,锁保证了多线程对一个数据的访问是同步的,即实现了原子性

读写锁状态 以共享的方式获取 以独占的方式获取
自由 成功 成功
共享 成功 等待
独占 等待 等待

iOS中的线程

操作系统实现了一个线程工厂称为线程池,还有一个配合工作的管理器称为调度中心,iOS系统并没有接口去直接操作线程池,线程的创建、调度、销毁全权交给线程池,当我们试图去创建一个线程的时候,调度中心会检查线程池的运行状态、运行线程数、运行策略,决定接下来的执行流程,是直接申请线程执行还是放入缓冲队列中,待到执行的时候,线程池决定是开辟新的线程还是复用现有空闲线程,长时间空闲的线程会被回收(一般10s左右)
iOS操作系统为线程运行配备了一套数据结构,一个栈、一个autoreleasePool、一个runloop(懒加载)以及一些用于控制状态的标志位变量,这些变量存储在TLS

iOS中的锁

这里只讨论原理和适用场景,不再给出demo,使用方法可以看苹果的api或者官网文档

上一篇 下一篇

猜你喜欢

热点阅读