Android Binder 线程模型
一、Binder 线程池架构
arduino
┌─────────────────────────────────────────────────────────────────┐
│ Client Process │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Main │ │ Binder │ │ Binder │ Binder Thread Pool │
│ │ Thread │ │ Thread 1 │ │ Thread 2 │ (Max 16 threads) │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
│ │ │ │ │
└───────┼────────────┼────────────┼───────────────────────────────┘
│ │ │
└────────────┴────────────┘
│
▼
┌────────────────────────┐
│ Binder Driver │
│ /dev/binder │
└────────────────────────┘
│
┌────────────┴────────────┐
│ │ │
┌───────┼────────────┼────────────┼───────────────────────────────┐
│ │ │ │ │
│ ┌────┴─────┐ ┌────┴─────┐ ┌────┴─────┐ │
│ │ Main │ │ Binder │ │ Binder │ Binder Thread Pool │
│ │ Thread │ │ Thread 1 │ │ Thread 2 │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ Server Process │
└─────────────────────────────────────────────────────────────────┘
二、核心数据结构
2.1 内核层数据结构
c
// 代表一个进程
struct binder_proc {
struct hlist_node proc_node; // 进程链表节点
struct rb_root threads; // 红黑树:该进程的所有binder线程
struct rb_root nodes; // 红黑树:该进程的所有binder实体
struct rb_root refs_by_desc; // 红黑树:该进程的所有binder引用
struct list_head waiting_threads; // 等待中的线程列表
struct list_head todo; // 待处理工作队列
int max_threads; // 最大线程数 (默认15+1主线程=16)
int requested_threads; // 请求创建的线程数
int requested_threads_started; // 已启动的线程数
int ready_threads; // 空闲线程数
struct binder_alloc alloc; // 内存分配器
// ...
};
// 代表一个线程
struct binder_thread {
struct binder_proc *proc; // 所属进程
struct rb_node rb_node; // 红黑树节点
struct list_head waiting_thread_node; // 等待线程链表节点
int pid; // 线程ID
int looper; // 线程状态标志
bool looper_need_return;
struct binder_transaction *transaction_stack; // 事务栈
struct list_head todo; // 线程私有待处理队列
wait_queue_head_t wait; // 等待队列头
// ...
};
// 代表一次事务
struct binder_transaction {
struct binder_work work; // 工作项
struct binder_thread *from; // 发送线程
struct binder_transaction *from_parent; // 父事务
struct binder_proc *to_proc; // 目标进程
struct binder_thread *to_thread; // 目标线程
struct binder_transaction *to_parent; // 目标父事务
unsigned int code; // 调用方法码
unsigned int flags; // 标志位
struct binder_buffer *buffer; // 数据缓冲区
// ...
};
// 线程状态标志
enum {
BINDER_LOOPER_STATE_REGISTERED = 0x01, // 已注册
BINDER_LOOPER_STATE_ENTERED = 0x02, // 主线程进入循环
BINDER_LOOPER_STATE_EXITED = 0x04, // 已退出
BINDER_LOOPER_STATE_INVALID = 0x08, // 无效
BINDER_LOOPER_STATE_WAITING = 0x10, // 等待中
BINDER_LOOPER_STATE_POLL = 0x20, // 在poll中
};
2.2 用户层数据结构
cpp
// ProcessState - 进程单例
class ProcessState {
int mDriverFD; // binder驱动文件描述符
void* mVMStart; // mmap映射区域起始地址
size_t mVMSize; // 映射大小 (默认1MB-8KB)
mutable Mutex mLock;
Vector<handle_entry> mHandleToObject; // handle到BpBinder的映射
int mMaxThreads; // 最大线程数
int mCurrentThreads; // 当前线程数
int mStarvationStartTimeMs; // 饥饿检测时间
};
// IPCThreadState - 线程单例 (TLS)
class IPCThreadState {
ProcessState* mProcess;
pid_t mMyThreadId;
int mLastError;
Parcel mIn; // 接收数据缓冲区
Parcel mOut; // 发送数据缓冲区
int mStrictModePolicy;
int32_t mCallingPid; // 调用者PID
int32_t mCallingUid; // 调用者UID
};
三、完整调用流程示例
场景:Client调用Server的add(1, 2)方法
scss
┌──────────────────┐ ┌──────────────────┐
│ Client Process │ │ Server Process │
│ │ │ │
│ ┌────────────┐ │ │ ┌────────────┐ │
│ │ Client │ │ │ │ Server │ │
│ │ Thread │ │ │ │ Thread │ │
│ └─────┬──────┘ │ │ └─────┬──────┘ │
│ │ │ │ │ │
└────────┼─────────┘ └────────┼─────────┘
│ │
│ ① transact() │ (waiting...)
▼ │
┌─────────────────────────────────────────────────────────┐
│ Binder Driver │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ binder_proc │ │ binder_proc │ │
│ │ (client) │ │ (server) │ │
│ │ │ │ │ │
│ │binder_thread│───────► │binder_thread│ │
│ │ (waiting) │ ②③④ │ (wakeup) │ │
│ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────┘
3.1 阶段一:Client 发起调用
cpp
// ======================== 用户空间 ========================
// Step 1: 应用调用代理方法
// 假设 ICalculator.aidl 定义了 add(int a, int b) 方法
int result = calculator->add(1, 2);
// Step 2: BpCalculator 打包数据
class BpCalculator : public BpInterface<ICalculator> {
int add(int a, int b) override {
Parcel data, reply;
data.writeInterfaceToken(ICalculator::getInterfaceDescriptor());
data.writeInt32(a); // 写入参数1
data.writeInt32(b); // 写入参数2
// 发起远程调用
remote()->transact(ADD_TRANSACTION, data, &reply);
return reply.readInt32();
}
};
// Step 3: BpBinder::transact
status_t BpBinder::transact(uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags) {
// 调用 IPCThreadState
return IPCThreadState::self()->transact(mHandle, code, data, reply, flags);
}
// Step 4: IPCThreadState::transact
status_t IPCThreadState::transact(int32_t handle, uint32_t code,
const Parcel& data, Parcel* reply,
uint32_t flags) {
// 写入命令到 mOut
writeTransactionData(BC_TRANSACTION, flags, handle, code, data, nullptr);
if ((flags & TF_ONE_WAY) == 0) { // 同步调用
// 等待返回
waitForResponse(reply);
} else { // 异步调用
waitForResponse(nullptr, nullptr);
}
return NO_ERROR;
}
// Step 5: 准备binder_transaction_data
status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,
int32_t handle, uint32_t code,
const Parcel& data, status_t* err) {
binder_transaction_data tr;
tr.target.handle = handle; // 目标 binder handle
tr.code = code; // 方法码 ADD_TRANSACTION
tr.flags = binderFlags;
tr.data_size = data.ipcDataSize();
tr.data.ptr.buffer = data.ipcData();
tr.offsets_size = data.ipcObjectsCount() * sizeof(binder_size_t);
tr.data.ptr.offsets = data.ipcObjects();
mOut.writeInt32(cmd); // BC_TRANSACTION
mOut.write(&tr, sizeof(tr));
return NO_ERROR;
}
// Step 6: 进入内核
status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult) {
while (1) {
talkWithDriver(); // 发送并等待
cmd = mIn.readInt32();
switch (cmd) {
case BR_TRANSACTION_COMPLETE:
// 事务已被接收,继续等待结果
break;
case BR_REPLY:
// 收到回复
binder_transaction_data tr;
mIn.read(&tr, sizeof(tr));
reply->ipcSetDataReference(...);
return NO_ERROR;
// 其他case...
}
}
}
// Step 7: 与驱动交互
status_t IPCThreadState::talkWithDriver(bool doReceive) {
binder_write_read bwr;
bwr.write_size = mOut.dataSize();
bwr.write_buffer = mOut.data();
bwr.read_size = mIn.dataCapacity();
bwr.read_buffer = mIn.data();
// 系统调用进入内核
ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr);
return NO_ERROR;
}
3.2 阶段二:Binder 驱动处理
c
// ======================== 内核空间 ========================
// Step 8: ioctl 入口
static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) {
struct binder_proc *proc = filp->private_data;
struct binder_thread *thread;
// 获取或创建 binder_thread
thread = binder_get_thread(proc);
switch (cmd) {
case BINDER_WRITE_READ:
ret = binder_ioctl_write_read(filp, cmd, arg, thread);
break;
// 其他命令...
}
return ret;
}
// Step 9: 处理 BINDER_WRITE_READ
static int binder_ioctl_write_read(struct file *filp, unsigned int cmd,
unsigned long arg, struct binder_thread *thread) {
struct binder_proc *proc = filp->private_data;
struct binder_write_read bwr;
copy_from_user(&bwr, ubuf, sizeof(bwr));
// 处理写入的命令 (BC_TRANSACTION)
if (bwr.write_size > 0) {
binder_thread_write(proc, thread, bwr.write_buffer,
bwr.write_size, &bwr.write_consumed);
}
// 等待并读取结果
if (bwr.read_size > 0) {
binder_thread_read(proc, thread, bwr.read_buffer,
bwr.read_size, &bwr.read_consumed,
filp->f_flags & O_NONBLOCK);
}
copy_to_user(ubuf, &bwr, sizeof(bwr));
return 0;
}
// Step 10: 处理 BC_TRANSACTION
static int binder_thread_write(struct binder_proc *proc,
struct binder_thread *thread,
binder_uintptr_t binder_buffer,
size_t size, binder_size_t *consumed) {
while (*consumed < size) {
uint32_t cmd;
get_user(cmd, (uint32_t __user *)ptr);
switch (cmd) {
case BC_TRANSACTION: {
struct binder_transaction_data tr;
copy_from_user(&tr, ptr, sizeof(tr));
binder_transaction(proc, thread, &tr,
cmd == BC_REPLY, 0);
break;
}
// 其他命令...
}
}
return 0;
}
// Step 11: 核心事务处理
static void binder_transaction(struct binder_proc *proc,
struct binder_thread *thread,
struct binder_transaction_data *tr,
int reply, binder_size_t extra_buffers_size) {
struct binder_transaction *t;
struct binder_proc *target_proc;
struct binder_thread *target_thread = NULL;
struct binder_node *target_node = NULL;
// ===== 1. 查找目标进程和目标节点 =====
if (reply) {
// BC_REPLY: 回复给原来的请求线程
in_reply_to = thread->transaction_stack;
target_thread = in_reply_to->from;
target_proc = target_thread->proc;
} else {
// BC_TRANSACTION: 新的请求
if (tr->target.handle) {
// 通过 handle 查找 binder_ref -> binder_node
struct binder_ref *ref;
ref = binder_get_ref_olocked(proc, tr->target.handle, true);
target_node = ref->node;
} else {
// handle=0 表示 ServiceManager
target_node = context->binder_context_mgr_node;
}
target_proc = target_node->proc;
}
// ===== 2. 选择目标线程 =====
if (!reply && !(tr->flags & TF_ONE_WAY)) {
// 同步调用: 尝试找到空闲线程或创建新线程
target_thread = binder_select_thread_ilocked(target_proc);
}
// ===== 3. 创建事务对象 =====
t = kzalloc(sizeof(*t), GFP_KERNEL);
t->from = thread; // 源线程
t->to_proc = target_proc; // 目标进程
t->to_thread = target_thread; // 目标线程
t->code = tr->code; // 方法码
t->flags = tr->flags;
// ===== 4. 在目标进程分配 buffer =====
// 这里使用 mmap 的共享内存区域
t->buffer = binder_alloc_new_buf(&target_proc->alloc,
tr->data_size,
tr->offsets_size,
extra_buffers_size,
!reply && (t->flags & TF_ONE_WAY));
// ===== 5. 拷贝数据 (只需一次拷贝!) =====
// 从 client 用户空间 -> server 内核映射区(也是server用户空间)
copy_from_user(t->buffer->data,
(void __user *)tr->data.ptr.buffer,
tr->data_size);
// ===== 6. 处理 Binder 对象 (flat_binder_object) =====
// 转换 binder 实体为引用,或引用为引用
off_end = (void *)t->buffer->data + t->buffer->data_size;
for (; offp < off_end; offp++) {
struct flat_binder_object *fp;
fp = (struct flat_binder_object *)(t->buffer->data + *offp);
switch (fp->hdr.type) {
case BINDER_TYPE_BINDER:
// Binder 实体 -> 创建 binder_node 和 binder_ref
ret = binder_translate_binder(fp, t, thread);
break;
case BINDER_TYPE_HANDLE:
// Binder 引用 -> 转换为目标进程的引用
ret = binder_translate_handle(fp, t, thread);
break;
case BINDER_TYPE_FD:
// 文件描述符 -> 在目标进程创建新 fd
ret = binder_translate_fd(fp, t, thread);
break;
}
}
// ===== 7. 设置事务栈 =====
if (!reply && !(t->flags & TF_ONE_WAY)) {
// 同步调用: 建立事务栈关系
t->from_parent = thread->transaction_stack;
thread->transaction_stack = t;
}
// ===== 8. 将事务放入目标队列 =====
t->work.type = BINDER_WORK_TRANSACTION;
if (target_thread) {
// 放入目标线程的私有队列
binder_enqueue_thread_work(target_thread, &t->work);
} else {
// 放入目标进程的公共队列
binder_enqueue_work(&t->work, &target_proc->todo);
}
// ===== 9. 发送 BR_TRANSACTION_COMPLETE 给发送方 =====
binder_enqueue_thread_work(thread, &tcomplete->work);
// ===== 10. 唤醒目标线程 =====
if (target_thread)
wake_up_interruptible(&target_thread->wait);
else
wake_up_interruptible(&target_proc->wait);
}
3.3 阶段三:Server 处理请求
cpp
// ======================== 用户空间 - Server端 ========================
// Step 12: Server 主线程或工作线程的循环
// 在 ProcessState::startThreadPool 启动后
void IPCThreadState::joinThreadPool(bool isMain) {
// 告诉驱动本线程进入循环
mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
status_t result;
do {
// 处理完成后将回复写回
processPendingDerefs();
// 从驱动获取命令
result = getAndExecuteCommand();
// 检查是否需要创建新线程
if (result == TIMED_OUT && !isMain) {
break; // 非主线程可以退出
}
} while (result != -ECONNREFUSED && result != -EBADF);
mOut.writeInt32(BC_EXIT_LOOPER);
talkWithDriver(false);
}
// Step 13: 执行命令
status_t IPCThreadState::getAndExecuteCommand() {
status_t result = talkWithDriver(); // 获取命令
if (result >= NO_ERROR) {
cmd = mIn.readInt32();
result = executeCommand(cmd);
}
return result;
}
// Step 14: 处理 BR_TRANSACTION
status_t IPCThreadState::executeCommand(int32_t cmd) {
switch (cmd) {
case BR_TRANSACTION: {
binder_transaction_data tr;
mIn.read(&tr, sizeof(tr));
// 保存调用者信息
mCallingPid = tr.sender_pid;
mCallingUid = tr.sender_euid;
Parcel buffer;
buffer.ipcSetDataReference(
reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
tr.data_size,
reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
tr.offsets_size / sizeof(binder_size_t),
freeBuffer, this);
Parcel reply;
// 找到对应的 BBinder 并调用
if (tr.target.ptr) {
// 这里是 BBinder 的地址
reinterpret_cast<BBinder*>(tr.cookie)->transact(
tr.code, buffer, &reply, tr.flags);
} else {
// Service Manager 的特殊处理
the_context_object->transact(tr.code, buffer, &reply, tr.flags);
}
// 发送回复
if ((tr.flags & TF_ONE_WAY) == 0) {
sendReply(reply, 0);
}
break;
}
case BR_SPAWN_LOOPER:
// 驱动请求创建新线程
mProcess->spawnPooledThread(false);
break;
// 其他命令...
}
return result;
}
// Step 15: BBinder::transact (分发到具体实现)
status_t BBinder::transact(uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags) {
switch (code) {
case INTERFACE_TRANSACTION:
reply->writeString16(getInterfaceDescriptor());
return NO_ERROR;
case DUMP_TRANSACTION:
// ...
default:
// 调用子类实现
return onTransact(code, data, reply, flags);
}
}
// Step 16: BnCalculator::onTransact (Server实现)
status_t BnCalculator::onTransact(uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags) {
switch (code) {
case ADD_TRANSACTION: {
CHECK_INTERFACE(ICalculator, data, reply);
int a = data.readInt32(); // 读取参数1
int b = data.readInt32(); // 读取参数2
int result = add(a, b); // 调用实际实现!!!
reply->writeInt32(result); // 写入结果
return NO_ERROR;
}
// 其他方法...
}
return BBinder::onTransact(code, data, reply, flags);
}
// Step 17: 发送回复
status_t IPCThreadState::sendReply(const Parcel& reply, uint32_t flags) {
status_t err;
writeTransactionData(BC_REPLY, flags, -1, 0, reply, &err);
return waitForResponse(nullptr, nullptr);
}
3.4 阶段四:Client 收到响应
c
// ======================== 回到内核 - 处理 BC_REPLY ========================
// Step 18: binder_transaction 处理 reply=true
static void binder_transaction(..., int reply, ...) {
// reply=true 时
in_reply_to = thread->transaction_stack;
target_thread = in_reply_to->from; // 原来的发送者
target_proc = target_thread->proc;
// 创建回复事务
t = kzalloc(sizeof(*t), GFP_KERNEL);
t->from = thread;
t->to_proc = target_proc;
t->to_thread = target_thread;
// 分配 buffer 并拷贝回复数据
t->buffer = binder_alloc_new_buf(&target_proc->alloc, ...);
copy_from_user(t->buffer->data, ...);
// 清理事务栈
thread->transaction_stack = in_reply_to->to_parent;
target_thread->transaction_stack = in_reply_to->from_parent;
// 将回复放入原发送线程的队列
binder_enqueue_thread_work(target_thread, &t->work);
// 唤醒原发送线程 (Client线程)
wake_up_interruptible(&target_thread->wait);
// 释放原事务
binder_free_transaction(in_reply_to);
}
cpp
// ======================== 回到用户空间 - Client 端 ========================
// Step 19: Client 线程被唤醒
// 在 waitForResponse 中继续执行
status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult) {
while (1) {
talkWithDriver();
cmd = mIn.readInt32();
switch (cmd) {
case BR_REPLY: {
binder_transaction_data tr;
mIn.read(&tr, sizeof(tr));
if (reply) {
// 设置回复数据引用 (零拷贝)
reply->ipcSetDataReference(
reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
tr.data_size, ...);
}
return NO_ERROR; // 返回!!!
}
}
}
}
// Step 20: 回到 BpCalculator::add
int result = reply.readInt32(); // 读取结果 = 3
return result; // 返回给应用
四、线程管理机制
4.1 线程创建时机
ruby
┌─────────────────────────────────────────────────────────────┐
│ 线程创建决策流程 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 有新请求到达 ─────┐ │
│ ▼ │
│ ┌───────────────┐ │
│ │ 是否有空闲线程?│ │
│ └───────┬───────┘ │
│ │ │
│ ┌────Yes──┴──No────┐ │
│ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────────┐ │
│ │ 唤醒空闲线程 │ │ 是否达到最大线程? │ │
│ └─────────────┘ └────────┬────────┘ │
│ │ │
│ ┌────Yes──┴──No────┐ │
│ ▼ ▼ │
│ ┌───────────┐ ┌───────────────┐ │
│ │ 放入进程 │ │ 发送 │ │
│ │ 公共队列 │ │ BR_SPAWN_LOOPER│ │
│ └───────────┘ └───────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────┐ │
│ │ 创建新Binder │ │
│ │ 工作线程 │ │
│ └───────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
4.2 线程选择算法
c
// 内核中选择目标线程
static struct binder_thread *binder_select_thread_ilocked(
struct binder_proc *proc) {
struct binder_thread *thread;
// 优先选择 waiting_threads 列表中的线程
// 这些线程正在 binder_thread_read 中等待
thread = list_first_entry_or_null(&proc->waiting_threads,
struct binder_thread,
waiting_thread_node);
if (thread) {
list_del_init(&thread->waiting_thread_node);
}
// 如果没有空闲线程,考虑请求新建线程
if (!thread && proc->ready_threads == 0 &&
proc->requested_threads == 0 &&
proc->requested_threads_started < proc->max_threads) {
proc->requested_threads++;
// 稍后会发送 BR_SPAWN_LOOPER
}
return thread;
}
4.3 线程池配置
cpp
// 用户层配置
void ProcessState::setThreadPoolMaxThreadCount(size_t maxThreads) {
mMaxThreads = maxThreads;
// 通知驱动
ioctl(mDriverFD, BINDER_SET_MAX_THREADS, &maxThreads);
}
// 默认值
// frameworks/native/libs/binder/ProcessState.cpp
#define DEFAULT_MAX_BINDER_THREADS 15 // + 1个主线程 = 16
五、完整时序图
scss
Client Binder Driver Server
│ │ │
│ BC_TRANSACTION │ │
│ ───────────────────────>│ │
│ │ │
│ │ 创建binder_transaction │
│ │ 拷贝数据到共享内存 │
│ │ 放入server todo队列 │
│ │ │
│ BR_TRANSACTION_COMPLETE│ │
│ <───────────────────────│ │
│ │ │
│ │ BR_TRANSACTION │
│ (等待中) │ ───────────────────────>│
│ ┆ │ │
│ ┆ │ │ 处理请求
│ ┆ │ │ 调用add(1,2)
│ ┆ │ │
│ ┆ │ BC_REPLY │
│ ┆ │ <───────────────────────│
│ ┆ │ │
│ ┆ │ BR_TRANSACTION_COMPLETE│
│ ┆ │ ───────────────────────>│
│ │ │
│ BR_REPLY │ │
│ <───────────────────────│ │
│ │ │
│ 读取结果(3) │ │
│ │ │
▼ ▼ ▼
六、关键设计总结
| 特性 | 说明 |
|---|---|
| 线程池 | 每进程最大16个Binder线程,按需动态创建 |
| 一次拷贝 | mmap共享内存,数据只从发送方拷贝到共享区 |
| 同步等待 | 发送线程睡眠等待回复,事务栈记录调用关系 |
| 线程唤醒 | 目标线程从等待队列唤醒处理请求 |
| 负载均衡 | 优先复用空闲线程,必要时创建新线程 |
| TLS | IPCThreadState为线程本地存储,每线程独立 |
这就是 Binder 线程模型的完整工作机制!