Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >[051]Binder线程优先级继承

[051]Binder线程优先级继承

作者头像
王小二
发布于 2020-06-08 04:11:08
发布于 2020-06-08 04:11:08
2.9K00
代码可运行
举报
运行总次数:0
代码可运行

前言

Binder通信需要两个线程,这两个线程的优先级是不同,也就意味着,他们能获取到的cpu的优先级不同。

假如线程A通过非oneway的Binder调用到线程B,如果线程A的优先级大于线程B,这里就会有一个问题出现,线程A会因为线程B的优先级较低而block更多的时间。显然这是不合理的,Binder设计理念就是让你感觉不到IPC的存在,如同在同一线程中调用一个方法那么容易。

一、非oneway的Binder的流程

假设线程A通过Binder接口int add(a, b)将a和b发送给线程B,然后线程B计算c=a+b,将c返回给线程A。 简化一下步骤就是如图1.1

图1.1

二、如何将线程A优先级传递给线程B

我们先不看代码,自己想想如何实现这个需求。 我们可以考虑在a,b的数据包中带上线程A的优先级参数, 唤醒线程B的时候设置成A线程优先级,然后处理c=a+b, 处理完成之后然后发送c的数据给线程A, 发完之后,将线程B恢复成原来的线程优先级。 其实Binder驱动也就是这样子实现。简化一下步骤就是如图2.1

图2.1

三、代码分析

看了图2.1中的红色字体,你会发现整个实现很简单,有种将大象装进冰箱总共需要三步一样简单,我们就来分析每一步是如何实现的。

3.1 将线程A的优先级打包进a,b的数据包

对于非oneway的方法,会将client端线程A也就是current的policy和normal_prio值打包进binder_transaction t->priority

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    struct binder_transaction *t;

    if (!(t->flags & TF_ONE_WAY) &&
        binder_supported_policy(current->policy)) {
        /* Inherit supported policies for synchronous transactions */
                //将client端线程也就是current的policy和normal_prio值打包进binder_transaction
        t->priority.sched_policy = current->policy;
        t->priority.prio = current->normal_prio;
    } else {
        /* Otherwise, fall back to the default priority */
        t->priority = target_proc->default_priority;
    }

3.2 唤醒线程B之后,保存线程B的优先级参数,并设置成线程A的优先级

从binder_transaction中获取线程A的优先级参数desired_prio 保存线程B的优先级参数到t->saved_priority 设置线程B的优先级参数为desired_prio。 注意:对于线程B返回给线程A的时候,不需要改变线程A的优先级

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
static int binder_thread_read(struct binder_proc *proc,
                  struct binder_thread *thread,
                  binder_uintptr_t binder_buffer, size_t size,
                  binder_size_t *consumed, int non_block)
{
....
        if (t->buffer->target_node) {
            struct binder_node *target_node = t->buffer->target_node;
            struct binder_priority node_prio;

            trd->target.ptr = target_node->ptr;
            trd->cookie =  target_node->cookie;
            node_prio.sched_policy = target_node->sched_policy;
            node_prio.prio = target_node->min_priority;
            //开始设置线程B的优先级
            binder_transaction_priority(current, t, node_prio,
                            target_node->inherit_rt);//跳转到3.2.1
            cmd = BR_TRANSACTION;
        } else { //对于server段返回给client端,不需要改变client端的线程优先级
            trd->target.ptr = 0;
            trd->cookie = 0;
            cmd = BR_REPLY;
        }
...
}

//3.2.1
static void binder_transaction_priority(struct task_struct *task,
                    struct binder_transaction *t,
                    struct binder_priority node_prio,
                    bool inherit_rt)
{
    //提取3.1保存的线程A的优先级,作为desired_prio
    struct binder_priority desired_prio = t->priority;
    //保存线程B的优先级到binder_transaction的saved_priority
    t->saved_priority.sched_policy = task->policy;
    t->saved_priority.prio = task->normal_prio;
        ...
    //设置线程B的优先级为desired_prio
    binder_set_priority(task, desired_prio);
}

3.3 恢复线程B的优先级

线程B返回结果的时候会调用这个代码 唤醒线程A 将线程B的优先级恢复

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    if (reply) {
        ...
        //唤醒线程A
        wake_up_interruptible_sync(&target_thread->wait);
        //将线程B的优先级恢复
        binder_restore_priority(current, in_reply_to->saved_priority);
                ...
    } 

四、带着问题看源码

