Android开发之ProcessState和IPCThreadState类分析

在Android中ProcessState是客户端和服务端公共的部分,作为Binder通信的基础,ProcessState是一个singleton类,每个
进程只有一个对象,这个对象负责打开Binder驱动,建立线程池,让其进程里面的所有线程都能通过Binder通信。
与之相关的是IPCThreadState,每个线程都有一个IPCThreadState实例登记在Linux线程的上下文附属数据中,主要负责
Binder的读取,写入和请求处理框架。IPCThreadState在构造的时候获取进程的ProcessState并记录在自己的成员变量
mProcess中,通过mProcess可以获得Binder的句柄。

[html]  view plain  copy
  1. frameworks/base/include/binder/ProcessState.h  
  2. class ProcessState : public virtual RefBase  
  3. {  
  4. public:  
  5.     static sp<ProcessState> self();   // 单例模式,获取实例  
  6.       
  7.     void setContextObject(const sp<IBinder>& object);  
  8.     sp<IBinder> getContextObject(const sp<IBinder>& caller);  
  9.       
  10.     void setContextObject(const sp<IBinder>& object, const String16& name);  
  11.     sp<IBinder> getContextObject(const String16& name, const sp<IBinder>& caller);  
  12.       
  13.     void startThreadePool();  
  14.       
  15.     typdef bool (*context_check_func)(const String16& name, const sp<IBinder>& caller, void* userData);  
  16.       
  17.     bool isContextManager(void) const;  
  18.     bool becomeContextManager(context_check_func checkFunc, void* userData);  
  19.       
  20.     sp<IBinder> getStrongProxyForHandle(int32_t handle);  
  21.     wp<IBinder> getWeakProxyForHandle(int32_t handle);  
  22.     void espungeHandle(int32_t handle, IBinder* binder);  
  23.       
  24.     void spawnPooledThread(boot isMain);  
  25. private:  
  26.     friend class IPCThreadState;  
  27.         ProcessState();  
  28.         ~ProcessState;  
  29.         ProcessState(const ProcessState& o);  
  30.     ProcessState& operator=(const ProcessState& o);  
  31.       
  32.     struct hdndle_entry {  
  33.         IBinder* binder;  
  34.         RefBase::weakref_type* refs;  
  35.     };  
  36.       
  37.     handle_entry* lookupHandleLocked(int32_t handle);  
  38.       
  39.     int mDriverFD;      // 打开的binder驱动文件描述符  
  40.     void* mVMStart;  
  41.       
  42.     Vector<handle_entry> mHandleToObject;  
  43.       
  44.     bool mManagerContexts;  
  45.     context_check_func mBinderContextCheckFunc;  
  46.     void* mBinderContextUserData;  
  47.     KeyedVector<String16, sp<IBinder> > mContexts;  // 映射,服务名字 和 IBinder对应  
  48.     bool mThreadPoolStarted;    // 线程池是否已经创建  
  49. volatile int32_t mThreadPoolSeq;    // 这个进程中启动线程个数  
  50. };  

 

1)获得ProcessState的实例

[html]  view plain  copy
  1. sp<ProcessState> proc(ProcessState::self());  
  2. 调用函数:  
  3. sp<ProcessState> ProcessState::self()   
  4. {  
  5.     if (gProcess != NULL) return gProcess;  
  6.     AutoMutext _l(gProcessMutex);  
  7.     if(gProcess == NULL) gProcess = new ProcessState;  
  8.     return gProcess;  
  9. }  
  10. 进入构造函数:  
  11. ProcessState::ProcessState() : mDriverFD(open_driver())  
  12.             , mVMStart(MAP_FAILED),  
  13.             , mManagerContexts(false)  
  14.             , mBinderContextCheckFunc(NULL)  
  15.             , mBinderContextUserData(NULL)  
  16.             , mThradPoolStarted(false)  
  17.             , mThreadPoolSeq(1)   
  18. {  
  19.   
  20. }  

这个构造函数里面调用open_driver()打开了/dev/binder设备驱动文件,返回文件描述符。这样我们就能通过这个mDriverFd
来和binder驱动交互了。

2)创建线程ProcessState::self()->startThreadPool();

[html]  view plain  copy
  1. void ProcessState::startThreadPool()  
  2. {  
  3.     AutoMutex _l(mLock);  
  4.     if(!mThreadPoolStarted) {  
  5.         mThreadPoolStarted = true;  
  6.         spawnPooledThread(true);  
  7.     }  
  8. }  
  9. void ProcessState::spawnPoolThread(bool isMain)  
  10. {  
  11.     if (mThreadPoolStarted) {  
  12.         int32_t s = android_atomic_add(1, &mThreadPoolSeq);  
  13.         sp<Thread> t = new PoolThread(isMain);  
  14.         t->run(buf);  
  15.     }  
  16. }  
