
Binder 线程可以分为两类:主线程 和 普通线程,它们的区别是:
Binder_1 or Binder:<pid>_1,普通线程则从 2 开始(ProcessState::makeBinderThreadName)TIMED_OUT 退出(IPCThreadState::joinThreadPool)BINDER_SET_MAX_THREADS)只影响普通线程,更确切地说是只影响通过 BR_SPAWN_LOOPER - BC_REGISTER_LOOPER 创建的 binder 线程Binder 主线程是在其所在进程的初始化流程里启动的,Java 层进程的创建都是通过 Process.start() 方法,向 Zygote 进程发出创建进程的 socket 消息,Zygote 进程收到消息后会调用 Zygote.forkAndSpecialize() 来 fork 出新进程,在新进程中会调用到 RuntimeInit.nativeZygoteInit() 方法,该方法经过 jni 映射最终会调用到 app_main.cpp 中的 onZygoteInit,那么接下来从这个方法说起
/**
* The main function called when started through the zygote process. This could be unified with
* main(), if the native code in nativeFinishInit() were rationalized with Zygote startup.
*/
public static Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
String[] argv, ClassLoader classLoader) {
// ...
ZygoteInit.nativeZygoteInit();
return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
classLoader);
}
// <https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/jni/AndroidRuntime.cpp>
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
gCurRuntime->onZygoteInit(); // AppRuntime->onZygoteInit()
}
// <https://cs.android.com/android/platform/superproject/+/master:frameworks/base/cmds/app_process/app_main.cpp>
virtual void onZygoteInit()
{
// 上面介绍过,ProcessState 是单例模式,初始化实例时会:
// 1,打开 binder driver:open("/dev/binder") && mmap
// 2,版本查询和校验:BINDER_VERSION
// 3,设置线程数:BINDER_SET_MAX_THREADS
// ...
sp<ProcessState> proc = ProcessState::self();
ALOGV("App process: starting thread pool.\\\\n");
proc->startThreadPool();
}
// 开启 binder 主线程执行 binder 消息通讯的 loop:IPCThreadState::self()->joinThreadPool = talkWithDriver + executeCommand
// <https://cs.android.com/android/platform/superproject/+/master:frameworks/native/libs/binder/ProcessState.cpp>
void ProcessState::startThreadPool()
{
AutoMutex _l(mLock);
if (!mThreadPoolStarted) {
mThreadPoolStarted = true;
spawnPooledThread(true);
}
}
// spawn - 产卵
// spawnPooledThread 是创建 binder 线程的核心函数,它创建新线程执行 IPCThreadState::joinThreadPool
// 新的 binder 线程的生命流程:
// 1,往 binder 发送 BC_ENTER_LOOPER(主线程) or BC_REGISTER_LOOPER(普通线程)
// 2. 主循环:getAndExecuteCommand()
// 3. 退出循环时发送 BC_EXIT_LOOPER 给 binder driver
void ProcessState::spawnPooledThread(bool isMain /* true 表示主线程 */)
{
if (mThreadPoolStarted) {
String8 name = makeBinderThreadName(); // Binder_x or Binder:<pid>_x
ALOGV("Spawning new pooled thread, name=%s\\\\n", name.string());
sp<Thread> t = sp<PoolThread>::make(isMain);
t->run(name.string());
pthread_mutex_lock(&mThreadCountLock);
mKernelStartedThreads++;
pthread_mutex_unlock(&mThreadCountLock);
}
}
class PoolThread : public Thread
{
virtual bool threadLoop()
{
IPCThreadState::self()->joinThreadPool(mIsMain);
return false;
}
};
void IPCThreadState::joinThreadPool(bool isMain) // binder 线程的整个生命流程
{
mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
status_t result;
mIsLooper = true;
do {
processPendingDerefs();
// now get the next command to be processed, waiting if necessary
result = getAndExecuteCommand();
// Let this thread exit the thread pool if it is no longer
// needed and it is not the main process thread.
if(result == TIMED_OUT && !isMain) { // 可以看到主线程与普通线程的区别之一:主线程永远不会主动退出
break;
}
} while (result != -ECONNREFUSED && result != -EBADF);
mOut.writeInt32(BC_EXIT_LOOPER);
mIsLooper = false;
talkWithDriver(false);
}
// 主线程注册(BC_REGISTER_LOOPER)和普通线程注册(BC_ENTER_LOOPER)很类似
// 都是打开标志位 BINDER_LOOPER_STATE_ENTERED or BINDER_LOOPER_STATE_REGISTERED
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)
{
case BC_REGISTER_LOOPER:
binder_inner_proc_lock(proc);
if (thread->looper & BINDER_LOOPER_STATE_ENTERED) {
thread->looper |= BINDER_LOOPER_STATE_INVALID;
binder_user_error("%d:%d ERROR: BC_REGISTER_LOOPER called after BC_ENTER_LOOPER\\\\n",
proc->pid, thread->pid);
} else if (proc->requested_threads == 0) {
thread->looper |= BINDER_LOOPER_STATE_INVALID;
binder_user_error("%d:%d ERROR: BC_REGISTER_LOOPER called without request\\\\n",
proc->pid, thread->pid);
} else {
proc->requested_threads--;
proc->requested_threads_started++;
}
thread->looper |= BINDER_LOOPER_STATE_REGISTERED;
binder_inner_proc_unlock(proc);
break;
case BC_ENTER_LOOPER:
if (thread->looper & BINDER_LOOPER_STATE_REGISTERED) {
thread->looper |= BINDER_LOOPER_STATE_INVALID;
binder_user_error("%d:%d ERROR: BC_ENTER_LOOPER called after BC_REGISTER_LOOPER\\\\n",
proc->pid, thread->pid);
}
thread->looper |= BINDER_LOOPER_STATE_ENTERED;
break;
}
// binder 线程命名规则:Binder_x(如果 >= Android N 则是 Binder:<pid>_x)
// 其中的 x 从 1 开始
// <https://cs.android.com/android/platform/superproject/+/master:frameworks/native/libs/binder/ProcessState.cpp>
String8 ProcessState::makeBinderThreadName() {
int32_t s = android_atomic_add(1, &mThreadPoolSeq);
pid_t pid = getpid();
std::string_view driverName = mDriverName.c_str();
android::base::ConsumePrefix(&driverName, "/dev/");
String8 name;
name.appendFormat("%.*s:%d_%X", static_cast<int>(driverName.length()), driverName.data(), pid,
s);
return name;
}
ProcessState::ProcessState(const char* driver)
: mDriverName(String8(driver)),
mDriverFD(-1),
mVMStart(MAP_FAILED),
mThreadCountLock(PTHREAD_MUTEX_INITIALIZER),
mThreadCountDecrement(PTHREAD_COND_INITIALIZER),
mExecutingThreadsCount(0),
mWaitingForThreads(0),
mMaxThreads(DEFAULT_MAX_BINDER_THREADS),
mCurrentThreads(0),
mKernelStartedThreads(0),
mStarvationStartTimeMs(0),
mForked(false),
mThreadPoolStarted(false),
mThreadPoolSeq(1), // binder 线程名的序号从 1 开始
mCallRestriction(CallRestriction::NONE) {
// ...
}
流程概览:binder driver 在满足以下条件的情况下,发送 BR_SPAWN_LOOPER 给应用进程,应用进程开启新线程 ProcessState::spawnPooledThread(false) 后,发送 BC_REGISTER_LOOPER 告知 binder driver 线程已启动
有三种情况可以进入 binder_thread_read done 代码段:
BINDER_WORK_TRANSACTION 的任务,即 binder driver 收到的命令是 BC_TRANSACTION(client 发送 request 至 binder) or BC_REPLY(server 响应 response 至 binder)BR_DEAD_BINDER按需启动普通 binder 线程的条件:
proc->requested_threads == 0@requested_threads: number of binder threads requested but not yet started. In current implementation, can only be 0 or 1.
binder 发送 BR_SPAWN_LOOPER 给应用进程后将 requested_threads 置真,直到应用进程将新线程启动并回复 BC_REGISTER_LOOPER 后才将 requested_threads 置假
list_empty(&thread->proc->waiting_threads)@waiting_threads: threads currently waiting for proc work
参考 client 线程调度例子 里的 binder_wait_for_work
proc->requested_threads_started < proc->max_threadsbinder 线程池上限默认 15,可通过 BINDER_SET_MAX_THREADS 修改
BC_ENTER_LOOPER or BC_REGISTER_LOOPER,thread->looper & (BINDER_LOOPER_STATE_REGISTERED | BINDER_LOOPER_STATE_ENTERED)参考 主线程与普通线程