【安卓BInder底层1】Linux常见跨进程通信方式

Linux 中跨进程通信方式有很多种,安卓framework中主要使用到了四种。

  • 管道

  • Socket

  • 内存共享

  • 信号

一、管道

1、特点

a、半双工的,即单项的。

管道描述符数据只能往一个方向流,要么是读,要么是写。
如果需要既能读又能写,那么管道需要两个文件描述符。Linux还是很人性化的,提供了api pipe(fds),这个api可以生成一对描述符,一个用于读,一个用于写。


 int result = pipe(fd) //  创建管道

     fd[0] // 数组代表读端
     fd[1]// 数组代表写端
     

b、有名管道&无名管道

管道分为有名管道,无名管道。
无名管道一般是在父子进程之间进行通信。有名管道只要双方都知道管道名字也可以进行通信。

c、可以和epoll相结合监听管道读写事件。

d、进程内可以用(无名管道),进程间也可以用(有名管道),在数据不大的跨进程通信时非常好用。

2、 Android framework中的使用

Looper的native层使用到了管道, 但是在安卓4.0之后换成了evendfd。
管道使用起来还是很方便的,主要可以可和epoll结合起来监听读写事件。
在这里插入图片描述>1、通过pipe创建一对管道描述符读、写。
2、创建epoll监听读的文件描述符
3、其他线程往当前线程写信息时当前线程读描述符就会监听到。

在这里插入图片描述

epoll对读端事件的监听:
1、epoll_wait 阻塞等待事件,返回值是触发事件的个数。
2、for循环中处理事件,我们这里最关注的是读端事件。
3、如果事件是可读事件,通过awoken吧事件从管道读出。唤醒当前线程。
ps:这里不管写端写了什么,都全部从管道读出,否则管道数据满了其他端往管道写数据失败。至于怎么往管道写数据呢,是其他线程调用wake函数通过write 往写端描述符写数据。

二、本地Socket

1、特点

a、全双工的。

即可读,又可写,不用再区分读端,写端。

b、可以用在两个无亲缘关系的进程间。

创建时指定路径,只需要把路径公开给别人,就可以给别人通信了。

2、 framework中的使用

Zygote进程创建Sever端Socket,不断loop循环,去检测有无ams端发送过来新的socket连接请求,或者检测有无ams 发送来的socket消息。

在这里插入图片描述
在这里插入图片描述

1、poll用来检测有无我们关注的事件
2、有关注的事件分两种情况:

1、有新的连接:处理新的连接
2、有新的消息:处理发送过来新的数据。具体是如何处理的呢?首先从socket中读取参数,然后根据参数执行相应指令。主要是创建应用进程,进程创建成功后吧进程pid写给对方。

三、共享内存

管道、Socket都有个缺点,传输的数据量不能太大,否则性能会很糟,二者都涉及到两次拷贝。

1、共享内存特点

a、很快,不需要多次拷贝。

拿到描述符,吧描述符同时映射到两个进程的内存空间即可。这样一个进程往描述符写数据,另一个进程就能读到。

b、进程间无需存在亲缘关系。

只要拿到文件描述符即可,文件描述符可以跨进程传递的。

2、 framework中的使用

一般用在进程间大数据传输的如图片的相关,如有个memoryFile工具类。

在这里插入图片描述

1、通过native函数在native层 调用ashmem_create_regin创建匿名共享内存。返回个描述符。
2、通过native函数在native层 调用mmap 给描述符映射到当前进程空间。当前进程空间地址为mAddress

在这里插入图片描述

memoryFile的读写:
1、读:吧数据从共享内存读到应用层的buffer中。
ps:setByteArrayRegin就是把buffer的数据拷贝到运行时数组中。
2、写:功能与读相反。

四、信号

1、信号的特点

a、单向的。

信号发出后,其他进程是否处理发出信号的进程无法得知。

b、只能带个信号,不能带别的参数

c、知道进程的pid就可以给进程发信号,也可以一次给一群进程发信号。

给其他进程发信号是需要权限的,要么具有系统权限,要么两进程具有相同的uid.
这里需要注意,虽然所有的进程都是由zygote进程fork出来的,具有相同的uid,但是进程被创建之后一般都会被重新设置uid的。

2、信号的应用:通知杀死某一进程

zygote关注的sigchld 信号。子进程死亡后zygote进行清理。

在这里插入图片描述

1、给指定pid的进程发送SINGAL_KILL 信号
2、Zygote关注的信号SIGXHLD信号,当子进程退出时会发送这个信号,Zygote收到信号后会回收子进程资源表信息。防止僵尸进程产生。

The end

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值