[html]  view plain  copy
  1. 其实这里就是创建一个线程PoolThread,而PoolThread是一个继承于Thread的类。所以调用t->run()之后相当于调用  
  2. PoolThread类的threadLoop()函数,我们来看看PoolThread类的threadLoop线程函数。  
  3. virtual bool threadLoop()  
  4. {  
  5.     IPCThreadState::self()->joinThreadPool(mIsMain);   
  6.     // 这里线程函数调用了一次IPCThreadState::self()->joinThreadPool()后就退出了  
  7.     return false;  
  8. }  

 

3)IPCThreadState::self()->joinThreadPool();

      我们知道:进程调用spawnPoolThread()创建了一个线程,执行joinThreadPool(),而主线程也是调用这个函数。唯一区别
是参数,主线程调用的joinThreadPool(true),创建的线程调用的是jointThreadPool(false)。
下面我们来分析下这个函数,首先我们来看看IPCThreadState这个类

[html]  view plain  copy
  1. frameworks/base/include/IPCThreadState.h  
  2. class IPCThreadState  
  3. {  
  4. public:  
  5.     static IPCThreadState* self();  
  6.     sp<ProcessState> process();  
  7.     ......  
  8.     void joinThradPool(bool isMain = true);  
  9.     status_t transact(int32_t handle, uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);  
  10.     void incStrongHandle(int32_t handle);  
  11.     void decStrongHandle(int32_t handle);  
  12.     void incWeakHandle(int32_t handle);  
  13.     void decWeakHandle(int32_t handle);  
  14. private:  
  15.     IPCThraedState();  
  16.     ~IPCThreadState();  
  17.     status_t sendReplay(const Parcel& reply, uint32_t flags);  
  18.     status_t waitForResponse(Parcel& reply,  status_t *acquireResult = NULL);  
  19.     status_t talkWithDriver(bool doReceice = true);  
  20.     status_t writeTransactionData();  
  21.     status_t executeCommand();  
  22. private:  
  23.     sp<ProcessState> mProcess;  
  24.     Vector<BBinder> mPendingStrongDerefs;  
  25.     Vector<RefBase::weakref_type*> mPendingWeakDerefs;  
  26.     Parcel mIn;  
  27.     Parcel mOut;  
  28. }  
  29. 上面是IPCThreadState类常用的几个函数。  
  30. IPCThreadState* IPCThreadState::self()  
  31. {  
  32.     if(gHaveTLS) {  // 第一次进来肯定为false  
  33. restart:  
  34.         const pthread_key_t k = gTLS;  
  35.         IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);  
  36.         if(st) return st;  
  37.         return new IPCThreadState;  // new 一个IPCThreadState对象  
  38.     }  
  39.       
  40.     if(gShutdown) return NULL;  
  41.       
  42.     pthread_mutex_lock(&gTLSMutex);  
  43.     if(!gHaveTLS) {  
  44.         // 第一个参数为指向一个键值的指针,第二个参数指明一个destructor函数,当线程结束时调用  
  45.         if(phread_key_create(&gTLS, threadDestructor) != 0) {  
  46.             pthread_mutex_unlock(&gTLSMutex);  
  47.             return NULL;  
  48.         }  
  49.         gHaveTLS = true;  
  50.     }  
  51.     pthread_mutex_unlock(&gTLSMutex);  
  52.     goto restart;  
  53. }  

 

下面来说明下线程中特有的线程存储:Thread Specific Data.
在多线程中,所有线程共享程序中变量,如果每一个线程都希望单独拥有它,就需要线程存储了。即一个变量表面看起来是
全局变量,所有线程都可以使用它,它的值在每一个线程都是单独存储的。
用法:
       1)创建一个类型为pthread_key_t 类型变量
       2)pthread_key_create()创建改变量,第二个参数表上一个清理函数,用来在线程释放该线程存储的时候调用。
       3)当线程中需要存储特殊值的时候,可以用pthread_setspecific(),第一个参数为pthread_key_t 变量,第二个参数为void* 变量,可以存储任何类型的值。
       4)当需要取出存储值的时候,调用pthread_getspecific(),返回void*类型变量值。

好了我们现在知道pthread_key_t是干什么用的了?既然代码中有pthread_getspecific()获取IPCThreadState*对象的函数
那么肯定有设置这个变量值的地方?我们找到IPCThreadState的构造函数:

