您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
   
 
 
     
   
 订阅
  捐助
FregServer进程,启动Binder线程池
 
作者 jltxgcy的博客,火龙果软件    发布于 2014-09-10
   次浏览      
 

一、测试代码:

 ~/Android/external/binder/server
----FregServer.cpp
~/Android/external/binder/common
----IFregService.cpp
----IFregService.h
~/Android/external/binder/client
----FregClient.cpp

Binder库(libbinder)代码:

 ~/Android/frameworks/base/libs/binder
----BpBinder.cpp
----Parcel.cpp
----ProcessState.cpp
----Binder.cpp
----IInterface.cpp
----IPCThreadState.cpp
----IServiceManager.cpp
----Static.cpp
~/Android/frameworks/base/include/binder
----Binder.h
----BpBinder.h
----IInterface.h
----IPCThreadState.h
----IServiceManager.h
----IBinder.h
----Parcel.h
----ProcessState.h

驱动层代码:

~/Android//kernel/goldfish/drivers/staging/android
----binder.c
----binder.h

二、源码分析

继续上一篇Android Binder进程间通信---FregServer进程,处理BC_REPLY,返回BR_REPLYhttp://blog.csdn.net/jltxgcy/article/details/26339313,执行完waitForResponse函数,参考Android Binder进程间通信---FregServer进程,发送BC_TRANSACTION,睡眠等待http://blog.csdn.net/jltxgcy/article/details/26076149。应该返回IPCThreadState类的transact方法,再返回BpBinder类的transact函数,最后返回BpServiceManager类addService函数。最后再返回FregService类的main函数,实现如下:

~/Android/external/binder/server

----FregServer.cpp

int main(int argc, char** argv)  
{
FregService::instantiate();

ProcessState::self()->startThreadPool();//启动一个Binder线程池
IPCThreadState::self()->joinThreadPool();//主线程加入线程池

return 0;
}

首先当前进程的ProcessState对象的成员函数startThreadPool来启动一个Binder线程池,接着继续调用当前线程的IPCThreadState对象的成员函数joinThreadPool,将当前线程加入到前面所启动的Binder线程池中去等待和处理来自Client进程的进程间通信请求。

下面我们就分析ProcessState类的成员函数startThreadPool的实现,在分析过程中,同时也会分析IPCThreadState类的成员函数joinThreadPool的实现。

ProcessState类的成员函数startThreadPool的实现如下:

~/Android/frameworks/base/libs/binder

----ProcessState.cpp

void ProcessState::startThreadPool()  
{
AutoMutex _l(mLock);
if (!mThreadPoolStarted) {//默认值为false
mThreadPoolStarted = true;//防止它的成员函数spawnPooledThread被重复调用来启动Binder线程池
spawnPooledThread(true);
}
}

当前进程的ProcessState对象的成员变量mThreadPoolStarted被初始化为false,当它将一个Binder线程池启动起来之后,就会将内部的成员变量mThreadPoolStarted的值设置为true,防止它的成员函数spawnPooledThread被重复调用来启动Binder线程池。spawnPooledThread函数实现如下:

~/Android/frameworks/base/libs/binder

----ProcessState.cpp

void ProcessState::spawnPooledThread(bool isMain)  
{
if (mThreadPoolStarted) {
int32_t s = android_atomic_add(1, &mThreadPoolSeq);
char buf[32];
sprintf(buf, "Binder Thread #%d", s);
LOGV("Spawning new pooled thread, name=%s\n", buf);
sp<Thread> t = new PoolThread(isMain);//isMain为true
t->run(buf);//启动一个新的线程
}
}

创建了一个PoolThread对象t,调用它的成员函数run来启动一个新的线程。

PoolThread类继承了线程类Thread,并且重写了它的线程入口成员函数threadLoop,因此当一个PoolThread对象t所对应的线程启动起来之后,它的成员函数threadLoop就会被调用。实现如下:

~/Android/frameworks/base/libs/binder

----ProcessState.cpp

class PoolThread : public Thread  
{
public:
PoolThread(bool isMain)
: mIsMain(isMain)//isMain为true
{
}

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

const bool mIsMain;
};

和主线程一样调用了IPCThreadState类的成员函数joinThreadPool。实现如下:

~/Android/frameworks/base/libs/binder

----IPCThreadState.cpp

void IPCThreadState::joinThreadPool(bool isMain)//默认值为true  
{
.........

mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);//isMain为true,BC_ENTER_LOOPER

........

status_t result;
do {
int32_t cmd;

.......
result = talkWithDriver();//将自己注册到Binder线程池中,一个无线循环中不断等待进程间通信请求
if (result >= NO_ERROR) {
size_t IN = mIn.dataAvail();
if (IN < sizeof(int32_t)) continue;
cmd = mIn.readInt32();
........


result = executeCommand(cmd);//处理进程间通信请求
}

.........
if(result == TIMED_OUT && !isMain) {//一直为false,因为isMain为true
break;
}
} while (result != -ECONNREFUSED && result != -EBADF);

........

mOut.writeInt32(BC_EXIT_LOOPER);//退出Binder线程池
talkWithDriver(false);
}

参数isMain是一个默认参数,它的默认值为true。从前面的调用过程可以知道,无论是FregServer进程的主线程,还是FregServer进程刚才所创建的线程,它们都是主动(isMain为true)请求加入到Binder线程池的,即它们都不是由于Binder驱动程序请求创建而加入到Binder线程池的。

一个Binder线程的生命周期可以划分为三个阶段:

第一阶段是将自己注册到Binder线程池中;

第二阶段是一个无线循环中不断等待和处理进程间通信请求;

第三阶段是退出Binder线程池。

最后执行完的结果是FregServer有两个线程,睡眠等待进程间通信数据的到来。

   
次浏览       
 
相关文章

手机软件测试用例设计实践
手机客户端UI测试分析
iPhone消息推送机制实现与探讨
Android手机开发(一)
 
相关文档

Android_UI官方设计教程
手机开发平台介绍
android拍照及上传功能
Android讲义智能手机开发
相关课程

Android高级移动应用程序
Android系统开发
Android应用开发
手机软件测试
最新活动计划
Node+Vue3.0前端全栈开发 7-5 [特惠]
Spring Cloud微服务架构 7-5[特惠]
SysML和EA系统设计与建模 7-26[特惠]
Python、数据分析与机器学习 8-23[特惠]
嵌入式软件架构设计 8-22[线上]
Linux内核编程及设备驱动 7-25[北京]

android人机界面指南
Android手机开发(一)
Android手机开发(二)
Android手机开发(三)
Android手机开发(四)
iPhone消息推送机制实现探讨
手机软件测试用例设计实践
手机客户端UI测试分析
手机软件自动化测试研究报告
更多...   


Android高级移动应用程序
Android应用开发
Android系统开发
手机软件测试
嵌入式软件测试
Android软、硬、云整合


领先IT公司 android开发平台最佳实践
北京 Android开发技术进阶
某新能源领域企业 Android开发技术
某航天公司 Android、IOS应用软件开发
阿尔卡特 Linux内核驱动
艾默生 嵌入式软件架构设计
西门子 嵌入式架构设计
更多...