FregServer进程,启动Binder线程池,睡眠等待在proc->wait
来源:互联网 发布:男朋友很厉害体验知乎 编辑:程序博客网 时间:2024/06/08 16:03
本文参考《Android系统源代码情景分析》,作者罗升阳
一、测试代码:
~/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有两个线程,睡眠等待进程间通信数据的到来。
- FregServer进程,启动Binder线程池,睡眠等待在proc->wait
- Service Manager进程,发送BC_REPLY,唤醒FregServer进程,返回BR_TRANSACTION_COMPLETE,睡眠等待在proc->wait
- Service Manager进程启动,睡眠等待在进程proc->wait
- FregServer进程,发送BC_TRANSACTION,唤醒ServiceManager进程,返回BR_TRANSACTION_COMPLETE,睡眠等待主线程thread->wait
- android 的 线程的睡眠,等待,wait,notify
- 进程等待wait,waitpid
- 线程等待join(),wait()
- FregServer进程,返回BR_REPLY
- linux 进程等待 wait 、 waitpid
- 进程等待与wait&waitpid
- 进程的等待wait() --多进程编程
- 【进程&线程】睡眠与唤醒
- android的binder驱动 进程,线程,线程池
- android的binder驱动 进程,线程,线程池
- Linux--等待进程结束wait()和waitpid()
- 让wait等待所有子进程结束
- 进程的等待(wait和waitpid)
- 正确理解线程等待和释放(wait/notify)
- Android控件 之 GridView九宫格实现方法二
- 当GOLang遇到大量ESTABLISHED时
- 安全、兼容性及权限——关于UAC的一席谈(略更新)
- C# SSH Shell终端模拟控件Rebex SSH Shell详细介绍
- STM8S PWM 应用 呼吸灯
- FregServer进程,启动Binder线程池,睡眠等待在proc->wait
- Minimum Depth of Binary Tree
- js 采用call实现继承
- U-Boot启动过程--详细版的完全分析 .
- grep
- 解析C语言结构体对齐(内存对齐问题)
- 多tomcat启动
- centos apache httpd.conf文件初始化配置
- 苹果收购Beats,花32亿美元为的是苹果电视