Jimmy Chen

A Programmer

(原创)IPCThreadState和ProcessState

  Android中的ProcessState是客户端和服务端的公共部分,作为Binder通信的基础,ProcessState是一个singleton类,每个进程只有一个对象,每个对象负责打开Binder驱动,建立线程池,让其进程里面的所有线程都能够进行binder通信。与之相关的是IPCThreadState,每个线程都有一个IPCThreadState实例登记在Linux线程的上下文附属数据中,主要负责Binder的读取、写入和请求处理。

一. ProcessState

1.1 ProcessState.h

接下来看看ProcessState类中几个重要的方法。

1.2 ProcessState::self()函数

  self函数好理解,单例模式,一个进程中只有一个,如果没有创建就调用ProcessState的构造函数,下面看看ProcessState的构造函数。

1.3 ProcessState的构造函数

1.4 open_driver()函数

1.5 startThreadPool()函数

  代码比较短,这里继续调用到spawnPooledThread函数,传进去的是true,这里稍微记一下。下面看看spawnPooledThread函数

1.6 spawnPooledThread()函数

  接下来看PoolThread类发现PoolThread类是继承了Thread类的,所以当调用其run方法是会自动调用其threadLoop方法,下面看PoolThread类

1.7 PoolThread类

  这里先看到这里,其余的函数大概看一下基本也能明白是用来干什么的,在后续的binder文章中应该会看到其中的大部分。

二. IPCThreadState

2.1 IPCThreadState.h

2.2 IPCThreadState::self()函数

  pthread_getspecific、pthread_setspecific和pthread_key_create都和线程局部性有关。函数pthread_setspecific将pointer的值与key相关联。而函数pthread_getspecific则是将与key相关联的数据读取出来。返回的数据类型都是void *,所以可以指向任何的数据类型。同时因为是线程相关的,所以不同线程调用pthread_setspecific设置与key关联的值后,并不会影响到其他的线程。举例来说就是,在线程A中调用pthread_setspecific设置与key相关的值为a,线程B中调用pthread_setspecific设置与key相关的值为b,那么A线程中调用pthread_getspecific获取与key关联的值会得到a,并不会因为在线程B中设置为b了而影响到A线程中的值。

  那么具体的与key关联的值是在IPCThreadState的构造函数中设置的

其中与gTLS相关联的值就是IPCThreadState自己了。

2.3 joinThreadpool函数

  在ProcessState的PoolThread中最后会调用到IPCThreadState的joinThreadPool函数,下面就看看这个函数做了些什么事情。

mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);根据这行代码可以得出这两个点:

  • 如果isMain为true,那么写到mOut中的command为BC_ENTER_LOOPER,代表该线程是主线程,再根据if(result == TIMED_OUT && !isMain),可以得知主线程是不会退出循环的。
  • 如果isMain为false,那么写到mOut中的command为BC_REGISTER_LOOPER代表向binder驱动中注册一个线程,如果该线程在处理command时超时,那么就会退出线程循环。

2.4 getAndExecuteCommand函数

2.5 talkWithDriver函数

  这里最后会调用到Binder驱动的相应功能,具体的函数这里先略过,后面计划在理解Binder数据传输流程的时候再看吧。

  回到getAndExecuteCommand函数,然后会对返回的结果进行解析获取对应的cmd值,然后再执行executeCommand函数。

2.6 executeCommand函数

这里只看BC_ENTER_LOOPER返回的相应值

  这里最后会调用到ProcessState里面的spawnPooledThread函数,无非也是在里面执行start开启一个线程

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注