Binder线程池启动过程

基于Android U

在应用程序进程创建过程中会启动Binder线程池。

1
2
3
4
5
6
7
8
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
String[] argv, ClassLoader classLoader) {
...
ZygoteInit.nativeZygoteInit();
return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
classLoader);
}

nativeZygoteInit()会在新创建的应用程序进程中创建Binder线程池。

1
2
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
private static native void nativeZygoteInit();
1
2
3
4
5
frameworks/base/core/jni/AndroidRuntime.cpp
const JNINativeMethod methods[] = {
{ "nativeZygoteInit", "()V",
(void*) com_android_internal_os_ZygoteInit_nativeZygoteInit },
};

nativeZygoteInit()是一个JNI方法,它对应的函数是com_android_internal_os_ZygoteInit_nativeZygoteInit()。

1
2
3
4
5
frameworks/base/core/jni/AndroidRuntime.cpp
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
gCurRuntime->onZygoteInit();
}

gCurRuntime是AndroidRuntime类型的指针,它是在AndroidRuntime初始化时就创建的。

1
2
3
4
5
6
7
8
9
10
11
frameworks/base/core/jni/AndroidRuntime.cpp

static AndroidRuntime* gCurRuntime = NULL;
AndroidRuntime::AndroidRuntime(char* argBlockStart, const size_t argBlockLength) :
mExitWithoutCleanup(false),
mArgBlockStart(argBlockStart),
mArgBlockLength(argBlockLength)
{
...
gCurRuntime = this;
}

AppRuntime继承自AndroidRuntime,AppRuntime创建时就会调用AndroidRuntime的构造函数,gCurRuntime就会被初始化,它指向的是AppRuntime。AppRuntime在app_main.cpp中实现。

1
2
3
4
5
6
7
frameworks/base/cmds/app_process/app_main.cpp
virtual void onZygoteInit()
{
sp<ProcessState> proc = ProcessState::self();
ALOGV("App process: starting thread pool.\n");
proc->startThreadPool();
}

调用ProcessState#startThreadPool()来启动Binder线程池。

1
2
3
4
5
6
7
8
9
10
11
12
13
frameworks/native/libs/binder/ProcessState.cpp
void ProcessState::startThreadPool()
{
AutoMutex _l(mLock);
if (!mThreadPoolStarted) {
if (mMaxThreads == 0) { // 1
ALOGW("Extra binder thread started, but 0 threads requested. Do not use "
"*startThreadPool when zero threads are requested.");
}
mThreadPoolStarted = true; // 2
spawnPooledThread(true);
}
}

支持Binder通信的进程中都有一个ProcessState类,它里面有一个mThreadPoolStarted变量,用来表示Binder线程池是否已经被启动过,默认值为false。在每次调用startThreadPool()时都会在注释1处先检查这个标记,从而确保Binder线程池只会被启动一次。如果Binder线程池未被启动,则在注释2处设置mThreadPoolStarted为true,并调用spawnPooledThread()来创建线程池中的第一个线程,也就是线程池的主线程。

1
2
3
4
5
6
7
8
9
10
11
12
13
frameworks/native/libs/binder/ProcessState.cpp
void ProcessState::spawnPooledThread(bool isMain)
{
if (mThreadPoolStarted) {
String8 name = makeBinderThreadName();
ALOGV("Spawning new pooled thread, name=%s\n", name.string());
sp<Thread> t = sp<PoolThread>::make(isMain);
t->run(name.string()); // 1
pthread_mutex_lock(&mThreadCountLock);
mKernelStartedThreads++;
pthread_mutex_unlock(&mThreadCountLock);
}
}

可以看到Binder线程为一个PoolThread。在注释1处调用PoolThread#run()来启动一个新的线程。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
frameworks/native/libs/binder/ProcessState.cpp
class PoolThread : public Thread
{
public:
explicit PoolThread(bool isMain)
: mIsMain(isMain)
{
}

protected:
virtual bool threadLoop()
{
IPCThreadState::self()->joinThreadPool(mIsMain); // 1
return false;
}

const bool mIsMain;
};

PoolThread类继承了Thread类。在注释1处调用IPCThreadState#joinThreadPool(),将当前线程注册到Binder驱动程序中,这样我们创建的线程就加入了Binder线程池中,新创建的应用程序进程就支持Binder进程间通信了,我们只需要创建当前进程的Binder对象,并将它注册到ServiceManager中就可以实现Binder进程间通信。


Binder线程池启动过程
https://citrus-maxima.github.io/2024/03/10/Binder线程池启动过程/
作者
柚子树
发布于
2024年3月10日
许可协议