在android系统中,经过binder进行IPC时,服务端老是会起一些Binder线程来响应客户端的请求。以下面的这个设备上,system_process进程中就能够看到许多名为"Binder_X"的线程:java
那这些Binder线程又是如何建立,如何管理的呢?而这些Binder线程自己又有些什么样的特色呢?在android的java app进程被建立起来时,它就会去创建一个线程池,来专门处理那些binder IPC事务。在frameworks/base/cmds/app_process/app_main.cpp中咱们能够看到下面的这两个方法:android
virtual void onStarted() { sp<ProcessState> proc = ProcessState::self(); ALOGV("App process: starting thread pool.\n"); proc->startThreadPool(); AndroidRuntime* ar = AndroidRuntime::getRuntime(); ar->callMain(mClassName, mClass, mArgC, mArgV); IPCThreadState::self()->stopProcess(); } virtual void onZygoteInit() { // Re-enable tracing now that we're no longer in Zygote. atrace_set_tracing_enabled(true); sp<ProcessState> proc = ProcessState::self(); ALOGV("App process: starting thread pool.\n"); proc->startThreadPool(); }
app_main实际上就是android java app的java命令。这里的代码老是一个android java app执行控制的重要的枢纽。大致扫一眼这个部分的code,没错,就是上面的proc->startThreadPool()这个调用建立的Binder线程池。在android binder的设计中,ProcessState被设计来直接与binder驱动进行通讯。ProcessState类被按照单例模式来设计,以确保这种类的对象能够保证在进程的全局是惟一的。它的构造函数是private,在代码中只能经过ProcessState::self()来访问ProcessState类的对象。咱们顺便来看一下ProcessState::self()的实现(frameworks/native/libs/binder/ProcessState.cpp):
app
sp<ProcessState> ProcessState::self() { Mutex::Autolock _l(gProcessMutex); if (gProcess != NULL) { return gProcess; } gProcess = new ProcessState; return gProcess; }
蛮典型的一个C++单例模式的一个实现呢。那在ProcessState::startThreadPool()中又是如何建立线程池的呢?(frameworks/native/libs/binder/ProcessState.cpp)函数
void ProcessState::startThreadPool() { AutoMutex _l(mLock); if (!mThreadPoolStarted) { mThreadPoolStarted = true; spawnPooledThread(true); } }
这里会经过一个标记mThreadPoolStarted来代表binder线程线程池是否已经被启动过。在每次调用这个函数时都会先去检查这个标记,从而确保即便这个函数被屡次调用,线程池也只会被启动一次。具体来看启动线程池的过程:设置mThreadPoolStarted为true,而后调用spawnPooledThread(true)来建立线程池中的第一个线程,也就是线程池的main线程。oop
那binder线程具体又是什么呢?能够看spawnPooledThread()的实现(frameworks/native/libs/binder/ProcessState.cpp):this
String8 ProcessState::makeBinderThreadName() { int32_t s = android_atomic_add(1, &mThreadPoolSeq); String8 name; name.appendFormat("Binder_%X", s); return name; } 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()); } } ProcessState::ProcessState() : mDriverFD(open_driver()) , mVMStart(MAP_FAILED) , mManagesContexts(false) , mBinderContextCheckFunc(NULL) , mBinderContextUserData(NULL) , mThreadPoolStarted(false) , mThreadPoolSeq(1) {
能够看到,所谓的binder线程,不过就是PoolThread而已。在进程全局且惟一的ProcessState对象中,有一个已经建立的binder线程的计数器mThreadPoolSeq,每建立一个新的线程,这个计数器就会加1。在ProcessState::makeBinderThreadName()函数中,会根据当前的binder线程计数器的值来构造新建立的binder线程的线程名"Binder_%X",从而能够根据线程名来识别各个不一样的binder线程。atom
那PoolThread具体又有些什么特色呢?这个仍是得看PoolThread的threadLoop()方法实现(frameworks/native/libs/binder/ProcessState.cpp):spa
class PoolThread : public Thread { public: PoolThread(bool isMain) : mIsMain(isMain) { } protected: virtual bool threadLoop() { IPCThreadState::self()->joinThreadPool(mIsMain); return false; } const bool mIsMain; };
这个却是简单的很,就是调用IPCThreadState::self()->joinThreadPool(mIsMain)而已。线程
在android binder设计中,IPCThreadState是一个binder线程的一个抽象,用于管理binder线程的具体执行。这个类被设计为,其对象在每一个binder线程中惟一。为了控制这个类的对象的建立,其构造函数也被声明为private,而且只能经过IPCThreadState::self()来建立或访问IPCThreadState类的对象(frameworks/native/libs/binder/IPCThreadState.cpp):设计
static pthread_mutex_t gTLSMutex = PTHREAD_MUTEX_INITIALIZER; static bool gHaveTLS = false; static pthread_key_t gTLS = 0; static bool gShutdown = false; static bool gDisableBackgroundScheduling = false;
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) return NULL; pthread_mutex_lock(&gTLSMutex); if (!gHaveTLS) { if (pthread_key_create(&gTLS, threadDestructor) != 0) { pthread_mutex_unlock(&gTLSMutex); return NULL; } gHaveTLS = true; } pthread_mutex_unlock(&gTLSMutex); goto restart; }
IPCThreadState::self()函数在第一次被调到时,会先去建立一个线程局部存储的key,也就是gTLS。随后则会建立IPCThreadState对象,在IPCThreadState的构造函数中,会把this保存到线程局部存储gTLS标识的部分去(frameworks/native/libs/binder/IPCThreadState.cpp):
IPCThreadState::IPCThreadState() : mProcess(ProcessState::self()), mMyThreadId(androidGetTid()), mStrictModePolicy(0), mLastTransactionBinderFlags(0) { pthread_setspecific(gTLS, this); clearCaller(); mIn.setDataCapacity(256); mOut.setDataCapacity(256); }
建立好了IPCThreadState对象以后就返回给调用者。所以,这个地方其实是运用了线程局部存储机制来实现IPCThreadState对象的线程级单例的。
咱们再回到IPCThreadState::joinThreadPool(),来接着看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); // This thread may have been spawned by a thread that was in the background // scheduling group, so first we will make sure it is in the foreground // one to avoid performing an initial transaction in the background. set_sched_policy(mMyThreadId, SP_FOREGROUND); 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=%p\n", (void*)pthread_self(), getpid(), (void*)result); mOut.writeInt32(BC_EXIT_LOOPER); talkWithDriver(false); }
在这个函数中,基本上就是执行一个getAndExecuteCommand()的循环。在getAndExecuteCommand()中则会不停的向binder driver拿命令执行,拿命令执行。
Binder线程池中首个线程的建立执行,大体如上所述,在android java app进程一旦被建立,也就紧跟着会被建立。那意思是说,任何一个android Java app都至少有一个Binder线程,而无论它是否有一个service组件并对其余app提供服务喽?是的,事实就是这个样子的。咱们能够去查看任何一个android java app进程中的线程状况,都至少有一个以上的Binder线程,甚至是最简单的HelloWorld app也是这样的。
所谓的binder线程池,不能是只有这么一个线程吧。那Binder线程池中其它的线程又是如何建立的呢?实际上是kernel发命令给某个已经在运行的binder线程来产生新的线程,以下:
case BR_SPAWN_LOOPER: mProcess->spawnPooledThread(false); break;
大致的backtrace为:
IPCThreadState::executeCommand(int32_t cmd) 《= IPCThreadState::getAndExecuteCommand() 《= IPCThreadState::joinThreadPool(bool isMain) 《= PoolThread::threadLoop()。
binder线程真的就只有这两种建立的方式吗?所谓的binder线程,不过指的就是执行binder IPC事务处理循环的线程吧。而binder IPC事务处理循环不是被封装在了IPCThreadState::joinThreadPool()中了嘛。那是否是任何一个线程只要执行了IPCThreadState::self()->joinThreadPool(),就能够把本身变成一个binder线程了?确实是这样的。在android系统中,也确实有一些native的service,在设置好执行环境以后,甚至会让主线程去执行binder IPC事务处理循环从而把主线程变成binder线程。好比在mediaserver中(frameworks/av/media/mediaserver/main_mediaserver.cpp),就会在main()函数的最后来执行IPCThreadState::self()->joinThreadPool():
118 } else { 119 // all other services 120 if (doLog) { 121 prctl(PR_SET_PDEATHSIG, SIGKILL); // if parent media.log dies before me, kill me also 122 setpgid(0, 0); // but if I die first, don't kill my parent 123 } 124 sp<ProcessState> proc(ProcessState::self()); 125 sp<IServiceManager> sm = defaultServiceManager(); 126 ALOGI("ServiceManager: %p", sm.get()); 127 AudioFlinger::instantiate(); 128 MediaPlayerService::instantiate(); 129 CameraService::instantiate(); 130 AudioPolicyService::instantiate(); 131 registerExtensions(); 132 ProcessState::self()->startThreadPool(); 133 IPCThreadState::self()->joinThreadPool(); 134 }
binder线程还具备一个特色。那就是binder线程线程池中线程的数量是有一个上限的,咱们能够看ProcessState.cpp中open_driver()函数的实现:
343static int open_driver() 344{ 345 int fd = open("/dev/binder", O_RDWR); 346 if (fd >= 0) { 347 fcntl(fd, F_SETFD, FD_CLOEXEC); 348 int vers; 349 status_t result = ioctl(fd, BINDER_VERSION, &vers); 350 if (result == -1) { 351 ALOGE("Binder ioctl to obtain version failed: %s", strerror(errno)); 352 close(fd); 353 fd = -1; 354 } 355 if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) { 356 ALOGE("Binder driver protocol does not match user space protocol!"); 357 close(fd); 358 fd = -1; 359 } 360 size_t maxThreads = 15; 361 result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads); 362 if (result == -1) { 363 ALOGE("Binder ioctl to set max threads failed: %s", strerror(errno)); 364 } 365 } else { 366 ALOGW("Opening '/dev/binder' failed: %s\n", strerror(errno)); 367 } 368 return fd; 369}
在这个函数中,会经过ioctl命令,告诉binder驱动,只能建立最多15个的binder线程。
Done.