1.png

主线程与普通线程

Binder 线程可以分为两类:主线程普通线程,它们的区别是:

  1. 主线程名称为 Binder_1 or Binder:<pid>_1,普通线程则从 2 开始(ProcessState::makeBinderThreadName
  2. 主线程在应用进程起来后立刻启动,且不会退出;普通线程由 BR_SPAWN_LOOPER 启动且会被 binder driver 命令 TIMED_OUT 退出(IPCThreadState::joinThreadPool
  3. binder 线程上限(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 线程命名

创建普通线程

流程概览:binder driver 在满足以下条件的情况下,发送 BR_SPAWN_LOOPER 给应用进程,应用进程开启新线程 ProcessState::spawnPooledThread(false) 后,发送 BC_REGISTER_LOOPER 告知 binder driver 线程已启动

有三种情况可以进入 binder_thread_read done 代码段:

  1. 当 binder driver 处理类型为 BINDER_WORK_TRANSACTION 的任务,即 binder driver 收到的命令是 BC_TRANSACTION(client 发送 request 至 binder) or BC_REPLY(server 响应 response 至 binder)
  2. 当前线程的 return_error 发生 error
  3. Binder Driver 向 client 发送死亡通知 BR_DEAD_BINDER

按需启动普通 binder 线程的条件:

  1. 进程没有请求创建 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 置假

  1. 没有等待/阻塞在进程 todo list 的 client thread,list_empty(&thread->proc->waiting_threads)

@waiting_threads: threads currently waiting for proc work

参考 client 线程调度例子 里的 binder_wait_for_work

  1. 已启动的 binder 线程数小于上限,proc->requested_threads_started < proc->max_threads

binder 线程池上限默认 15,可通过 BINDER_SET_MAX_THREADS 修改

  1. 当前线程已从应用进程收到 BC_ENTER_LOOPER or BC_REGISTER_LOOPERthread->looper & (BINDER_LOOPER_STATE_REGISTERED | BINDER_LOOPER_STATE_ENTERED)

参考 主线程与普通线程