Android Binder 线程池和线程池工作流程

简介:

每一个进程都有且只有一个processState(单例模式)来描述当前进程在binder通信时binder的状态。且都有一个默认的binder主线程Pool thread来跟底层Binder Driver进行通信,这个线程的主体是一个IPCThreadState对象。关系如下:

 Pool Thread的类在ProcessState.cpp中:

 Binder 线程池的启动代码走读:

binder线程池的启动是通过调用ProcessState.cpp 的startThreadPool()实现的,主要做了两件事:1.设置了线程池的启动状态 2.调用了spawnPooledThread方法,传入参数为TRUE

1.创建binder线程名

2.创建线程并开启线程。结合上面PoolThread的类看,创建后会执行到threadLoop方法,并传入参数true 调用IPCThreadState的joinThreadPool方法如下:

void IPCThreadState::joinThreadPool(bool isMain)
{
   
    LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid());
//isMain ==TRUE 代表主线程,isMain ==FALSE 代表普通的binder线程
//主线程 BC_ENTER_LOOPER 发送给binder_driver后,binder_driver会确定能否启动线程
//普通binder线程 BC_REGISTER_LOOPER 发送给binder_driver后,binder_driver会确定能否启动线程
    mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);

    mIsLooper = true;
    status_t result;
    do {
        processPendingDerefs();
        // now get the next command to be processed, waiting if necessary
        result = getAndExecuteCommand();

        if (result < NO_ERROR && result != TIMED_OUT && result != -ECONNREFUSED && result != -EBADF) {
            LOG_ALWAYS_FATAL("getAndExecuteCommand(fd=%d) returned unexpected error %d, aborting",
                  mProcess->mDriverFD, result);
        }

        // Let this thread exit the thread pool if it is no longer
        // needed and it is not the main process thread.
        if(result == TIMED_OUT && !isMain) {
            break;
        }
    } while (result != -ECONNREFUSED && result != -EBADF);

    LOG_THREADPOOL("**** THREAD %p (PID %d) IS LEAVING THE THREAD POOL err=%d\n",
        (void*)pthread_self(), getpid(), result);

    mOut.writeInt32(BC_EXIT_LOOPER);
    mIsLooper = false;
    talkWithDriver(false);
}

 

主线程是在启动binder线程池的时候被创建的,其他线程是binder Driver发送BR_SPAWN_LOOPER 来通知进程创建的。

发送BR_SPAWN_LOOPER的条件如下:

  1. 当前进程已经没有可以请求的线程,并且也没有已经ready可用的线程了
  2. 当前进程已经开始请求的线程小于最大线程数(每个进程包含主线程一个,其他线程的限额是15个)
  3. 当前线程状态不能是BINDER_LOOPER_STATE_REGISTERED,也不能是BINDER_LOOPER_STATE_ENTERED.这两个状态代表此线程的状态已经启动了。不能重复启动

{其中BR_SPAWN_LOOPER 是在BINDER_WORK_TRANSACTION的cmd中被发送出来的,而BINDER_WORK_TRANSACTION是在client发送BC_TRANSACTION或者发送BC_REPLY的时候被调用的

BC_TRANSACTION或发送BC_REPLY 对应两种情景:

BC_TRANSACTION : client进程向 binderDriver发送IPC调用请求的时候

BC_REPLY : server进程收到了binderDriver的IPC调用请求,请求执行完毕后发送返回值时候}

线程池的工作过程:

线程池工作中主要涉及ProcessState,Pool Thread, IPCThreadState 和BpBinder。ProcessState和Pool Thread 、IPCThreadState 都是以单例模式设计的。每个进程中只有一个。

ProcessState 负责创建并管理BpBinder以及Pool Thread,PoolThread的核心是IPCThreadState,这个类里面有两个Parcel对象,分别负责存储从BinderDriver读出来的数据和要往BinderDriver中写入的数据。我们一般使用的各种Manager继承自BpBinder,当我们需要通过IPC调用到server的接口时,会通过BpBinder的transact方法将数据写入到mOut中,然后IPCThreadState 又会通过talkwithDriver将数据发给binderDriver。

 Binder通信模型流程图:

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值