深入解析:Zygote进程与Init进程在系统启动中的协同作用

更新:10-26 民间故事 我要投稿 纠错 投诉

大家好,今天小编来为大家解答以下的问题,关于深入解析: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怎么工作,这个分析能让我更清楚了。

    有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位网友表示赞同!

【深入解析:Zygote进程与Init进程在系统启动中的协同作用】相关文章:

1.动物故事精选:寓教于乐的儿童故事宝库

2.《寓教于乐:精选动物故事助力儿童成长》

3.探索动物旅行的奇幻冒险:专为儿童打造的童话故事

4.《趣味动物刷牙小故事》

5.探索坚韧之旅:小蜗牛的勇敢冒险

6.传统风味烤小猪,美食探索之旅

7.探索奇幻故事:大熊的精彩篇章

8.狮子与猫咪的奇妙邂逅:一场跨界的友谊故事

9.揭秘情感的力量:如何影响我们的生活与决策

10.跨越两岸:探索彼此的独特世界

上一篇:高典原子最新版下载与安装指南 下一篇:2024年度热门歌曲免费下载:流行音乐百度云资源汇总