Binder线程池的启动
Binder线程池在Android是一个非常重要的技术,访问其它应用ContentProvider的,应用进程和系统服务之间的通信等操作在服务端是运行在Binder线程池中的。Binder线程池是一个比较底层的概念,关于Binder的代码在native层中:
../frameworks/native/libs/binder
接着APP进程的启动(见:APP进程启动流程),在ZygoteInit的zygoteInit(...)方法
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) {
...
//启动Binder线程池
ZygoteInit.nativeZygoteInit();
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}提到ZygoteInit的nativeZygoteInit()方法,该方法定义是native层的方法:
private static final native void nativeZygoteInit();进入AOSP的native源码目录找到binder,这里面定义了关于Binder线程池的顶层逻辑实现代码。ZygoteInit的nativeZygoteInit()方法经过JNI映射,调用到app_main.cpp中
virtual void onZygoteInit()
{
sp<ProcessState> proc = ProcessState::self();
ALOGV("App process: starting thread pool.\n");
proc->startThreadPool();
}ProcessState的self()方法返回单例
sp<ProcessState> ProcessState::self()
{
Mutex::Autolock _l(gProcessMutex);
if (gProcess != nullptr) {
return gProcess;
}
gProcess = new ProcessState(kDefaultDriver);
return gProcess;
}在onZygoteInit()方法中调用startThreadPool()方法
void ProcessState::startThreadPool()
{
AutoMutex _l(mLock);
if (!mThreadPoolStarted) {
mThreadPoolStarted = true;
spawnPooledThread(true);
}
}再调用spawnPooledThread(bool )方法
void ProcessState::spawnPooledThread(bool isMain)
{
if (mThreadPoolStarted) {
String8 name = makeBinderThreadName();
ALOGV("Spawning new pooled thread, name=%s\n", name.string());
sp<Thread> t = new PoolThread(isMain);
t->run(name.string());
}
}PoolThread类定义在ProcessState类中,继承自Thread线程
class PoolThread : public Thread
{
public:
explicit PoolThread(bool isMain)
: mIsMain(isMain)
{
}
protected:
virtual bool threadLoop()
{
IPCThreadState::self()->joinThreadPool(mIsMain);
return false;
}
const bool mIsMain;
};PoolThread的run(...)方法执行:先获取IPCThreadState单例,借助IPCThreadState::self()
IPCThreadState* IPCThreadState::self()
{
if (gHaveTLS) {
restart:
const pthread_key_t k = gTLS;
IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
if (st) return st;
return new IPCThreadState;
}
if (gShutdown) {
ALOGW("Calling IPCThreadState::self() during shutdown is dangerous, expect a crash.\n");
return nullptr;
}
pthread_mutex_lock(&gTLSMutex);
if (!gHaveTLS) {
int key_create_value = pthread_key_create(&gTLS, threadDestructor);
if (key_create_value != 0) {
pthread_mutex_unlock(&gTLSMutex);
ALOGW("IPCThreadState::self() unable to create TLS key, expect a crash: %s\n",
strerror(key_create_value));
return nullptr;
}
gHaveTLS = true;
}
pthread_mutex_unlock(&gTLSMutex);
goto restart;
}现在已经看不太懂C++语法(╥╯^╰╥) ,仿佛看到了goto跳转。该方法返回的IPCThreadState单实例
最后,调用joinThreadPool(bool isMain)方法将当前构造的Binder线程池注册到Binder驱动中。
void IPCThreadState::joinThreadPool(bool isMain)
{
LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid());
mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
status_t result;
do {
processPendingDerefs();
// now get the next command to be processed, waiting if necessary
result = getAndExecuteCommand();
if (result < NO_ERROR && result != TIMED_OUT && result != -ECONNREFUSED && result != -EBADF) {
ALOGE("getAndExecuteCommand(fd=%d) returned unexpected error %d, aborting",
mProcess->mDriverFD, result);
abort();
}
// 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);
LOG_THREADPOOL("**** THREAD %p (PID %d) IS LEAVING THE THREAD POOL err=%d\n",
(void*)pthread_self(), getpid(), result);
mOut.writeInt32(BC_EXIT_LOOPER);
talkWithDriver(false);
}创建的线程加入到Binder线程池中,应用程序启动之后就支持使用这个Binder线程进行进程间通信,至于Binder是如何实现进程间通信的,就无需再往下“刨”了,不求甚解。
学习资料:
Android进阶解密 > 第三章 Binder线程池启动过程

