请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

老师可以把课后题的答案分享一下吗

正在回答

2回答

风语 2019-04-30 22:13:24

同学你好,

关于第一个问题,

孵化应用进程这种事为什么不交给SystemServer来做,而专门设计一个Zygote?

我们知道,应用在启动的时候需要做很多准备工作,包括启动虚拟机,加载各类系统资源等等,这些都是非常耗时的,如果能在zygote里就给这些必要的初始化工作做好,子进程在fork的时候就能直接共享,那么这样的话效率就会非常高。这个就是zygote存在的价值,这一点呢systemServer是替代不了的,主要是因为systemServer里跑了一堆系统服务,这些是不能继承到应用进程的。而且我们应用进程在启动的时候,内存空间除了必要的资源外,最好是干干净净的,不要继承一堆乱七八糟的东西。所以呢,不如给systemServer和应用进程里都要用到的资源抽出来单独放在一个进程里,也就是这的zygote进程,然后zygote进程再分别孵化出systemServer进程和应用进程。孵化出来之后,systemServer进程和应用进程就可以各干各的事了。

再看第二个问题,

Zygote的IPC通信机制为什么不采用binder?如果采用binder的话会有什么问题么?

关于为什么不采用binder,有两个原因,

先看第一个原因,我们可以设想一下采用binder调用的话该怎么做,首先zygote要启用binder机制,需要打开binder驱动,获得一个描述符,再通过mmap进行内存映射,还要注册binder线程,这还不够,还要创建一个binder对象注册到serviceManager,另外AMS要向zygote发起创建应用进程请求的话,要先从serviceManager查询zygote的binder对象,然后再发起binder调用,这来来回回好几趟非常繁琐,相比之下,zygote和systemServer进程本来就是父子关系,对于简单的消息通信,用管道或者socket非常方便省事,如果对管道和socket不了解的话,可以参考APUE和UNP这两本书。

再看第二个原因,如果zygote启用binder机制,再fork出systemServer,那么systemServer就会继承了zygote的描述符以及映射的内存,这两个进程在binder驱动层就会共用一套数据结构,这显然是不行的,所以还得先给原来的旧的描述符关掉,再重新启用一遍binder机制,这个就是自找麻烦了。

总的来说呢,对于轻量级的跨进程消息通信,没必要杀鸡用牛刀,普通的管道或者socket足矣。


15 回复 有任何疑惑可以回复我~
  • 老师,您好,我还是不明白,1.为啥binder就复杂了,Socket就简单了?2.binder描述符合映射的内存会被继承,那么Socket相关的东西也会被继承,SystemServer就不需要关闭Socket相关的东西吗?
    回复 有任何疑惑可以回复我~ 2019-12-13 15:22:42
慕村9285654 2019-04-30 22:23:25

Zygote 与 Ams不用binder通讯的原因有没有多线程死锁的问题呢?感觉fork的时候如果有锁 复制的新进程走到有锁的地方就卡死了

5 回复 有任何疑惑可以回复我~
  • 风语 #1
    你说的对,多线程fork确实可能会死锁,所以zygote为了避免这个问题,在fork的时候给其它的线程都停掉了,另外呢,如果zygote采用binder机制的话,比较好的方式就是直接给主线程注册成binder线程,可以参考ServiceManager的做法,这样也就不会有多线程的问题了。启动进程这种事是个重量级的任务,zygote没必要开多个线程同时去处理好几个任务。
    回复 有任何疑惑可以回复我~ 2019-04-30 22:56:57
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信