看了上面的代码,我们大概清楚了Binder驱动是如何解决IPC中两个线程优先级不同问题。 只能说是大概,希望大家带着以下问题去看源码,你会发现还有很多细节。

4.1 binder_supported_policy中支持的policy,以及不同policy的继承逻辑,线程的policy有几种
4.2 oneway的Binder调用中target_proc->default_priority是在哪里设置的
4.3 怎么最后恢复是in_reply_to->saved_priority,明明是线程B的优先级保存在 t->saved_priority,他们两者是同一个结构体吗?
4.4 HwBinder中对于线程优先级的继承是不是有更加丰富的逻辑。需要去看看HwBinder中IPCThreadState和普通的Binder的IPCThreadState的区别,以及在Binder驱动中对应的实现。
4.5 如果整个过程中出现了异常,是否会存在线程B无法恢复优先级的情况。
4.6 能否改造binder驱动,将cpuset的值继承给线程B。

五、尾巴

Binder真的是一个很有意思的东西,每一个微小的细节都是工程师的智慧,我们在研究Binder的时候更多要去学习他的设计思路,以后我们自己去开发类似的框架或者功能的时候也可以参考设计思路。今天我就抛砖引玉一下,这个玉还需要你们自己去挖掘。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Python 数据处理:NumPy库
✅作者简介:人工智能专业本科在读,喜欢计算机与编程,写博客记录自己的学习历程。 🍎个人主页:小嗷犬的博客 🍊个人信条:为天地立心,为生民立命,为往圣继绝学,为万世开太平。 🥭本文内容:Python 数据处理:NumPy库 ---- Python 数据处理:NumPy库 1.NumPy简介 2.NumPy的ndarray:一种多维数组对象 2.1 创建ndarray 2.2 ndarray的数据类型 2.3 NumPy数组的运算 2.4 基本的索引和切片 2.5 切片索引 2.6 布尔型索引 2
小嗷犬
2022/11/15
5.8K0
Python 数据处理:NumPy库
盘一盘 Python 系列 2 - NumPy (上)
Numpy 是 Python 专门处理高维数组 (high dimensional array) 的计算的包,每次使用它遇到问题都会它的官网 (www.numpy.org). 去找答案。 在使用 numpy 之前,需要引进它,语法如下:
用户5753894
2019/07/05
2.5K0
盘一盘 Python 系列 2 - NumPy (上)
【Python数据分析】NumPy基础,看这一篇就够了!
NumPy是Python的一种开源的数值计算扩展库,包含很多功能,如创建n维数组(矩阵)、对数组进行函数计算、数学计算等等。
Skrrapper
2025/05/09
1780
【Python数据分析】NumPy基础,看这一篇就够了!
我的Python分析成长之路8
Numpy:是Numerical Python的简称,它是目前Python数值计算中最为基础的工具包,Numpy是用于数值科学计算的基础模块,不但能够完成科学计算的任而且能够用作高效的多维数据容器,可用于存储和处理大型矩阵。Numpy的数据容器能够保存任意类型的数据,这使得Numpy可以无缝并快速地整合各种数据。Numpy本身并没有提供很多高效的数据分析功能。理解Numpy数组即数组计算有利于更加高效地使用其他如pandas等数据分析工具。
py3study
2020/01/22
1.6K0
AI基础:Numpy简易入门
NumPy(Numeric Python)提供了许多高级的数值编程工具,如:矩阵数据类型、矢量处理,以及精密的运算库。专为进行严格的数字处理而产生。多为很多大型金融公司使用,以及核心的科学计算组织如:Lawrence Livermore,NASA 用其处理一些本来使用 C++,Fortran 或 Matlab 等所做的任务。
Ai学习的老章
2019/12/05
7290
初探Numpy中的花式索引
Numpy中对数组索引的方式有很多(为了方便介绍文中的数组如不加特殊说明指的都是Numpy中的ndarry数组),比如:
触摸壹缕阳光
2020/04/08
2.4K0
初探Numpy中的花式索引
python的numpy入门简介
arr=np.array(data)    #将列表转为numpy.ndarray  np.array([2,4])
用户7886150
2021/01/07
1.5K0
一份 Numpy 小抄请查收
在numpy中维度(dimensions)叫做轴(axes),轴的个数叫做秩(rank)。如3D空间中一个点的坐标[1,2,3]是一个秩为1的数组,因为它只有一个轴,这个轴长度为3,在下面的例子中数组的秩为2(它有两个维度),第一个维度为2,第二个维度为3。
syy
2020/04/07
4590
Numpy数组
一、NumPy简介 NumPy是针对多维数组(Ndarray)的一个科学计算(各种运算)包,封装了多个可以用于数组间计算的函数。 数组是相同数据类型的元素按一定顺序排列的组合,注意必须是相同数据类型的,比如说全是整数、全是字符串等。 array([1,2,3]) # 数值型数组 array(['w','s','q'],dtype = '<U1') # 字符型数组 二、NumPy 数组的生成 要使用 NumPy,要先有符合NumPy数组的数据,不同的包
见贤思齊
2020/08/05
5.2K0
NumPy从入门到放弃
公众号本文地址:https://mp.weixin.qq.com/s/EocThNWhQlI2zeLcUApsQQ
愷龍
2024/08/09
2420
NumPy从入门到放弃
Python:numpy模块最详细的教程
一、numpy简介 numpy官方文档:https://docs.scipy.org/doc/numpy/reference/?v=20190307135750 numpy是Python的一种开源的数
Python学习者
2023/01/04
1.3K0
【Python】Numpy使用指南
Numpy是用来存储和处理大型矩阵,比Python自身的嵌套列表结构要高效的多,本身是由C语言开发。这个是很基础的扩展,其余的扩展都是以此为基础。
keloli
2018/09/13
9700
【Python篇】NumPy完整指南(上篇):掌握数组、矩阵与高效计算的核心技巧
NumPy的功能不仅限于数值计算,它还支持复杂的数组操作,如切片、索引、线性代数运算等。NumPy通常与SciPy、Pandas等其他科学计算库一起使用,构成了Python科学计算的基础生态。
半截诗
2024/10/09
1.1K0
清晰易懂的Numpy入门教程
Numpy是python语言中最基础和最强大的科学计算和数据处理的工具包,如数据分析工具pandas也是基于numpy构建的,机器学习包scikit-learn也大量使用了numpy方法。本文介绍了Numpy的n维数组在数据处理和分析的所有核心应用。
Python数据科学
2019/08/28
1.6K0
数据分析之numpy
ndarray概述 创建n维数组 接收的是列表类型,所有元素类型必须相同 shape表示各维度大小的元组 dtype表示数组数据类型对象
Python疯子
2018/09/06
1.4K0
数据分析之numpy
Python 数据分析(一):NumPy 基础知识
NumPy(Numerical Python)是一个开源的 Python 科学计算扩展库,主要用来处理任意维度数组与矩阵,通常对于相同的计算任务,使用 NumPy 要比直接使用 Python 基本数据结构要简单、高效的多。安装使用 pip install numpy 命令即可。
Python小二
2020/08/18
9170
数据分析与数据挖掘 - 04科学计算
在人工智能的研发中,其本质就是把一切问题转化为数学问题,所以数学运算非常重要。很多数学运算采用的都是numpy这个库,因为它提供了非常多的科学计算的方法,能让我们的工作变得非常便利,这一章我将从numpy的基本使用开始,逐渐解决掉那些数学问题,让Python与数学能够更紧密的结合在一起。
马一特
2020/09/10
5970
numpy科学计算包的使用2
利用数组进行数据处理 NumPy数组使你可以将许多种数据处理任务表述为简洁的数组表达式(否则需要编写循环)。用数组表达式代替循环的做法,通常被称为矢量化。 矢量化数组运算要比等价的纯Python方式快上一两个数量级 利用数组进行数据处理 将条件逻辑表述为数组运算 传统方式缺点: 列表推导的局限性 纯Python代码,速度不够快。 无法应用于高维数组 解决方法:where # -*- coding: utf-8 -*- import numpy as np import numpy.random as n
听城
2018/04/27
1.8K0
numpy科学计算包的使用2
Python Numpy基础教程
本文是一个关于Python numpy的基础学习教程,其中,Python版本为Python 3.x
oYabea
2020/09/07
8580
小蛇学python(16)numpy高阶用法
如果只是从事简单的数据分析,其实numpy的用处并不是很大。简单了解一下numpy,学好pandas已经够用,尤其是对于结构化或表格化数据。但是精通面向数组的编程和思维方式是成为python科学计算牛人的关键一步。
用户2145057
2018/09/12
9900
小蛇学python(16)numpy高阶用法
相关推荐
Python 数据处理:NumPy库
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档