IPCThreadState 详解

IPC是Android的精华,找了个时间,详细分析下IPCThreadState 的组织架构及其功能


初始化:用这个方法,我们可以在每个线程里取得IPCThreadState

IPCThreadState* IPCThreadState::self()
{

    // 全局标志位,代表是否TSD已经建立
    if (gHaveTLS) {
restart:
        const pthread_key_t k = gTLS;

        // 获取线程私有数据,即IPCThreadState本身,没有则创建。  保证每个线程都有相对应的IPCThreadState
        IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
        if (st) return st;
        return new IPCThreadState;
    }


    if (gShutdown) return NULL;


    pthread_mutex_lock(&gTLSMutex);
    if (!gHaveTLS) {

        // 如果线程私有数据没建立,则创建一个。
        if (pthread_key_create(&gTLS, threadDestructor) != 0) {
            pthread_mutex_unlock(&gTLSMutex);
            return NULL;
        }
        gHaveTLS = true;
    }
    pthread_mutex_unlock(&gTLSMutex);

    // 创建完,恢复到启始逻辑
    goto restart;
}

看了它的构造函数,明显,这就是为每个线程邦定了个结构体。 


然后,就是IPCThreadState的构造函数,非常简单简洁

IPCThreadState::IPCThreadState()
    : mProcess(ProcessState::self()),
      mMyThreadId(androidGetTid()),
      mStrictModePolicy(0),
      mLastTransactionBinderFlags(0)
{
    pthread_setspecific(gTLS, this);
    clearCaller();
    mIn.setDataCapacity(256);
    mOut.setDataCapacity(256);
}

可以看到,mIn和mOut 直接设了个容量,


接下来总结下各个功能


1. freeBuffer: 
          用于释放空间。  2个用处:
               1)             buffer.ipcSetDataReference 作为释放函数传入  
               2)             BR_REPLY: if no reply
          作为释放函数传入时,分别在传入和传出有体现BR_TRANSACTION and BR_REPLY 
    

           if (parcel != NULL) parcel->closeFileDescriptors();
          检查是否为空, noreply(2) 情况此值为空。 传入(1)此值为this, 当前parsel.   遍寻parsel结构体关闭所有 BINDER_TYPE_FD类型file .

          IPCThreadState* state = self(); 得到当前线程的IPCThreadState, 其实也就是当前结构体

          state->mOut.writeInt32(BC_FREE_BUFFER);
          state->mOut.writeInt32((int32_t)data);
          通过read write 写命令到驱动层,释放结构体。

2. threadDestructor
           用于毁掉这个线程,应该包括各种释放

          self->flushCommands();  ==〉 
           
          // 检查是否打开了底层驱动,如果没,直接返回
          if (mProcess->mDriverFD <= 0)
               return;
          // 与底层交流,试图关闭驱动
          talkWithDriver(false);  细节以后分析,不需要接受命令,但会把当前须传出的命令传下去

          #if defined(HAVE_ANDROID_OS)
               ioctl(self->mProcess->mDriverFD, BINDER_THREAD_EXIT, 0);
          #endif
          直接操纵底层驱动,从驱动层删除了这个线程

3. executeCommand  执行各种命令  命令基本来自驱动层

              case BR_ERROR:
                  result = mIn.readInt32();
                  break;
               从下层读一个32bit, 好象是下面发了个错误信号,上层去读为什么出问题

               case BR_OK:
                  break;
               蛋疼。。

               case BR_ACQUIRE:
                   refs = (RefBase::weakref_type*)mIn.readInt32();
                   obj = (BBinder*)mIn.readInt32();
                   从底层拿这两个结构体上来。
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在 Android 系统中,`ProcessState::self()->startThreadPool()` 用于启动 Binder 线程池服务,而 `IPCThreadState::self()->joinThreadPool()` 则是让当前线程加入到 Binder 线程池中。如果一个 HAL service 没有调用 `ProcessState::self()->startThreadPool()`,但是调用了 `IPCThreadState::self()->joinThreadPool()`,那么该 HAL service 就会试图将当前线程加入到不存在的线程池中,这会导致运行时错误。因此,HAL service 在启动时应该始终调用 `ProcessState::self()->startThreadPool()` 来启动 Binder 线程池服务,以便正确地加入到 Binder 线程池中。 ### 回答2: 如果一个 HAL 服务没有调用 `ProcessState::self()->startThreadPool()`,而只调用了 `IPCThreadState::self()->joinThreadPool()`,可能出现以下情况: 1. HAL 服务是在其他进程中运行的:`ProcessState::self()->startThreadPool()` 用于在当前进程中启动线程池,而 `IPCThreadState::self()->joinThreadPool()` 用于加入现有的线程池。所以如果一个 HAL 服务运行在其他进程中,它只需要加入已经被其他服务启动的线程池即可。 2. HAL 服务是在单线程环境下运行的:在某些情况下,HAL 服务可能是在单线程环境中运行的,不需要多线程支持。此时,并不需要调用 `ProcessState::self()->startThreadPool()` 来启动线程池,只需调用 `IPCThreadState::self()->joinThreadPool()` 即可将服务加入到当前进程的单一线程池中。 总之,只调用 `IPCThreadState::self()->joinThreadPool()` 而不调用 `ProcessState::self()->startThreadPool()` 可能是由于 HAL 服务运行在其他进程中,或者 HAL 服务是在单线程环境中运行的,不需要启动额外的线程池。这种情况下,服务只需加入已存在的线程池即可。 ### 回答3: 在某些情况下,hal service没有调用ProcessState::self()->startThreadPool(),只调用IPCThreadState::self()->joinThreadPool(),主要是因为这个hal service不需要创建自己的线程池。 在Android系统中,HAL(Hardware Abstraction Layer)服务提供了与硬件交互的接口。通常情况下,HAL服务中会涉及到与硬件设备进行通信的操作,比如传感器、摄像头等。为了保证这些HAL服务可以并行运行,Android框架提供了多线程机制。 在HAL服务的实现中,ProcessState::self()->startThreadPool()用于创建一个线程池,并启动多个线程来并行处理来自客户端的请求。而IPCThreadState::self()->joinThreadPool()则会将当前线程加入到线程池中,并等待处理来自客户端的请求。 但是,并不是所有的HAL服务都需要自己的线程池。有些HAL服务可能只需要在调用时等待客户端的请求,而不需要并行处理。对于这种情况,就不需要调用ProcessState::self()->startThreadPool(),只需调用IPCThreadState::self()->joinThreadPool()加入到现有的线程池中即可。 总结来说,如果一个HAL服务没有调用ProcessState::self()->startThreadPool(),只调用了IPCThreadState::self()->joinThreadPool(),那说明这个HAL服务只是简单地等待处理客户端的请求,而不需要额外的线程池来进行并行处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值