进程间通信机制Binder

binder 是什么?

  • 进程间通信机制
  • 也是一个驱动
  • Binder.java --> 实现 Ibinder — 跨进程的能力
    在这里插入图片描述
    什么时候用到多进程?
    自己创建的进程:webVIew 视频播放、音乐、大图浏览、推送
    系统服务:打电话,闹钟等等

多进程优点在哪里?

  • 内存 : 一个app ,6G,8G,16G (使用更多)
  • 风险隔离 : 每一个进程,单独的一个app

Linux进程间通信机制有哪些?
管道、信号量、socket 、共享内存等等

Android为什么要增加Binder?
Binder与传统IPC对比
在这里插入图片描述
binder 小于共享内存 ,优于其他IPC(进程间通信)
线程共享区域 — 麻烦 – 同步
身份识别 — PID 多少 — 不靠谱
系统分配 UID — 更安全 – linux — 组id 用户id
系统服务 – 实名 — getsystemservice(context.activity)

进程间是怎么通信的?

进程之间的内存隔离
内存被操作系统划分成两块:用户空间和内核空间,用户空间是用户程序代码运行的地方,内核空间是内核代码运行的地方。为了安全,它们是隔离的,即使用户的程序崩溃了,内核也不受影响。

32位系统,即2^32,即总共可访问地址为4G。内核空间为1G,用户空间为3G。

64位系统,低位:0~47位才是有效的可变地址(寻址空间256T)(用户和内核空间都是256位),高位:48~63位全补0或全补1。一般高位全补0对应的地址空间是用户空间。高位全补1对应的是内核空间。

在这里插入图片描述
在这里插入图片描述
传统IPC传输数据 两次拷贝(拷贝进去,拷贝出来)

在这里插入图片描述

Binder传输数据(拷贝进去)(接收方和内核有共同区域)
在这里插入图片描述

MMAP的原理讲解

Linux通过将一个虚拟内存区域与一个磁盘上的对象关联起来,以初始化这个虚拟内存区域的内容,这个过程称为内存映射(memory mapping)。

对文件进行mmap,会在进程的虚拟内存分配地址空间,创建映射关系。

实现这样的映射关系后,就可以采用指针的方式读写操作这一段内存,而系统会自动回写到对应的文件磁盘上

在这里插入图片描述

用户空间 — 直接操作文件吗??不可以

所有的系统资源管理都是在内核空间中完成的。比如读写磁盘文件,分配回收内存,从网络接口读写数据等等。用户空间通过系统调用让内核空间完成这些功能。

写文件流程:
1、调用write,告诉内核需要写入数据的开始地址与长度
2、内核将数据拷贝到内核缓存
3、由操作系统调用,将数据拷贝到磁盘,完成写入
在这里插入图片描述
内存条 — 物理内存

磁盘 – 物理内存 — 文件

mmap — 能够让虚拟内存和指定物理内存直接联系起来

共享内存 — 怎么实现无需拷贝??
三者全部共享一块数据(发送端、核心区域、接受)

Binder驱动

linux 一切皆文件
驱动也是一个文件

binder_init():

  1. 分配内存
  2. 初始化设备
  3. 放入链表 binder_devices

binder_open():

  1. 创建binder_proc对象
  2. 当前进程信息保存到proc,proc带有进程信息
  3. filp->private_data = proc;
  4. 添加到binder_procs链表中

binder_mmap():

  1. 通过用户空间的虚拟内存大小 — 分配一块内核的虚拟内存
  2. 分配了一块物理内存 — 4KB
  3. 把这块物理内存分别映射到用户空间的虚拟内存和内核的虚拟内存

binder_mmap
struct vm_struct *area; — 内核的虚拟内存
vma — 进程的虚拟内存 — 4M 驱动定的,1M-8k — intent(binder)

binder_ioctl():
读写操作 — BINDER_WRITE_READ — ioctl(BINDER_WRITE_READ)
数据头 —
有效数据 — 拷贝一次

binder的jni注册

目的:java 和 native 能够互相调用 — 系统 — jni

service_manager 大管家(SM)

管理系统服务的(AMS,PMS…)

sm注册

  1. 打开驱动,内存映射(设置大小 128K)
  2. 设置 SM 为大管家(守护进程) — sm 作用 为了管理系统服务
    1. 创建 binder_node 结构体对象
    2. proc --》 binder_node
    3. 创建 work 和 todo --》类似 messageQueue (客户端和服务端两个来读取)
  3. BC_ENTER_LOOPER 命令
    1. 写入状态Loop
    2. 去读数据:binder_thread_read:ret = wait_event_freezable_exclusive(proc->wait, binder_has_proc_work(proc, thread)); 进入等待

sm获取

获取sm的情况:native 的服务注册和获取的时候都会走这个

  1. 注册服务到sm
  2. 通过sm去获取服务 —java

也是服务端

  1. ProcessState::self()->getContextObject(NULL)、
    1. ProcessState::self()
      1. 打开驱动:binder
      2. 设置线程最大数目:15个
      3. mmap – 设置共享内存大小 — (1M-8K) 普通服务的大小
    2. getContextObject
      1. 创建一个BpBinder — 客户端的对象
  2. interface_cast
    1. new BpServiceManager(new BpBinder) == 》 new Proxy(binder==BinderProxy)
    2. remote.transact -->远程调用
    3. remote == BpBinder
  3. java 层 — ServiceManager.addService
    1. new ServiceManagerProxy(new BinderProxy)
    2. mRemote == BinderProxy
    3. BinderProxy.mObject == BpBinder
    4. mRemote.transact == BpBinder.transact
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值