6.2.5 秋风扫落叶-StartThread Pool和join Thread Pool分析

最后更新于:2022-04-02 05:50:30

重要的内容都已讲过了,现在就剩下最后两个函数startThreadPool()和joinThreadPool没有分析了。它们就太简单了不是? 1. 创造劳动力——startThreadPool() startThreadPool()的实现,如下面的代码所示: **ProcessState.cpp** ~~~ //太简单,没什么好说的 void ProcessState::startThreadPool() { AutoMutex _l(mLock); //如果要是已经startThreadPool的话,这个函数就没有什么实质作用了 if(!mThreadPoolStarted) { mThreadPoolStarted = true; spawnPooledThread(true); //注意,传进去的参数是true } } ~~~ 上面的spawnPooledThread()函数的实现,如下所示: **ProcessState.cpp** ~~~ void ProcessState::spawnPooledThread(bool isMain) { //注意,isMain参数是true。 if(mThreadPoolStarted) { int32_t s = android_atomic_add(1, &mThreadPoolSeq); char buf[32]; sprintf(buf, "Binder Thread #%d", s); sp t = new PoolThread(isMain); t->run(buf); } } ~~~ PoolThread是在IPCThreadState中定义的一个Thread子类,它的实现,如下所示: **IPCThreadState.h::PoolThread类** ~~~ class PoolThread : public Thread { public: PoolThread(bool isMain) :mIsMain(isMain){} protected: virtualbool threadLoop() { //线程函数如此简单,不过是在这个新线程中又创建了一个IPCThreadState。 // 你还记得它是每个伙计都有一个的吗? IPCThreadState::self()->joinThreadPool(mIsMain); return false; } const boolmIsMain; }; ~~~ 2. 万众归一——joinThreadPool 还需要看看IPCThreadState的joinThreadPool的实现,因为新创建的线程也会调用这个函数,具体代码如下所示: **IPCThreadState.cpp** ~~~ void IPCThreadState::joinThreadPool(bool isMain) { //注意,如果isMain为true,我们需要循环处理。把请求信息写到mOut中,待会儿一起发出去 mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER); androidSetThreadSchedulingGroup(mMyThreadId, ANDROID_TGROUP_DEFAULT); status_tresult; do { int32_t cmd; if(mIn.dataPosition() >= mIn.dataSize()) { size_t numPending = mPendingWeakDerefs.size(); if (numPending > 0) { for (size_t i = 0; i < numPending; i++) { RefBase::weakref_type* refs = mPendingWeakDerefs[i]; refs->decWeak(mProcess.get()); } mPendingWeakDerefs.clear(); } //处理已经死亡的BBinder对象 numPending = mPendingStrongDerefs.size(); if (numPending > 0) { for (size_t i = 0; i < numPending; i++) { BBinder* obj = mPendingStrongDerefs[i]; obj->decStrong(mProcess.get()); } mPendingStrongDerefs.clear(); } } // 发送命令,读取请求 result = talkWithDriver(); if(result >= NO_ERROR) { size_t IN = mIn.dataAvail(); if (IN < sizeof(int32_t)) continue; cmd = mIn.readInt32(); result= executeCommand(cmd); //处理消息 } ...... } while(result != -ECONNREFUSED && result != -EBADF); mOut.writeInt32(BC_EXIT_LOOPER); talkWithDriver(false); } ~~~ 原来,我们的两个伙计在talkWithDriver,它们希望能从Binder设备那里找到点可做的事情。 3. 有几个线程在服务 到底有多少个线程在为Service服务呢?目前看来是两个: - startThreadPool中新启动的线程通过joinThreadPool读取Binder设备,查看是否有请求。 - 主线程也调用joinThreadPool读取Binder设备,查看是否有请求。看来,binder设备是支持多线程操作的,其中一定是做了同步方面的工作。 mediaserver这个进程一共注册了4个服务,繁忙的时候,两个线程会不会显得有点少呢?另外,如果实现的服务负担不是很重,完全可以不调用startThreadPool创建新的线程,使用主线程即可胜任。
';