title | date | categories | tags | description | ||
---|---|---|---|---|---|---|
系统启动问题 |
2018-10-08 |
|
|
|
2 什么是写时拷贝(copy-on-write)?
写时拷贝copy_on_write技术: fork的实现是使用copy_on_write技术实现的,它是一种可以推迟甚至避免拷贝的技术,内核此时并不复制整个进程的地址空间,而是让父子进程共享同一个地址空间,只有在子进程真正需要写入数据的时候才会赋值地址空间,从而使得每个进程拥有自己的进程空间,也就是说资源的复制是在需要写入数据的时候才会进行,在此之前只会以只读的形式共享。
3 孤儿进程和僵尸进程是什么?
fork系统调用之后,父子进程将交替执行,执行顺序不定。如果父进程先退出,子进程还没退出那么子进程的父进程将变为init进程(托孤给了init进程)。(注:任何一个进程都必须有父进程)如果子进程先退出,父进程还没退出,那么子进程必须等到父进程捕获到了子进程的退出状态才真正结束,否则这个时候子进程就成为僵进程(僵尸进程:只保留一些退出信息供父进程查询).
4 system_server 为什么要在 Zygote 中启动,而不是由 init 直接启动呢?
Zygote 作为一个孵化器,可以提前加载一些资源,这样 fork() 时基于 Copy-On-Write 机制创建的其他进程就能直接使用这些资源,而不用重新加载。比如 system_server 就可以直接使用 Zygote 中的 JNI函数、共享库、常用的类、以及主题资源。
5 为什么要专门使用 Zygote 进程去孵化应用进程,而不是让 system_server 去孵化呢?
system_server 相比 Zygote 多运行了 AMS、WMS 等服务,这些对一个应用程序来说是不需要的。另外进程的 fork() 对多线程不友好,仅会将发起调用的线程拷贝到子进程,这可能会导致死锁,而system_server 中肯定是有很多线程的。
6 多线程的进程fork调用为什么会导致死锁?
多线程的进程的fork调用:复制整个用户空间的数据(通常使用 copy-on-write 的策略, 所以可以实现的速度很快)以及所有系统对象,然后仅复制当前线程到子进程。这里:所有父进程中别的线程,到了子进程中都是突然蒸发掉的假设这么一个环境,在 fork 之前,有一个子线程 lock 了某个锁,获得了对锁的所有权。fork 以后,在子进程中,所有的额外线程都人间蒸发了。而锁却被正常复制了,在子进程看来,这个锁没有主人,所以没有任何人可以对它解锁。当子进程想 lock 这个锁时,不再有任何手段可以解开了。程序发生死锁
7 Zygote 为什么不采用 Binder 机制进行 IPC 通信?
Binder 机制中存在 Binder 线程池,是多线程的,如果 Zygote 采用 Binder 的话就存在上面说的fork() 与 多线程的问题了。其实严格来说,Binder 机制不一定要多线程,所谓的 Binder 线程只不过是在循环读取 Binder 驱动的消息而已,只注册一个 Binder 线程也是可以工作的,比如 service manager就是这样的。实际上 Zygote 尽管没有采取 Binder 机制,它也不是单线程的,但它在 fork() 前主动停止了其他线程,fork() 后重新启动了。
———————————————— 版权声明:本文为CSDN博主「Zhou Jiang」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/oman001/article/details/108914711