Binder机制-IPCThreadState过程

Binder通信过程中的用户空间线程池的管理 在Binder通信机制里,客户端与服务端之间的通信是在专门的IPC通信线程中进行的。这些线程构成一个线程池。线程的创建和销毁是在用户空间进行的,而对线程的控制是在驱动层进行的,即驱动控制线程池中线程的生命,而线程本身则是运行在用户空间的。驱动层是通过BR_SPAWN_LOOPER向用户空间发送创建新线程的命令。 线程池的大小可以设置。默认情况下,线程池只有一个主线程,它在进程生命周期期间是不会退 阅读详情

在Binder通信的服务器端,一般会存在这样一条语句:

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

从语句的字面意思都可以理解出,应该是跟线程有关的。与ProcessState::self()一样,IPCThreadState::self()函数也是类IPCThreadState的静态成员函数,属于这个类,不属于具体某个对象。

class IPCThreadState
{
public:
    static  IPCThreadState*     self();
...
}

其函数体实现如下:

IPCThreadState* IPCThreadState::self()
{
// 判断gHaveTLS是true还是false,字面意思也可以知道是用来标记有无TLS(Thread Loacal Storage)的
    if (gHaveTLS) {
restart:
        const pthread_key_t k = gTLS;
        //如果存在TLS,则根据key:gTLS去获取存储指向IPCThreadState对象的指针值,
        //这是一个一对多的关系,所有线程使用相同的key,但是其每个线程存储的值(IPCThreadState对象)
        //是线程私有的,每个线程都有一个这样的对象
        IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k); 
        if (st) return st;
        //如果此线程不存在这样的key:gTLS对应的值,则创建一个IPCThreadState新对象,
        //并在其构造函数中添加进key:gTLS对应的线程局部空间中TLS(thread local storage)
        return new IPCThreadState; 
    }

    pthread_mutex_lock(&gTLSMutex);
    if (!gHaveTLS) { //gHaveTLS为false表示进程中还没有TLS,则需要创建基于key:gTLS的线程局部存储
        //创建基于key:gTLS的线程局部空间
        int key_create_value = pthread_key_create(&gTLS, threadDestructor);
        if (key_create_value != 0) {
            pthread_mutex_unlock(&gTLSMutex);
            return NULL;
        }
        gHaveTLS = true; //此时已经有TLS了,固gHaveTLS赋值为ture
    }
    pthread_mutex_unlock(&gTLSMutex);
    goto restart;
}

以上分析多次提到线程局部空间(thread local storage),代表的是每个线程所私有的存储空间,线程中互不可以访问,是一个相对独立的空间,不懂的可以先行查资料去了解一下,这里不展开讲解。此线程局部空间就是去存储每一个线程都拥有的一个IPCThreadState对象,且都是独立的。

再看一下IPCThreadState的构造函数:

IPCThreadState::IPCThreadState()
    : mProcess(ProcessState::self()),
      mStrictModePolicy(0),
      mLastTransactionBinderFlags(0)
{
    pthread_setspecific(gTLS, this); //在此往key:gTLS添加IPCThreadState对象
    clearCaller();
    mIn.setDataCapacity(256); //初始化线程私有的数据输入空间大小
    mOut.setDataCapacity(256); //初始化线程私有的数据输出空间大小
}

IPCThreadState::joinThreadPool()函数的目的是让线程进入到循环中,等待命令,解析命令,给出响应,函数体如下:

