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创建新的线程,使用主线程即可胜任。
';