[html]  view plain  copy
  1. IPCThreadState:IPCThreadState()   
  2.     : mProcess(ProcessState::self()),  
  3.       mMyThreadId(androidGetTid()),  
  4.       mStrictModePolicy(0),  
  5.       mLastTransactionBinderFlags(0)  
  6. {  
  7.     pthread_setspecific(gTLS, this);    // 设置为当前this 指针  
  8.     clearCaller();  
  9.     mIn.setDataCapacity(256);   // 这里mIn 和 mOut分别表示Binder输入输出的变量,我们后面分析  
  10.     mOut.setDataCapacity(256);  
  11. }  
[html]  view plain  copy
  1. 最后进入IPCThreadState::joinThreadPool(bool isMain)  
  2. void IPCThreadState::joinThreadPool(bool isMain)    // 默认为true  
  3. {  
  4.     mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);  
  5.     do {  
  6.         int32_t cmd;  
  7.           
  8.         if(mIn.dataPosition() >= mIn.dataSize()){  
  9.             size_t numPending = mPendingWeakDerefs.size();  
  10.             if(numPending > 0) {  
  11.                 for(size_t i = 0; i < numPending; i++) {  
  12.                     RefBase::weakref_type* refs = mPendingWeakDerefs[i];  
  13.                     refs->decWeak(mProcess.get);  
  14.                 }  
  15.                 mPendingWeakDerefs.clear();  
  16.             }  
  17.             numPending = mPendingStrongDerefs.size();  
  18.             if(numPending > 0) {  
  19.                 for(sizt_t i = 0; i < numPending; i++) {  
  20.                     BBinder* obj = mPendingStrongDerefs[i];  
  21.                     obj->decStrong(mProcess.get);  
  22.                 }  
  23.                 mPendingStrongDerefs.clear();  
  24.             }  
  25.         }  
  26.         // 读取下一个command进行处理  
  27.         result = talkWithDriver();// 来等待Client的请求  
  28.         if(result >= NO_ERROR) {  
  29.             size_t IN = mIn.dataAvail();  
  30.             if(IN < sizeof(int32_t)) continue;  
  31.             cmd = mIn.readInt32();  
  32.         }  
  33.         result = executeCommand(cmd);  
  34.       
  35.         if(result == TIMED_OUT && !isMain)  
  36.             break;  
  37.     } while(result != -ECONNREFUSED && result != -EBADF);  
  38.       
  39.     mOut.writeInt32(BC_EXIT_LOOPER);  
  40.     talkWithDriver(false);  
  41. }  

          这里的talkWithDriver()里面之际调用的是ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr)从/dev/binder读取
Client端发过来的请求,然后调用executeCommand处理

[html]  view plain  copy
  1. status_t IPCThreadState::executeCommand(int32_t cmd)  
  2. {  
  3.     BBinder* obj;  
  4.     RefBase::weakref_type* refs;  
  5.     status_t result = NO_ERROR;  
  6.       
  7.     switch(cmd) {  
  8.         case BR_TRANSACTION:  
  9.         binder_transaction_data tr;  
  10.         result = mIn.read(&tr, sizeof(tr));  
  11.         ....  
  12.         Parcel reply;  
  13.         if(tr.target.ptr) {  
  14.             sp<BBinder> b((BBinder*)tr.cookie);  
  15.             const status_t error  = b->transact(tr.code, buffer, &reply, tr.flags);  
  16.         }  
  17.         ....  
  18.         break;  
  19.       
  20.     }  
  21. }  
  22. 最后又调用到BBinder 的transact()函数里面去了。  
  23. status_t BBinder::transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags )  
  24. {  
  25.     data.setDataPosition(0);  
  26.     switch(code)  
  27.     {  
  28.         case PING_TRANSACTION:  
  29.             reply->writeInt32(pingBinder());  
  30.             break;  
  31.         default:  
  32.             err = onTransact(code, data, reply, flags);  
  33.             break;  
  34.     }  
  35.     return err;  
  36. }  

        到这里IPCThreadState类的流程就大概清楚了,线程调用joinThreadPool()从/dev/binder读取客户端的请求,然后调用
BBinder::transact()处理。那么这个BBinder是怎么来的呢?
上面代码中:sp<BBinder> b((BBinder*)tr.cookie)说明这个BBinder指针是从Binder驱动中获取到,肯定是客户端
发送过来的,那么它的实际类型又是什么呢?而BBinder调用的onTransact()函数只是一个虚函数,肯定由它的子类来实
现,那我们服务端又怎么找到这个BBinder的实际类型呢?
这些内容我们下一节通过MediaPlayer这个具体示例分析。

猜你喜欢

转载自blog.csdn.net/weixin_38503885/article/details/80482240