iOS 多线程完整知识体系
🧠 一、多线程思维导图
多线程
├── 1. 基础概念
│ ├── 进程(Process)与线程(Thread)
│ ├── 同步(Synchronous) vs 异步(Asynchronous)
│ ├── 串行(Serial) vs 并发(Concurrent)
│ ├── 线程安全(Thread Safety)与竞态条件(Race Condition)
│ ├── 上下文切换(Context Switch)
│ └── 死锁(Deadlock)
├── 2. iOS 多线程方案
│ ├── pthread(POSIX线程,C语言,跨平台,手动管理)
│ ├── NSThread(OC,面向对象,手动管理)
│ ├── GCD(Grand Central Dispatch,C语言,自动管理,基于队列)
│ │ ├── 函数
│ │ │ ├── dispatch_sync(同步派发)
│ │ │ └── dispatch_async(异步派发)
│ │ ├── 队列
│ │ │ ├── 串行队列(Serial Queue)
│ │ │ ├── 并发队列(Concurrent Queue)
│ │ │ ├── 主队列(Main Queue)
│ │ │ └── 全局并发队列(Global Concurrent Queue)
│ │ ├── 队列组(Dispatch Group)
│ │ ├── 栅栏(Dispatch Barrier)
│ │ ├── 信号量(Dispatch Semaphore)
│ │ ├── 数据源(Dispatch Source)
│ │ └── 死锁场景(Deadlock Scenarios)
│ └── NSOperationQueue(OC,面向对象,基于GCD)
│ ├── NSOperation 子类(NSInvocationOperation,NSBlockOperation)
│ ├── 特性:依赖(Dependency)、KVO、取消(Cancel)、最大并发数(MaxConcurrentOperationCount)
│ └── 对比 GCD
├── 3. 线程安全与锁
│ ├── 安全隐患
│ │ ├── 资源共享(Resource Sharing)
│ │ ├── 数据错乱(Data Corruption)
│ │ └── 死锁(Deadlock)
│ ├── 锁方案
│ │ ├── OSSpinLock(自旋锁,已废弃)
│ │ ├── os_unfair_lock(非公平锁,替代自旋锁)
│ │ ├── pthread_mutex(互斥锁,支持递归锁、条件锁)
│ │ ├── NSLock / NSRecursiveLock(递归锁)
│ │ ├── NSCondition(条件变量) / NSConditionLock(条件锁)
│ │ ├── dispatch_semaphore(信号量)
│ │ ├── @synchronized(同步锁)
│ │ ├── atomic(原子属性修饰符)
│ │ └── 串行队列实现同步(Serial Queue for Synchronization)
│ ├── 读写安全
│ │ ├── pthread_rwlock(读写锁)
│ │ └── dispatch_barrier_async(异步栅栏)
│ └── 自旋锁(Spinlock) vs 互斥锁(Mutex)
│ ├── 自旋锁:忙等(Busy-wait)、短临界区、多核
│ └── 互斥锁:休眠(Sleep)、长临界区、单核
├── 4. 常见问题与场景
│ ├── performSelector 延时与 RunLoop(运行循环)
│ ├── 主队列死锁(Main Queue Deadlock)
│ ├── 线程同步经典案例:存钱取钱、卖票
│ └── 多读单写(Multiple Readers Single Writer)实现
└── 5. 性能与源码
├── 锁性能对比(os_unfair_lock > dispatch_semaphore > ...)
├── GCD 源码:libdispatch
├── objc4 中的 @synchronized 实现
└── atomic 实现:objc-accessors.mm
❓二、面试题及答案
下面列出 15 道核心面试题,每道题均包含 专业答案(按【初级掌握】【中级扩展】【高级深入】分层)和 通俗解释。
1. 你理解的多线程?
【专业答案】
- 初级掌握:多线程是指从软件或硬件上实现多个线程并发执行的技术。在 iOS 中,主线程负责 UI 渲染,耗时操作(网络请求、文件读写)放在子线程,避免界面卡顿。
-
中级扩展:多线程的核心目的是充分利用多核 CPU,提高资源利用率。但同时也带来线程安全问题,如竞态条件、死锁。iOS 中通过 RunLoop、GCD 等机制管理线程生命周期,开发者需关注线程间通信(如
performSelector、dispatch_async回到主线程)。 - 高级深入:从操作系统层面,线程是 CPU 调度的最小单位,每个线程有自己的栈空间和寄存器状态。iOS 采用 XNU 内核,基于 Mach 线程和 POSIX 线程(pthread)实现。GCD 通过线程池管理,避免频繁创建销毁线程的开销,同时利用 workqueue 机制根据系统负载动态调整线程数。深入理解多线程需要掌握内存屏障、指令重排、缓存一致性等底层知识。
【通俗解释】
多线程就是让计算机同时干多件事。就像一个人(主线程)做饭,如果还要接电话,就会手忙脚乱;多线程就是多找几个人帮忙,各干各的,提高效率。但人多了容易吵架(数据错乱)或互相等死(死锁),需要一套管理规则。
2. iOS 的多线程方案有哪几种?你更倾向于哪一种?
【专业答案】
- 初级掌握:四种方案:pthread(C 语言,跨平台)、NSThread(OC,面向对象)、GCD(C 语言,基于队列)、NSOperation(OC,基于 GCD)。我倾向使用 GCD,因为它简单高效,能满足大部分需求。
-
中级扩展:选择依据场景:
- GCD:适合轻量级异步任务,如网络回调、数据解析。
- NSOperationQueue:适合复杂任务管理,如任务依赖、取消、最大并发数控制。
- NSThread:需要手动管理线程生命周期,几乎不用。
-
pthread:底层跨平台需求,如音视频 SDK。
我倾向于 NSOperationQueue,因为它提供更高层的抽象,且易于维护。
- 高级深入:从性能角度,GCD 基于 libdispatch,是 C 语言实现的,轻量且高效,其底层使用线程池和 workqueue,能根据 CPU 核心数和负载动态调整。NSOperationQueue 是对 GCD 的封装,增加了 OC 对象开销,但提供了 KVO、依赖等特性。在需要精细控制时,也可直接使用 pthread。苹果官方推荐优先使用 GCD 和 NSOperation,避免直接操作线程。我还研究过 GCD 的源码,其队列、组、信号量的实现涉及双向链表、原子操作和条件变量。
【通俗解释】
就像干活有不同的工具:GCD 像一把瑞士军刀,简单好用;NSOperationQueue 像工具箱,功能更多(可以设置任务依赖、取消等)。简单任务用 GCD,复杂任务用 NSOperationQueue。
3. GCD 的队列类型有哪些?
【专业答案】
- 初级掌握:两种:串行队列(Serial Dispatch Queue)和并发队列(Concurrent Dispatch Queue)。还有系统提供的主队列(主线程串行)和全局并发队列。
-
中级扩展:队列分为:
- 主队列:绑定主线程,串行。
- 自定义串行队列:创建一个新线程(或复用线程池中的线程)串行执行。
- 全局并发队列:系统提供的并发队列,有四个优先级(对应 QOS)。
-
自定义并发队列:自己创建的并发队列,可以设置优先级。
注意:dispatch_sync向当前串行队列提交任务会导致死锁。
-
高级深入:GCD 队列底层是一个
dispatch_queue_s结构体,包含队列类型、优先级、挂载的线程池等。串行队列底层绑定一个pthread_workqueue,而并发队列使用线程池,任务通过dispatch_async提交后,由 libdispatch 的 worker 线程执行。全局并发队列本质上是系统维护的几个静态队列,优先级对应QOS_CLASS。深入理解队列需要研究dispatch_async的入队和唤醒机制,涉及系统调用和 workqueue 的负载均衡。
【通俗解释】
队列就像任务管道:主队列是给主线程用的(只有一条路),串行队列也是一条路,一个一个来;并发队列是多个路,可以同时走;全局队列是公共道路。
4. OperationQueue 和 GCD 的区别,各自的优势?
【专业答案】
-
初级掌握:
- GCD:基于 C,轻量,适合简单异步任务。
- NSOperationQueue:基于 GCD,面向对象,支持任务依赖、取消、状态监控。
-
中级扩展:
- GCD 优势:语法简洁,性能高,使用 block,适合快速开发。
-
NSOperationQueue 优势:可设置最大并发数、任务依赖(
addDependency)、暂停/恢复(suspended)、KVO 监听状态,支持自定义NSOperation子类。
选择:如果需要精细控制任务流程,用 NSOperationQueue;否则用 GCD。
-
高级深入:NSOperationQueue 底层使用 GCD 的队列和信号量实现,但其抽象层提供了更丰富的功能。例如,任务依赖通过维护一个等待队列和计数器实现;取消操作通过原子标志位和 KVO 触发。GCD 则更接近底层,没有这些高层抽象,但可以自己用
dispatch_group、dispatch_semaphore模拟。性能上,GCD 略胜一筹,因为 NSOperationQueue 增加了 Objective-C 消息转发和 KVO 开销。但在实际应用中,除非是极端性能要求,否则差异可忽略。
【通俗解释】
GCD 写起来快,像一把快刀;NSOperationQueue 像一把多功能军刀,可以随时取消任务,让任务排队等,适合复杂场景。
5. 线程安全的处理手段有哪些?
【专业答案】
-
初级掌握:加锁(如
@synchronized、NSLock)、使用串行队列、atomic 属性修饰符。 -
中级扩展:常见手段:
-
锁:互斥锁(
pthread_mutex、NSLock)、自旋锁(os_unfair_lock)、递归锁、条件锁、读写锁。 -
GCD:串行队列、信号量(
dispatch_semaphore)、栅栏(dispatch_barrier_async)。 -
其他:atomic(仅保证 setter/getter 原子性)、不可变对象(如
NSString)、线程本地存储(Thread Local Storage)。
需根据场景选择合适方案,避免死锁和性能瓶颈。
-
锁:互斥锁(
-
高级深入:深入理解线程安全需考虑硬件层面(缓存一致性、内存屏障)和编译器层面(指令重排)。iOS 中,atomic 修饰符在底层通过 spinlock(旧版)或
os_unfair_lock(新版)实现,但只保证读写的原子性,不保证业务逻辑安全。真正的线程安全需要从设计上避免共享可变状态,多用值类型(Swift)或不可变对象。此外,无锁编程(Lock-Free)利用 CAS 原子操作实现高性能同步,但难度极高,需谨慎。
【通俗解释】
给共享资源加把锁,一次只让一个人访问。锁的种类很多,各有特点。还可以用 GCD 的队列来串行化访问,或者用读写锁实现多读单写。
6. 你了解的锁有哪些?请对比自旋锁和互斥锁,并说明使用注意。
【专业答案】
-
初级掌握:锁有
OSSpinLock、os_unfair_lock、pthread_mutex、NSLock、@synchronized等。自旋锁会一直占用 CPU 等待,互斥锁会让线程休眠。使用注意避免死锁。 -
中级扩展:
-
自旋锁:适合临界区短、多核环境,避免线程切换开销。但
OSSpinLock已废弃,因优先级反转问题,改用os_unfair_lock(实际是互斥锁)。 - 互斥锁:适合临界区长、单核环境,线程休眠不占 CPU。
-
注意:锁的粒度要小,避免在加锁时调用外部可能加锁的代码;递归锁用于递归函数;使用
@synchronized时要注意对象不能为 nil。
-
自旋锁:适合临界区短、多核环境,避免线程切换开销。但
-
高级深入:
-
OSSpinLock:基于忙等,无系统调用,但高优先级线程等待低优先级线程释放锁时,低优先级无法调度,导致优先级反转。iOS 10 后用
os_unfair_lock替代,它基于 mach semaphore,线程会休眠。 - pthread_mutex:支持普通、递归、条件等多种类型,性能高,可跨平台。底层使用 futex(Linux)或 ulock(iOS)实现快速用户态锁。
- dispatch_semaphore:信号量,初始值设为 1 可作互斥锁,底层基于条件变量和原子操作。
-
性能对比:
os_unfair_lock最快,其次是dispatch_semaphore,然后是pthread_mutex,最后是@synchronized(因需查表、异常处理)。 -
注意:锁的使用要结合内存屏障防止指令重排;在 Swift 中建议使用
os_unfair_lock或DispatchQueue串行同步。
-
OSSpinLock:基于忙等,无系统调用,但高优先级线程等待低优先级线程释放锁时,低优先级无法调度,导致优先级反转。iOS 10 后用
【通俗解释】
自旋锁就像你在门口一直敲门,适合快速操作;互斥锁是先去睡觉,有人叫你再起来,适合慢操作。用锁时要小心,别把自己锁死(死锁)。不同锁的速度也不同,os_unfair_lock 最快。
7. 如何实现多读单写(读写安全)?
【专业答案】
-
初级掌握:可以使用
dispatch_barrier_async实现,写操作使用栅栏,读操作使用异步并发。 -
中级扩展:两种主流方案:
- pthread_rwlock:读写锁,读加读锁,写加写锁,支持多读单写。
-
dispatch_barrier_async:在自定义并发队列中,写操作提交栅栏任务,读操作提交普通异步任务,利用栅栏保证写独占。
注意:栅栏必须用在自定义并发队列,全局队列无效。
-
高级深入:
pthread_rwlock底层基于条件变量和互斥锁实现,读锁可重入,写锁优先级可能提升以避免写饥饿。dispatch_barrier_async的底层机制:在并发队列中,栅栏任务之前的任务全部执行完毕后,栅栏任务单独执行,之后的任务才继续并发。其实现依赖于队列的挂起和唤醒机制。性能上,pthread_rwlock在大量读场景下表现更好,栅栏在写操作较少时开销较低。还需考虑公平性,避免写线程长时间等待。
【通俗解释】
读可以同时多人,写只能一个人,写的时候不能读。pthread_rwlock 是专门的读写锁,栅栏是利用 GCD 的特性实现的。
8. 什么是上下文切换?它对性能有什么影响?
【专业答案】
- 初级掌握:上下文切换是指 CPU 从一个线程/进程切换到另一个线程/进程时,保存当前状态(上下文)并加载新状态的过程。频繁切换会消耗 CPU 时间,降低性能。
- 中级扩展:上下文切换涉及寄存器状态、程序计数器、栈指针等的保存与恢复,以及 TLB 刷新、缓存失效等。在 iOS 中,线程切换开销约为几微秒到几十微秒。过多的线程或锁竞争会导致频繁切换,成为性能瓶颈。使用 GCD 的线程池可减少切换,因为任务在同一线程上连续执行。
-
高级深入:上下文切换分为用户态切换(如协程)和内核态切换(线程切换)。内核态切换需要陷入内核,执行调度算法,开销更大。iOS 基于 Mach 内核,使用 workqueue 机制,线程切换涉及
mach_msg、thread_switch等系统调用。深入优化需减少锁竞争、使用无锁编程、合理设置线程优先级,避免优先级反转导致额外切换。
【通俗解释】
就像你正在看书,突然要去接电话,你需要记住看到哪一页(保存状态),接完电话再翻到那页(恢复状态)。频繁接电话就会浪费很多时间在翻书上。多线程切换也是一样,切换太多会拖慢速度。
9. 什么是 dispatch_source?有哪些应用场景?
【专业答案】
-
初级掌握:
dispatch_source是 GCD 提供的一种机制,用于监听底层系统事件(如定时器、文件描述符、信号等)并提交处理 block。常用场景:定时器、监控文件变化、处理信号。 -
中级扩展:
dispatch_source比NSTimer更精准(不受 RunLoop 模式影响),且支持取消、暂停、合并事件。例如,用dispatch_source创建定时器可实现后台持续任务;用DISPATCH_SOURCE_TYPE_VNODE监控文件写入。它基于事件驱动,效率高。 -
高级深入:
dispatch_source底层使用内核事件队列(kqueue)或 Mach 端口,将事件转换为 GCD 任务提交到指定队列。其事件处理支持合并(如DISPATCH_SOURCE_TYPE_DATA_ADD),可减少回调次数。源码中,dispatch_source通过kevent注册事件,由_dispatch_kevent_work线程唤醒。在 iOS 中,常用dispatch_source实现高性能定时器,避免NSTimer对 RunLoop 的依赖。
【通俗解释】
dispatch_source 就像一个小哨兵,专门盯着某些事情发生(比如时间到了、文件改了),然后通知你去做事。它比普通的定时器更可靠,不会因为你在刷朋友圈就耽误了。
10. NSCondition 和 NSConditionLock 的区别与使用?
【专业答案】
-
初级掌握:
NSCondition用于线程间的条件通知,可以等待某个条件成立再继续执行;NSConditionLock是带有特定条件值的锁,只有条件匹配时才能获得锁。两者都用于多线程同步。 -
中级扩展:
NSCondition封装了pthread_cond_t和pthread_mutex_t,提供wait、signal、broadcast方法,适合生产者-消费者模式。NSConditionLock封装了NSCondition,并增加了一个整型条件值,只有lockWhenCondition:时条件匹配才能加锁,更适用于状态机场景。使用时注意 wait 前必须加锁,signal 后要解锁。 -
高级深入:
NSCondition底层是 pthread 条件变量,wait 内部调用pthread_cond_wait,会原子性地释放锁并阻塞线程,被 signal 唤醒后重新获取锁。NSConditionLock在 condition 上维护一个整数值,加锁时检查当前值,不匹配则等待。其源码可在 GNUstep 中找到。性能上,两者接近,但NSConditionLock因增加条件检查略慢。实际开发中,可用dispatch_semaphore或串行队列替代。
【通俗解释】
NSCondition 像是一个广播站,线程可以等待特定消息;NSConditionLock 像是一个密码锁,只有密码对了才能开门。
11. atomic 关键字的底层实现?它能保证绝对线程安全吗?
【专业答案】
- 初级掌握:atomic 是属性修饰符,保证属性的 setter/getter 方法原子性,即同时读写不会被中断。但并不能保证整个对象的线程安全。
-
中级扩展:atomic 底层通过锁(旧版使用 spinlock,新版使用
os_unfair_lock)在 setter/getter 内部加锁实现。例如,objc_setProperty和objc_getProperty内部会加锁。它只保证单个属性的读写原子性,但不保证复合操作(如先读后改)的安全,且性能低于 nonatomic。 -
高级深入:源码位于
objc-accessors.mm,atomic 属性的 setter 调用reallySetProperty,内部使用spinlock_t(本质是os_unfair_lock)加锁。注意,atomic 只防止读写同时发生,但不阻止多个线程同时调用不同方法导致的数据竞争。真正的线程安全需要更高级的同步机制。此外,atomic 在 64 位平台上对某些类型使用原子指令(如atomic_load)优化,但本质上仍有限。
【通俗解释】
atomic 就像给属性加了一把小锁,保证你拿的时候不会被人改,但如果你先拿了再去做别的事,中间还是可能出问题。所以它不是万能药。
12. 请简述 GCD 的线程池管理机制(基于源码理解)。
【专业答案】
- 初级掌握:GCD 内部维护一个线程池,根据任务数量和系统负载动态创建和回收线程,避免频繁创建线程的开销。
-
中级扩展:GCD 的线程池称为 "workqueue" 或 "root queue"。全局并发队列对应几个优先级的 workqueue,自定义队列会挂载到这些 workqueue 上。当任务提交时,GCD 根据队列类型和优先级,从线程池中唤醒或创建线程执行。线程闲置一段时间后会被回收。通过
dispatch_async提交的任务,底层调用_dispatch_worker_thread,最终由 pthread 创建。 -
高级深入:深入 libdispatch 源码:
dispatch_queue_t对应struct dispatch_queue_s,内部有dq_state和dq_running等字段。提交任务时,通过_dispatch_queue_wakeup唤醒线程。线程池由_dispatch_worker_threads管理,使用_pthread_workqueue_addthreads创建新线程。GCD 采用 overcommit 策略,可根据 CPU 负载动态调整线程数,优先级通过 QOS 映射。研究源码可发现,GCD 的线程管理涉及 Mach 内核的 workqueue 机制,高效且省电。
【通俗解释】
GCD 就像一个调度中心,手底下有一群工人(线程)。任务来了,它会安排空闲的工人去做;工人不够就招新;工人闲着太久就让他们回家休息。这样既快又不浪费资源。
13. @synchronized 的底层实现原理?优缺点?
【专业答案】
-
初级掌握:
@synchronized是 OC 提供的便捷加锁语法,使用对象作为锁,保证同一时刻只有一个线程能执行大括号内的代码。 -
中级扩展:
@synchronized底层基于pthread_mutex递归锁实现。每个对象关联一个递归锁,存储在全局的SideTable中(通过对象的指针哈希映射)。当第一次使用时创建锁,之后复用。优点是语法简洁,支持递归;缺点是性能较差(需查表、异常处理),且容易因滥用导致死锁。 -
高级深入:源码位于
objc-sync.mm。@synchronized(obj)展开为objc_sync_enter(obj)和objc_sync_exit(obj)。内部通过id2data(obj)找到对应的SyncData,SyncData包含递归锁和线程计数。支持嵌套加锁,因为递归锁。缺点:锁的全局哈希表可能冲突,且有异常保护开销。苹果建议在性能敏感时使用其他锁。
【通俗解释】
@synchronized 就像给代码块贴了一个标签,标签对应的对象是谁,谁就是钥匙。同一时间只有拿着钥匙的人能进去。它很方便,但人多的时候有点慢。
14. 什么是死锁?如何避免死锁?
【专业答案】
- 初级掌握:死锁是指两个或多个线程互相等待对方释放资源,导致所有线程都无法继续执行。例如,主队列同步任务就会死锁。
- 中级扩展:死锁的四个必要条件:互斥、持有并等待、不可剥夺、循环等待。避免方法:破坏任一条件,如使用 tryLock、按相同顺序加锁、使用锁超时、减少锁粒度。在 iOS 中,避免在串行队列中调用同步任务,使用异步设计。
-
高级深入:死锁不仅发生在锁上,也可能发生在 GCD 队列(如
dispatch_sync向当前队列提交)。更深层,系统级死锁涉及资源分配图。检测死锁可使用 Instruments 的 Thread State 工具。设计时采用 "锁排序" 或 "资源分级" 策略。对于复杂系统,可用事务机制或死锁检测算法(如银行家算法)预防。
【通俗解释】
死锁就像两个人互相挡住对方的出路,谁也别想走。要避免这种情况,就要事先约定好谁先走,或者让一个人主动让一下。
15. 什么是竞态条件?举例说明并给出解决方案。
【专业答案】
- 初级掌握:竞态条件(Race Condition)是指多个线程同时访问共享数据,且结果依赖于线程执行顺序,导致数据不一致。例如,两个线程同时给同一个变量 +1,可能只加了一次。
-
中级扩展:经典例子:多线程卖票,不加锁会导致超卖。解决方案:加锁(如
@synchronized)、使用串行队列、原子操作。注意,竞态条件不仅发生在写操作,读-改-写操作也可能出现。 -
高级深入:竞态条件本质是操作的非原子性。编译器优化和 CPU 乱序执行也可能引入竞态。修复方法:使用原子操作(如
OSAtomicAdd32)、内存屏障、锁或无锁数据结构。在 Swift 中,可使用 actor(Swift 5.5+)隔离可变状态。底层需关注内存模型,避免重排。
【通俗解释】
竞态条件就像两个人同时抢一个麦克风,结果谁都没拿到,或者同时讲话乱套了。解决办法是排队(加锁)或者指定一个人拿(原子操作)。
🧭 三、初中高工程师回答指南
初级工程师
- 特点:掌握基本概念,能使用简单 API,理解常见场景。
-
准备方向:
- 熟悉 GCD 的基本使用:async/sync,主队列/全局队列。
- 知道锁的几种类型(
@synchronized,NSLock)。 - 能解释死锁的简单例子(如主队列 sync)。
-
回答技巧:
- 用生活中的例子类比,让面试官觉得你有理解。
- 遇到不会的,坦诚并表明自己会继续学习。
中级工程师
- 特点:能根据场景选择合适方案,理解原理和性能差异,能处理复杂问题。
-
准备方向:
- 深入理解 GCD 队列类型、组、信号量、栅栏。
- 掌握 NSOperationQueue 的高级特性(依赖、KVO、取消)。
- 了解各种锁的适用场景和性能排序。
- 熟悉常见的线程安全设计模式(如多读单写)。
-
回答技巧:
- 对比不同方案的优缺点,给出选择依据。
- 结合项目经验,说明解决过的问题(如用栅栏实现数据安全)。
- 能画图或口述代码示例。
高级工程师
- 特点:理解底层实现,能优化性能,解决疑难杂症,有源码阅读能力。
-
准备方向:
- 研究 GCD 源码(libdispatch),了解队列、线程池、workqueue。
- 理解锁的底层实现(futex, ulock, mach semaphore)。
- 掌握无锁编程、内存屏障、指令重排等底层知识。
- 能设计高性能线程安全组件(如读写锁封装)。
-
回答技巧:
- 深入原理,如提到 "
dispatch_async底层是调用_dispatch_worker_thread唤醒线程"。 - 分析性能瓶颈,给出优化建议(如锁粒度、避免优先级反转)。
- 引用苹果官方文档或源码注释,展示专业性。
- 深入原理,如提到 "
📘 四、英文术语速查表
| 英文术语 | 中文解释 | 简要说明 |
|---|---|---|
| Thread | 线程 | CPU 调度的最小单位 |
| Process | 进程 | 资源分配的基本单位,包含多个线程 |
| Concurrency | 并发 | 多个任务在同一个时间段内交替执行 |
| Parallelism | 并行 | 多个任务在同一时刻同时执行(多核) |
| Synchronous | 同步 | 等待任务执行完成才返回 |
| Asynchronous | 异步 | 不等待任务执行,立即返回 |
| Serial Queue | 串行队列 | 任务一个接一个执行 |
| Concurrent Queue | 并发队列 | 任务可以同时执行 |
| Deadlock | 死锁 | 两个或多个线程互相等待对方释放资源 |
| Race Condition | 竞态条件 | 多个线程访问共享数据导致结果不确定 |
| Thread Safety | 线程安全 | 多个线程同时访问不会导致数据错乱 |
| Mutex | 互斥锁 | 一次只有一个线程进入临界区 |
| Spinlock | 自旋锁 | 线程忙等,不进入休眠 |
| Semaphore | 信号量 | 控制并发访问数量的同步原语 |
| Read-Write Lock | 读写锁 | 多读单写,提高读并发 |
| Atomic | 原子操作 | 不可被中断的操作,通常用于属性修饰 |
| Barrier | 栅栏 | 在并发队列中确保任务顺序 |
| Dispatch Group | 调度组 | 监控一组任务的完成 |
| RunLoop | 运行循环 | 处理事件和定时器的线程循环 |
| Thread Pool | 线程池 | 一组预先创建的线程,用于执行任务 |
| Workqueue | 工作队列 | 内核级线程管理机制,GCD 底层使用 |
| Priority Inversion | 优先级反转 | 高优先级线程等待低优先级线程释放锁 |
| Context Switch | 上下文切换 | CPU 从一个线程切换到另一个线程 |
| Memory Barrier | 内存屏障 | 防止指令重排,保证内存操作顺序 |
以上是 iOS 多线程完整知识体系,覆盖了概念、方案、锁、常见问题、源码和面试准备。可作为学习、复习和面试的系统性资料。如有任何修改或补充需求,请随时告知。