void IPCThreadState::joinThreadPool(bool isMain = true)
{
     mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
    status_t result;
    do {
        processPendingDerefs();
        // now get the next command to be processed, waiting if necessary
        result = getAndExecuteCommand(); //此函数为joinThreadPool()函数的主要任务过程
    } while (result != -ECONNREFUSED && result != -EBADF);

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

从以上代码可以看出,IPCThreadState::joinThreadPool()函数主要是在一个do…while()循环里面不断的读取命令数据,然后解析命令数据,并给出相应的响应。

status_t IPCThreadState::getAndExecuteCommand()
{
    status_t result;
    int32_t cmd;

    result = talkWithDriver(); //读取数据
    if (result >= NO_ERROR) {
        size_t IN = mIn.dataAvail();
        if (IN < sizeof(int32_t)) return result;
        cmd = mIn.readInt32();
        IF_LOG_COMMANDS() {
            alog << "Processing top-level Command: "
                 << getReturnString(cmd) << endl;
        }

        pthread_mutex_lock(&mProcess->mThreadCountLock);
        mProcess->mExecutingThreadsCount++;
        if (mProcess->mExecutingThreadsCount &
Android 进阶——Binder IPC之Native家族成员驱动通信桥梁IPCThreadState 详解(七) 无论是BpBinder还是BnBinder,都是通过IPCThreadState和Binder 驱动程序通信的,换言之,Server进程是通过Binder库(客户端与服务端)的IPCThreadState 来处理与Binder驱动的协议的,类似Socket通信一样,IPCThreadState的代码一部分给客户端使用,一部分给服务端使用。 阅读详情

相关推荐

Android 进阶——Binder IPC之Native 服务的启动及代理对象的获取详解(六)

Binder IPC之Native 服务的启动及代理对象的获取详解

最美不过,心中有梦,身旁有你! 1926

Android C++底层Binder通信机制原理分析总结【通俗易懂】

Android C++层Binder通信: 通过transact()方法可以向远端的IBinder对象发出调用,再通过onTransact()函数让你自己的远程对象能够响应接收到的调用。 例如MediaRecorder的继承关系(向右箭头表示继承关系,#XXX#中间是关键方法,/斜线表示多继承): 客户端: 1、MediaRecorder->BnMediaRecorderClient#onTransact()#->BnInterface-> BBinder#transact()#(-&gt

CloverLHao的博客 3162

Binder系列4 Binder传输原理之请求发起

一 Binder是如何做到精确打击的? 我们先问一个问题,binder机制到底是如何从代理对象找到其对应的binder实体呢?难道它有某种制导装置吗?要回答这个问题,我们只能静下心来研究binder驱动的代码。在本系列文档的初始篇中,我们曾经介绍过ProcessState,这个结构是属于应用层次的东西,仅靠它当然无法完成精确打击。其实,在binder驱动层,还有个与之相对的结构,叫做binder_proc。为了说明问题,我修改了初始篇中的示意图,得到下图: 1.1 创建binder_proc 当构造Pro

liuwg1226的专栏 782

【Flink cdc】Data row is smaller than a column index, internal schema representation is probably xxx

翻译一下:当scan.startup.mode=EARLIEST_OFFSET时,如果在最早的offset之后表结构有过变化就无法支持。原因应该是在binlog 的earliest_offset之后,表结构被修改过。我的解决方案:source配置中使用。mysql source配置使用。,以时间戳为消费依据。

integrity 2085

异常数据处理——3σ原则、箱线图

异常数据处理——3σ原则、箱线图 用不包括异常值的剩余数据的均值替换、删除DataFrame中某列有异常值的整行等方法

杨老师的小跟班(*∩_∩*) 9033

neruolib全脑建模计算框架

neurolib 是一个用python编写的全脑建模计算框架,也是可扩展的、允许轻松实现自定义神经质量模型,能够在介观尺度上表示脑区平均活动。

Rootfyx的博客 1147

STM32H750_QSPI_Flash_Configuration_With_CubeMX

本文详细介绍了如何使用STM32CubeMX配置STM32H750的QSPI Flash接口,包括硬件连接、CubeMX参数设置、代码生成与初始化流程优化。通过实战示例展示了Flash ID读取、页编程与数据读取等常用操作,并提供了调试技巧与性能优化建议,帮助开发者高效实现高速外部存储扩展。

weixin_29176179的博客 274

HC-05蓝牙模块AT指令配置避坑全记录:从配对失败到稳定主从通信

本文详细记录了HC-05蓝牙模块AT指令配置的全过程,从基础认知到主从通信的稳定实现。涵盖了进入AT模式的方法、关键AT指令详解、主从配对流程及常见故障排除,帮助开发者快速掌握蓝牙串口模块的配置技巧,避免常见配对失败问题。

weixin_42632434的博客 415

Cisco Packet Tracer实战:三层交换机链路聚合配置全流程(附常见错误排查)

本文详细解析了在Cisco Packet Tracer环境中配置三层交换机链路聚合的全流程,包括基础网络设置、LACP协议配置、路由协议集成及高级优化技巧。通过实战案例和常见错误排查指南,帮助网络工程师和CCNA备考学员掌握这一提升带宽利用率和实现链路冗余的核心技术。

grafana6viz的博客 230

【Unity实战】实现最完美最简单的UI适配方案,背景压缩或者拉伸变形解决方案,手机刘海屏适配,适配不同分辨率,不同尺寸,不同设备。

这期来讲一个简单的UI设计方案,很多同学可能搞不懂锚点、轴心这些概念,导致做好的UI在别人的设备上,乱跑或者是重叠,或者是参加游戏老发时间比较紧来不及做适配,都可以来试试这个方法,通过填充边框来保持游戏画面的原始比例,所以它的缺点也很明显,在一些移动设备上会浪费比较大的显示面积。 unity不同设备UI变形? UI在不同设备上如何适配?

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 3650

第133章 PCL OrientedBoundingBox 有向包围盒

中文叫有向包围盒,是一种旋转过的包围盒。特点:不像AABB那样固定朝向坐标轴能更紧密地包裹物体适用于复杂姿态的物体,比如倾斜、旋转的物体通常通过PCA、惯性矩等算法确定方向。

yumeiguo的博客 263

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

上一篇: Binder机制-ProcessState过程
下一篇: Bindr机制-向ServiceManager添加服务
yanlinembed
博客等级 码龄12年 42粉丝 32原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值