Android Binder

作者: coder_斛律光 | 来源:发表于2018-04-11 16:23 被阅读34次

    进程间通讯

    1. 操作系统的进程间通讯

    进程间通讯 根据名字描述就是进程之间的信息交换
    进程间的互斥和同步 由于交换的信息量少 被归结为低级的进程间通讯

    高级通讯机制可以分成三类

    一. 共享存储器系统
    1. 基于共享数据结构的方式

    通过公用某些数据结构来进行通信 低效的 适用于少量的信息传递

    1. 基于共享存储区的方式
      1. 向系统申请一个共享存储区的分区 拿到分区的描述符
      2. 通过描述符把申请的共享分区连接到自己的进程
      3. 进行读写操作 实现数据传递
    二. 消息传递系统
    1. 进程间的通信是以格式化的消息(message)为单位的

      message 操作系统提供的一组通信命令

      实现了大量数据的传递 隐藏了通信的细节

    2. 实现方法

    直接通信

    利用OS提供的发送命令 直接将消息发送给目标进程
    Send(Receiver,message) Receive(Sender,message) 发送进程和接收进程需要显示的提供对方的标识符

    间接通信

    通过共享数据结构的实体 暂存发送的消息 允许接收方随时读取 类似信箱的功能 可以非实时的

    1. 信箱的创建和撤销 消息传递系统 进程调用的都是系统的原语 创建时提供名字 属性(公用 私有 共享)
    2. 消息发送和接收 必须使用共享信箱 Send(mailbox,message) Receive(mailbox,message)

    信箱的类型 属性决定的

    1.私有的

    进程的一部分 进程消失就消失 只有创建者可以读取 其他的只能发送

    1. 公共的

    系统创建的 系统中所有的核准进程使用 发送和读取 系统运行期间都存在

    1. 共享的

    信箱某进程创建 发送和接收之间存在4种关系

    1对1
    1对多
    多对1
    多对多

    三. 管道通信系统

    共享文件 一个读的进程 一个写的进程 连接起来实现进程间通讯 pipe
    管道机制需要有三方面的协调能力

    1. 互斥
    2. 同步
    3. 确定对方是否存在

    linux下的进程间通讯

    IPC

    Inter-Process Communication

    1. 管道 pipe
      什么是管道 通过一个进程的输出连接到另一个进程的输入 这就是管道
      linux 下是怎么实现的 记住两个函数
    
    FILE * popen(const char * command , const char * opend_mode);
    
    int pclose(FILE * stream_to_close); 
    
    

    popen函数 第一个参数是你要启动的进程名 第二个参数opend_mode是打开方式(只有r w两种)

    如果是r的时候 被启动的进程的输出可以被当前进程使用 popen函数的返回值是一个FILE* 文件流指针 可以通过fread 方法来读取被调用程序的输出

    pclose 函数 popen函数启动的进程结束的时候 通过pclose 关闭与之关联的文件流 返回值在启动的进程结束后才得到 如果调用pclose的时候 被启动的进程仍在进行 那么pclose的调用将等待结果

    pipe 是popen的底层实现

    1. 命名管道 FIFO

      这东西有点像socket 只不过文件是存在的了 比如A进程想访问B进程 那么在B进程中创建一个文件

      并将内容写入

      然后在A进程中打开并读取这个文件的内容 A进程也可以先进行打开读取 他会阻塞直到有数据才会继续read

    int mkfifo(const char * filename,mode_t mode);

    int mknod(const char * filename,mode_t mode | S_IFIFO, (dev_t 0));

    通过上面的函数创建fifo管道 与pipe对比 FIFO是以命名文件的形式存在的 pipe是文件描述符 所以操作他的时候也必须是open和close 打开关闭文件

    进程间通讯机制

    IPC

    Inter-Process Communication

    以下几个概念是进程间通讯的机制

    1. 信号量 特殊的符号量 只允许对他进行等待 和 发送信号这两种操作

    作用是对临界代码拥有资源独占式的访问权

    1. 共享内存 允许两个不相关的程序 访问同一块共享内存 程序员负责锁的问题

    2. 消息队列

    通过 int msgget(key_t key,int msgflag) 函数来创建和访问一个消息队列 第一个名字 第二个权限

    1. int msgget(int key_t key,int msgflag) 创建一个消息队列 返回值是消息队列标识

    参数1 给消息队列命名
    参数2 权限值

    1. int msgsnd(int msgid,const void * msg_ptr, size_t msg_sz,int msgflag) 发送消息

    参数1 是通过get时候的返回值也就是消息的标识符
    参数2 一个准备接收消息的指针
    参数3 消息的长度
    参数4 消息的接收优先级

    1. msgrcv(int msgid,const void * msg_ptr, size_t msg_sz,long int msgtype, int msgflag) 消息队列中获取消息

    参数1 是通过get时候的返回值也就是消息的标识符
    参数2 一个准备接收消息的指针
    参数3 消息的长度
    参数4 消息的接收优先级
    参数5 消息中没有相应类型的消息可以接收时发生

    1. msgctl(int msgqid, int command,struct msqid_ds *buf)

    参数1 消息队列的标识符
    参数2 采取的动作 删除 赋值等
    参数3 参数2操作的结构体

    android Binder

    android binder机制困扰我好多天 我一直也没弄明白 我学习的方式 是通过看书 跟着书里对binder的源码进行分析 这种学习方式对我来说是错的 先说下错的学习思路

    1. 首先书中介绍了android binder机制的几个组成部分
    1. /dev/binder 驱动 dev下放的大多数都是驱动
    2. service manger 作用是守护进程 并充当client 和 server的服务器
    3. server 你要交互的服务进程 或者你自己的写的service
    4. client 你自己的写的进程

    书中根据binder.c service manger.c 各种源码分析 给你讲解 service manger 怎么成为 dev/binder的守护进程 怎么又成了整个server 和client的服务端的 讲了好多的结构体 然后我就蒙了

    后来学习的过程总结

    1. 首先我要干啥 进程间通讯呀
    1. 我们已知的条件 IBinder 这个比较基础的 大家都清楚
    1. bindservice 时候 在onServiceConnection中 可以得到这个IBinder对像
    2. 你自己定义的service里 在onBInd 方法中得到IBInder 对象

    根据上边我们熟悉的东西 我们可以大概知道 BInder机制共享的是对象
    那和上边的几种进程间通讯对比下

    1. 共享寄存器

      跟他有点像 BInder是对象 他是共享一个数据结构或者共享一个寄存器的分区 通过对他的读写来进行通信

    2. 消息传递系统

      通过系统的原语 进行send receive 这种 需要知道对方进程的标识符
      linux下是通过申请队列 然后写消息 接收消息
      和他也有相似的地方

    3. 管道

    进程之间 未命名的只能是父子关系的进程通信 通过打开一个文件描述符
    命名管道 是通过指定的进程标识符 可以进行通信

    1. Socket

    通过协议控制

    相关文章

      网友评论

        本文标题:Android Binder

        本文链接:https://www.haomeiwen.com/subject/zxkahftx.html