一、GCD 队列底层原理
1.1 队列类型
- 串行队列:一次只执行一个任务。
- 并发队列:可以并发执行多个任务。
- 主队列:主线程的串行队列,用于更新 UI。
1.2 队列背后的线程
- GCD 使用 线程池 管理线程,具体由 libdispatch + pthread 实现。
- 并发队列任务实际是串行调度、并发执行(由系统根据线程池和资源自动调度)。
二、常见 GCD 高级用法
2.1 dispatch_barrier(栅栏函数)
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 
 | dispatch_queue_t queue = dispatch_queue_create("com.example.queue", DISPATCH_QUEUE_CONCURRENT);
 dispatch_async(queue, ^{
 
 });
 
 dispatch_barrier_async(queue, ^{
 
 });
 
 dispatch_async(queue, ^{
 
 });
 
 | 
2.2 dispatch_group(任务组)
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 
 | dispatch_group_t group = dispatch_group_create();dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
 
 dispatch_group_async(group, queue, ^{
 
 });
 
 dispatch_group_async(group, queue, ^{
 
 });
 
 dispatch_group_notify(group, dispatch_get_main_queue(), ^{
 
 });
 
 | 
2.3 dispatch_semaphore(信号量)
| 12
 3
 4
 5
 6
 7
 
 | dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
 dispatch_async(queue, ^{
 dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
 
 dispatch_semaphore_signal(semaphore);
 });
 
 | 
三、避免死锁与优雅使用
3.1 死锁示例(主队列同步调用)
| 12
 3
 
 | dispatch_sync(dispatch_get_main_queue(), ^{
 });
 
 | 
3.2 dispatch_once(线程安全的单例初始化)
| 12
 3
 4
 
 | static dispatch_once_t onceToken;dispatch_once(&onceToken, ^{
 
 });
 
 | 
四、GCD 优化技巧与实践
4.1 控制最大并发数(结合 semaphore)
| 12
 3
 4
 5
 6
 7
 8
 
 | dispatch_semaphore_t sema = dispatch_semaphore_create(3);for (int i = 0; i < 10; i++) {
 dispatch_async(queue, ^{
 dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
 
 dispatch_semaphore_signal(sema);
 });
 }
 
 | 
4.2 使用 QoS(服务质量)
| 12
 
 | dispatch_queue_attr_t attr = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_CONCURRENT, QOS_CLASS_USER_INITIATED, 0);dispatch_queue_t queue = dispatch_queue_create("com.example.qosqueue", attr);
 
 | 
五、和 NSOperation 比较
| 特性 | GCD | NSOperation | 
| 简洁性 | ✅ | ❌(更复杂) | 
| 依赖管理 | ❌ | ✅(operation.addDependency) | 
| 取消任务 | ❌ | ✅(operation.cancel) | 
| 重用性/扩展性 | ❌ | ✅(子类化) | 
| 并发控制(数量) | 借助 semaphore | ✅(maxConcurrentOperationCount) | 
GCD 的底层实现原理
Grand Central Dispatch(GCD)是苹果提供的一个多线程并发编程框架,其底层实现原理可以从几个关键的技术点来理解,包括:
一、核心结构与实现基础
1. GCD 基于 libdispatch 实现
GCD 的底层是开源的 libdispatch 库,核心用 C 和 C++ 编写,运行在系统内核之上,封装了线程调度、任务分发、队列管理等功能。
二、任务与队列模型
1. 任务:Block 形式的封装代码(实质是闭包)
每个任务是一个 dispatch_block_t,本质是封装在结构体中的函数指针和上下文数据。
2. 队列:串行 or 并发
- 串行队列:任务一个个顺序执行。
- 并发队列:任务可同时执行,具体是否并行取决于系统资源。
底层由结构体 dispatch_queue_s 表示,内部包含:
- 队列名称
- 优先级(QoS)
- Target Queue(用于继承行为)
- 队列状态(是否正在执行任务)
- 队列类型(串行/并发)
三、线程调度原理
1. 线程池机制
GCD 不直接创建线程,而是复用一个系统管理的线程池(Managed Thread Pool):
- Apple 使用内核的 pthread和kqueue机制动态创建和调度线程。
- 调用 dispatch_async等方法时任务进入队列,等待调度器(libdispatch)判断是否需要从线程池中取线程执行。
2. 结合内核的调度器
- 使用 XNU 内核提供的 workloop(基于 kqueue)来监视队列变化。
- 利用信号量、原子操作、互斥锁控制任务同步。
四、队列的调度机制
1. dispatch_async / dispatch_sync 的区别
| 方法 | 调度行为 | 是否阻塞线程 | 
| dispatch_async | 异步入队 | 否 | 
| dispatch_sync | 同步执行,当前线程等待任务完成 | 是 | 
底层通过:
- dispatch_async:创建任务对象 -> 放入目标队列 -> 唤醒线程池中的线程处理
- dispatch_sync:直接调用任务,并使用- semaphore阻塞当前线程,直到任务执行完
五、QoS(服务质量)控制
GCD 支持 QoS(Quality of Service)等级,例如:
- userInteractive(最高)
- userInitiated
- default
- utility
- background(最低)
这些优先级通过底层设置线程调度属性,在内核中会影响线程抢占和执行顺序。
六、关键数据结构(源码角度)
1. dispatch_queue_s(队列结构体)
包含:
| 12
 3
 4
 5
 6
 7
 
 | struct dispatch_queue_s {...
 dispatch_object_t _head;
 dispatch_object_t _tail;
 pthread_priority_t _priority;
 ...
 };
 
 | 
2. dispatch_continuation_s(封装 block 的任务结构体)
| 12
 3
 4
 5
 
 | struct dispatch_continuation_s {void *dc_func;
 void *dc_ctxt;
 ...
 };
 
 | 
七、并发控制:信号量、栅栏、组
- dispatch_semaphore:底层基于- semaphore_t(Mach 信号量)
- dispatch_barrier:写操作时阻塞其他任务,底层使用任务依赖和标记机制实现
- dispatch_group:通过计数器追踪任务组状态,配合信号量实现通知
总结
GCD 是基于 libdispatch 构建的线程池 + 队列调度框架,其核心优势包括:
- 高效的线程复用
- 简洁的 API 封装(block)
- 动态优先级管理(QoS)
- 底层结合内核机制(如 kqueue 和 pthread)