08 — 线程与任务调度
Chrome 的线程模型围绕一个目标:保持响应性。UI 线程、IO 线程和 Renderer 主线程都不能被长任务随便阻塞。
常见线程
- Browser UI 线程:处理窗口、标签、用户交互等。
- Browser IO 线程:处理部分 IPC、网络和异步 IO 相关工作。
- Renderer 主线程:运行 Blink 主流程,包括 JS、DOM、样式、布局等。
- 合成线程:处理合成、滚动、动画等。
- ThreadPool:承载后台计算和阻塞任务。
Task 和 Sequence
Chrome 偏好用 task 组织异步工作。
- Task:一段要执行的闭包。
- Sequence:逻辑上的串行执行队列,同一 sequence 内任务按顺序执行。
- SequencedTaskRunner:保证任务顺序。
- SingleThreadTaskRunner:保证在固定物理线程执行。
重点:Chrome 更偏好 sequence,而不是到处创建线程或加锁。
为什么不能阻塞 UI / IO 线程
UI 线程阻塞会直接造成界面卡顿。
IO 线程阻塞会拖慢 IPC、Mojo、网络等跨进程通信,影响面很广。
Renderer 主线程阻塞会造成 JS、布局、事件处理和渲染更新卡顿。
并发原则
- 能异步就不要同步等待。
- 重任务丢到 ThreadPool。
- 同一个对象尽量固定在同一个 sequence 使用。
- 跨线程通信优先消息传递,少共享可变状态。
总结
Chrome 通过 task、sequence、线程池和专用线程管理并发。核心不是“线程越多越好”,而是把工作放到正确的队列上,避免阻塞 UI、IO 和 Renderer 主线程。