大家好,今天小编来为大家解答以下的问题,关于深入解析:Zygote进程与Init进程在系统启动中的协同作用,这个很多人还不知道,现在让我们一起来看看吧!
2.1zygote服务配置
服务zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
主类
优先级-20
根用户
组根readproc
套接字zygote 流660 根系统
onrestart 写入/sys/android_power/request_state 唤醒
onrestart 写入/sys/power/state
onrestart 重新启动音频服务器
onrestart 重新启动cameraserver
onrestart 重新启动媒体
onrestart 重新启动网络
onrestart 重新启动wificond
writepid /dev/cpuset/foreground/tasks 从上面我们可以知道service通知init进程创建一个名为zygote的进程。进程路径为/system/bin/app_process64。以下是zygote服务的参数,类为main。
2.2,init进程对zygote的启动
我们知道init.rc解析后,会一一执行action。 init.rc文件中的一个action有以下配置
在非加密的情况下
类开始主//1
class_start Late_start动作的命令有class_start main,表示启动那些classname为main的服务。 zygote服务的classname是main,所以它也会被启动。通过命令和函数的绑定,我们了解到action的class_start执行的函数就是/system/core/init/builtins.cpp中的do_class_start函数。
///system/core/init/builtins.cpp
静态int do_class_start(const std:vector args) {
ServiceManager:GetInstance()。
ForEachServiceInClass(args[1], [] (Service* s) { s-StartIfNotDisabled(); });
返回0;
代码执行逻辑:从ServiceManager保存的所有之前解析的Service表中找到classname为main的service,并让该service执行StartNotDisabled()函数
///system/core/init/service.cpp
布尔服务:StartIfNotDisabled(){
if (!(flags_ SVC_DISABLED)) { //判断init.rc配置,init.rc没有设置disabled选项
返回开始(); //服务启动
} 别的{
flags_ |=SVC_DISABLED_START;
}
返回真;
更多配置用于判断是否启动服务。这个配置启动是是否允许服务重新启动。如果允许,则服务终止时会通过进程终止信号逐层处理找到该进程,清除该进程的所有信息,并重新启动该进程。
布尔服务:Start() {
//启动服务会将其从禁用或重置状态中删除,并且
//如果它处于重新启动状态,则立即将其从重新启动状态中取出。
flags_=(~(SVC_DISABLED|SVC_RESTARTING|SVC_RESET|SVC_RESTART|SVC_DISABLED_START));
//运行进程不需要额外的工作--- 如果它们位于
//退出过程中,我们确保它们会立即重新启动
//退出时,除非它们是ONESHOT。
//如果服务已启动,则不执行任何操作。
if (flags_SVC_RUNNING) {
返回假;
}
bool need_console=(flags_SVC_CONSOLE);
如果(需要控制台){
如果(console_.empty()){
控制台_=默认控制台;
}
.
//判断要启动的服务对应的执行文件是否存在。如果不存在,则不会执行。
struct stat sb;
if (stat(args_[0].c_str(), sb)==-1) {
PLOG(ERROR) "找不到"" args_[0] "",禁用"" name_ """;
flags_ |=SVC_DISABLED;
返回假;
}
std:字符串scon;
if (!seclabel_.empty()) {
scon=seclabel_;
} 别的{
LOG(INFO) "服务的计算上下文"" name_ """;
scon=ComputeContextFromExecutable(name_, args_[0]);
如果(scon==""){
返回假;
}
}
LOG(INFO) "正在启动服务""name_"".";
pid_t pid=-1;
如果(命名空间_标志_){
pid=克隆(nullptr,nullptr,namespace_flags_ | SIGCHLD,nullptr);
} 别的{
pid=fork(); //1 关键点是通过fock创建子进程。
}
如果(pid==0){
掩码(077);
````
//根据要求,设置我们的gid、补充gids、uid、上下文和
//优先事项。失败时中止。
设置进程属性();
std:向量strs;
ExpandArgs(args_, strs);
if (execve(strs[0], (char**) strs[0], (char**) ENV) 0) { //2 焦点,开始子进程的执行。
PLOG(ERROR) "无法执行("" strs[0] "")";
}
_退出(127);
}
.
NotifyStateChange("运行");
返回真;
start()函数比较长。这里我们只关心几点。剩下的就是一些参数和控制台操作。
注1:这里是重点。 init进程通过fock函数启动子进程服务,创建子进程。也就是说init启动的服务是一个进程,zygote也是一个进程。注2:这里是进程实际执行开始的地方,即告诉进程要执行什么,即zygote进程从这里开始执行。init进程在fock和execve之后创建一个新的子进程用于执行。也就是说下面的介绍——2.3启动zygote进程——实际上是zygote进程的一部分,只是进程的main函数没有执行。
2.3启动zygote过程
execve(strs[0], (char) strs[0], (char) ENV)函数主要供init进程使用,通过调动app_main.cpp的main函数中AppRuntime的start方法来启动zygote。
//位置/framework/base/cmds/app_process/app_main.cpp
int main(int argc, char* const argv[])
{
. //做了很多配置和参数操作
而(我argc){
const char* arg=argv[i++];
//下面根据不同的线程设置不同的标记位
if (strcmp(arg, "--zygote")==0) {
合子=真; //如果是zygote进程,zygote为true
好的名称=ZYGOTE_NICE_NAME;
} else if (strcmp(arg, "--start-system-server")==0) {
启动系统服务器=true; //如果是SystemServer进程,SystemServer为true
} else if (strcmp(arg, "--application")==0) {
应用=真; //如果是应用程序进程,application为true
} else if (strncmp(arg, "--nice-name=", 12)==0) {
NiceName.setTo(arg + 12);
} else if (strncmp(arg, "--", 2) !=0) {
类名.setTo(arg);
休息;
} 别的{
- 我;
休息;
}
}
……
如果(受精卵){
//如果运行在zygote进程中,则通过runtim启动进程
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
} else if (类名) {
//其他人有更多的类名来执行该过程。
runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
} 别的{
fprintf(stderr, "Error: 没有提供类名或--zygote。n");
app_usage();
LOG_ALWAYS_FATAL("app_process: 没有提供类名或--zygote。");
}这里,该过程是通过根据属性分析和组合各种参数来开始的。这就是合子的启动方式。 runtime.start("com.android.internal.os.ZygoteInit", args, zygote);是AndroidRuntime.cpp中执行的代码。
void AndroidRuntime:start(const char* className, const Vector 选项, bool zygote)
{
……
/* 启动虚拟机*/
JniIncation jni_incalling;
jni_inplication.Init(NULL);
JNIEnv* 环境;
if (startVm(mJavaVM, env, zygote) !=0) { //启动Java虚拟机
返回;
}
onVmCreated(env);
/*
* 注册android函数。
*/
if (startReg(env) 0) { //将JNI方法注册到Java虚拟机中,以便Java和c++可以互调
ALOGE("无法注册所有android nativen");
返回;
}
/*
* 我们想要使用一个带有参数的字符串数组来调用main()。
* 目前我们有两个参数,类名和选项字符串。
* 创建一个数组来保存它们。
*/
jclass 字符串类;
jobobjectArray strArray;
jstring 类名Str;
stringClass=env-FindClass("java/lang/String");
断言(stringClass!=NULL);
strArray=env-NewObjectArray(options.size() + 1, stringClass, NULL);
断言(strArray!=NULL);
//从上面我们知道classname是传入参数"com.android.internal.os.ZygoteInit",将classname转换成Java中的String字符串。
classNameStr=env-NewStringUTF(className);
断言(classNameStr!=NULL);
env-SetObjectArrayElement(strArray, 0, classNameStr);
for (size_t i=0; i options.size(); ++i) {
jstring optionsStr=env-NewStringUTF(options.itemAt(i).string());
断言(optionsStr!=NULL);
env-SetObjectArrayElement(strArray, i + 1, optionsStr);
}
//代替。在classnam中加上/以便jvm可以识别它。
char* 斜杠类名=toSlashClassName(类名);
jclass startClass=env-FindClass(slashClassName);
if (startClass==NULL) {
ALOGE("JavaVM 无法定位类"%s"n",lashClassName);
/* 继续前进*/
} 别的{
//在类名中查找main方法。
jmethodID startMeth=env-GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
if (startMeth==NULL) {
ALOGE("JavaVM 无法在"%s" 中找到main()n", className);
/* 继续前进*/
} 别的{
//这里调用classname的main方法。
env-CallStaticVoidMethod(startClass, startMeth, strArray);
#如果0
if (env-ExceptionCheck())
threadExitUncaughtException(env);
#endif
}
}
自由(斜杠类名);
ALOGD("正在关闭虚拟机n");
if (mJavaVM-DetachCurrentThread() !=JNI_OK)
ALOGW("Warning: 无法分离主线程n");
if (mJavaVM-DestroyJavaVM() !=0)
ALOGW("Warning: VM 未完全关闭n");
好了,本文到此结束,如果可以帮助到大家,还望关注本站哦!
【深入解析:Zygote进程与Init进程在系统启动中的协同作用】相关文章:
用户评论
讲道理,我一直很疑惑zygote怎么工作,这个分析能让我更清楚了。
有10位网友表示赞同!
感觉zygote和init都是Android系统里很重要的进程啊!
有6位网友表示赞同!
现在终于明白为啥zygote会被重复使用,效率很高嘛!
有5位网友表示赞同!
了解了zygote启动流程,对Android系统的架构有了新的认识。
有20位网友表示赞同!
这篇文章解释得很详细,我以前没怎么关注这些细节。
有20位网友表示赞同!
原来init进程还要负责启动zygote呢,太强了!
有11位网友表示赞同!
终于不用再猜zygote是怎么运作的了!
有7位网友表示赞同!
这种机制让人感觉很巧妙,能够节省系统资源。
有20位网友表示赞同!
学到新知识了! 之前都不知道zygote工作原理这么复杂。
有10位网友表示赞同!
这篇文章让我对Android系统的底层认识更加深入。
有11位网友表示赞同!
原来init进程的功能这么多啊!
有14位网友表示赞同!
学习一下这些技术内容,很有帮助,感谢作者分享!
有13位网友表示赞同!
以后再遇到有关zygote的问题可以参考一下这篇分析。
有16位网友表示赞同!
这篇文章的图解非常清晰,很容易理解。
有6位网友表示赞同!
对于 Android 开发者来说,了解zygote进程的启动机制很重要啊!
有15位网友表示赞同!
很有意思的分析,让我对系统架构有了更深的理解。
有13位网友表示赞同!
这个知识点挺有价值的,应该去好好学习一下!
有15位网友表示赞同!
文章语言很通俗易懂,即使不了解计算机原理的人也能读懂。
有11位网友表示赞同!
这篇文章让我对Android系统的进程管理有了更深入的理解。
有10位网友表示赞同!