Android Framework学习之跨进程通信方式

2022-12-22  本文已影响0人  一只二凡子

Android Framework用到了哪些IPC方式?

Linux IPC 方式

1.管道, 2. Socket, 3. 共享内存, 4. 信号

管道通信

半双工的,单向的,要么只能读,要么只能写,要想实现既能读又能写,管道得有两个描述符。linux API pipe(fds) 可以生成一对描述符,一个用来读,一个用来写。

一般是在父子进程之间使用(无名管道),如果是有名管道的话,只要两个进程知道这个管道的名字就可以通信了。

管道也可以用于同一进程

pipe(fd): 生成管道的一对描述符,fd[1]是用来写的,fd[0]是用来读的。fork出来的子进程会继承这个管道的一对描述符

close(fd[0]): 关闭父进程读描述符

close(fd[1]): 关闭子进程写描述符

java层Looper在native层对应的Looper,这是android4.4版本的代码,后面版本用的是EventFd

Looper里用到了管道

管道适用于数据量不大时的跨进程通信

Socket通信(非网络Socket)

全双工的,即可度也可写

两个进程之间无需存在亲缘关系

AMS与Zygote的通信就是用的Socket

main: Zygote 的入口函数

registerZygoteSocket:创建一个本地的Socket

Os.poll: 检测有没有我们关注的事件发生

runOnce:从Socket读取参数,根据参数执行相应的指令,主要是创建应用进程,进程创建完后,将pid写给对方

共享内存

很快,不需要多次拷贝(管道和Socket都不能传输大数据量,太大会导致性能下降,因它们涉及至少两次拷贝),通过文件描述符,把它同时映射到两个进程的内存空间,这样一个进程写,另一个进程就能读到

进程之间不用存在亲缘关系,只要能拿到文件描述符,文件描述符是可以跨进程传递的

共享内存主要用于大数据量的传递,比如图像相关的

MemoryFile是一个工具类, 封装了android 的 ashmem机制(匿名共享内存)

ashmem_create_region:在native层创建了一个快匿名共享内存

mmap:将描述符mFD映射到当前进程的一块内存空间,这个内存空间的地址是mAddress,

SetByteArrayRegion:将buffer的数据copy到java数组里

GetByteArrayRegion:将java层的数组 copy到native的buffer里

信号(需要root权限,或者与别的进程UID相同才能发信号)

单向的,发出去之后怎么处理是别人的事

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

知道进程pid就能发信号了,也可以一次给一群进程发信号

应用进程都是Zygote fork出来的,uid与Zygote的uid一样,应用进程会马上修改uid

SetSigChildHandler:Zygote关注的SIGCHLD信号,Zygote启动了子进程后需要关注这个子进程退出了没有,如果退出了Zygote需要即使将其资源回收掉

上一篇下一篇

猜你喜欢

热点阅读