1. Binder 线程池概述

Binder 是 AOSP 中进程间通信(IPC)的基石,而 Binder 线程池 则是驱动 Binder 通信高效运转的核心调度单元。本章将围绕线程池的定位、默认配置、与 Binder 驱动的协作机制展开,并给出全局架构示意图,为后续调优打下基础。

1.1 线程池核心作用

Binder 线程池在 Native 层(libbinder)和 Framework 层(Java Binder)中统一管理用于处理跨进程请求的工作线程。其核心职责包括:

  • 请求分发:将从 Binder 驱动收到的 BC_TRANSACTION / BC_REPLY 数据包交付给注册的 Service 处理。
  • 并发控制:通过池化线程限制并发请求数,防止服务端上下文过度切换。
  • 生命周期管理:按需创建、销毁线程,并维持主线程(Binder_1)的稳定存活。
  • 优先级继承:配合驱动完成实时性保障,避免优先级反转。
关键认知:Binder 线程池不直接参与数据传输,而是负责驱动侧事件(等待 ioctl 返回)到用户态回调函数的转换。池中每个线程均与驱动中的一块 binder_thread 结构体一一对应。

1.2 默认配置

AOSP 原生代码中,Binder 线程池的默认参数由 ProcessState 类(Native 层)和 BinderInternal(Java 层)定义。核心阈值如下:

参数名 默认值 说明
BINDER_CORE_MAX 15 最大工作线程数(含主线程)
binder_max_threads 15 驱动侧允许的最大线程数,与 BINDER_CORE_MAX 一致
BINDER_MIN_THREADS 1 线程池常驻的最小线程数(主线程)
BC_ACCEPT 模式 开启 线程池在空闲时主动挂起,减少轮询开销

默认配置通过以下 Native 初始化代码加载:

// frameworks/native/libs/binder/ProcessState.cpp
ProcessState::self()->setThreadPoolMaxThreadCount(15);
// 驱动侧通过 /sys/module/binder/parameters/ 亦可查询
adb shell cat /sys/module/binder/parameters/binder_max_threads
# 输出: 15
注意:此处“最大线程数”并非硬上限。当所有线程都被占用时,Binder 驱动会在内核态排队等待,直到线程池释放出空闲线程。若队列积累过高则可能导致 ANR。

1.3 与 Binder 驱动的交互关系

线程池与 Binder 驱动的协作遵循以下流程:

  1. 应用进程调用 ProcessState::startThreadPool(),创建 Binder_1 主线程。
  2. 线程执行 IPCThreadState::joinThreadPool(),通过 ioctl(fd, BINDER_WRITE_READ, &bwr) 进入内核态等待。
  3. 驱动检测到新请求时,激活线程;若所有线程忙碌,驱动通过 BC_ENTER_LOOPER / BC_REGISTER_LOOPER 指令通知线程池扩容。
  4. 线程池收到扩容指令后,在用户态创建新线程(最大不超过 BINDER_CORE_MAX)。
  5. 线程空闲超过阈值,驱动发送 BC_EXIT_LOOPER,线程池回收多余线程。

以下是驱动与线程池之间关键交互指令的对应关系:

驱动指令 线程池响应 影响
BC_ENTER_LOOPER 线程就绪可接收请求 主线程长期保持
BC_REGISTER_LOOPER 创建新工作线程 扩容行为
BC_EXIT_LOOPER 线程结束自身循环 缩容行为

1.4 架构示意图

Binder 线程池架构示意图 客户端进程 (Client) Binder 线程池 主线程 工作线程1 工作线程2 工作线程N N ≤ BINDER_CORE_MAX (15) ioctl(BINDER_WRITE_READ) Binder 驱动 (kernel) binder_thread 结构体池 binder_proc / binder_node 待处理事务队列 (todo list) BC_TRANSACTION 回调 服务端进程 (Server) onTransact() 回调分发 ServiceManager 注册回调 说明: 线程池通过 ioctl 与驱动交互;驱动采用 BC_ACCEPT 模式在无请求时挂起线程;binder_thread 数量受 binder_max_threads 限制(默认15)。

1.5 架构分层说明

从上述架构图可以看出,Binder 线程池处于 用户态(Client/Server) 和 内核态(Binder Driver) 之间的桥梁位置。关键分层特征如下:

  • 用户态线程池:负责线程创建、销毁、优先级设置,以及 IPCThreadState 的循环调度。
  • 内核态线程表示:驱动中仅维护 binder_thread 结构体,不直接参与线程生命周期管理。驱动通过 BC_REGISTER_LOOPER 等指令间接控制线程数量。
  • 数据流:Client 调用 transact() → 用户态写入 BINDER_WRITE_READ → 驱动解包 → 驱动查找 binder_ref → 驱动将事务附加到目标进程的 todo 队列 → Server 空闲线程被唤醒 → 执行 onTransact()。