zygote進(jìn)程啟動

1 啟動SytemServer 2 孵化應(yīng)用進(jìn)程

一般進(jìn)程啟動,會首先做一些準(zhǔn)備工作,然后進(jìn)進(jìn)入一個Looper循環(huán),來不停的接收消息,消息來源1 可能是通過socket 發(fā)過來的2 有可能是MessageQueue里面的消息3 有可能是Binder 驅(qū)動發(fā)送過來的消息

Zygote 進(jìn)程,系統(tǒng)服務(wù)進(jìn)程,app 進(jìn)程都是如此.

zygote進(jìn)程如何啟動的?

通過init進(jìn)程(Linux啟動之后,用戶空間的第一個進(jìn)程),init進(jìn)程啟動之后,會加載啟動配置文件init.rc,看一下init.rc里面定義了哪些系統(tǒng)服務(wù)需要啟動,Zygote就是要啟動的服務(wù)之一,還包括sm進(jìn)程等,init進(jìn)程通過fork+execve系統(tǒng)調(diào)用啟動了Zygote進(jìn)程

service?zygote?/system/bin/app_process64?-Xzygote /system/bin --zygote --start-system-server// 可以看到service name 是zygote ,通過APP_process 程序啟動,后面為參數(shù)

? ? class main

? ? priority -20

? ? user root

? ? group root readproc

?socket?zygote stream?660?root?system

onrestart?write?/sys/android_power/request_state wake

onrestart?write?/sys/power/state?on

? ? onrestart restart audioserver

? ? onrestart restart cameraserver

? ? onrestart restart media

? ? onrestart restart netd

? ? onrestart restart wificond

? ? writepid /dev/cpuset/smart-system/tasks

? ? onrestart restart surfaceflinger

啟動進(jìn)程

fork函數(shù)

#include<sys/types.h>

#include<unistd.h>

pid_t fork(void);

這個函數(shù)雖然執(zhí)行一次,但是會返回2次的不同的值。就是在這里一個進(jìn)程會變?yōu)閮蓚€進(jìn)程,原本的進(jìn)程叫做父進(jìn)程,新的進(jìn)程叫子進(jìn)程。父進(jìn)程中返回的值為子進(jìn)程的ID號。而子進(jìn)程中返回的是0.

execve函數(shù)

#include<unistd.h>

int?execve(const?char?*file,?const?char?*argv[]?const?char?*envp[]);

參數(shù)1:要執(zhí)行的文件

參數(shù)2:執(zhí)行文件后面跟著的參數(shù),可以是NULL;

參數(shù)3:環(huán)境變量

Fork + handle

pid_t?pid;

? ? ? ? pid = fork();

?if(pid >?0) ?{

// parent process ? ? ? ? ? ??

}?else?if(pid ==?0) {

// child process

? ? ? ? }

?return?0;

Fork + execve

pid_t?pid;

? ? ? ? pid = fork();

?if(pid >?0) ?{

// parent process ? ? ? ? ? ??

}?else?if(pid ==?0) {

// child process

execve(patch,argv,env)

? ? ? ? }

?return?0;

默認(rèn)情況 下創(chuàng)建的子進(jìn)程,繼承了父進(jìn)程的所有資源,如果調(diào)用了execve 加載頂一個二進(jìn)制程序的話,繼承的父進(jìn)程的資源會被清除掉.

SIGCHLD 信號處理

Fork 子進(jìn)程時,父進(jìn)程需要關(guān)注這個信號,父進(jìn)程fork子進(jìn)程,如果子進(jìn)程掛了,那么父進(jìn)程會收到SIGCHLD信號,例如init進(jìn)程fork Zygote進(jìn)程,如果Zygote進(jìn)程掛了,init進(jìn)程就會收到信號,去重啟Zygote進(jìn)程

啟動之后

Zygote進(jìn)程啟動之后做了什么工作?

Zygote進(jìn)程入口是在app_main.cpp main函數(shù)執(zhí)行的,天生是Native的,在Native層做了三件事情:

1 啟動Android虛擬機(jī)

2 注冊Android的JNI函數(shù)

3 進(jìn)入Java世界

看一下app_main.cpp 的main函數(shù),入口函數(shù)

int?main(int?argc,?char*?const?argv[]){

.....

if?(zygote) {

? ? runtime.start("com.android.internal.os.ZygoteInit", args, zygote);

}?else?if?(className) {

? ? runtime.start("com.android.internal.os.RuntimeInit", args, zygote);

}?

.....

看一下AndroidRuntime::start// ?AndroidRuntime.cpp

void?AndroidRuntime::start(const?char* className,?const?Vector& options,?boolzygote)

{

...

?if?(startVm(&mJavaVM, &env, zygote) !=?0) {

?return;

? ? }

? ? onVmCreated(env);

?/*

? ? ?* Register android functions.

? ? ?*/

?if?(startReg(env) <?0) {

? ? ? ? ALOGE("Unable to register all android natives\n");

?return;

? ? }

...

}

看一下startVm 方法

int?AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv,?bool?zygote)

{

.....

if?(JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) <?0) {//調(diào)用JNI_CreateJavaVM 創(chuàng)建虛擬機(jī), javaVM 是在Zygote進(jìn)程中創(chuàng)建好了,app進(jìn)程是通過Zygote進(jìn)程孵化出來了,所有就有javaVM了

? ? ALOGE("JNI_CreateJavaVM failed\n");

?return?-1;

}

Zygote的Java世界

1 預(yù)加載資源,為了將來孵化子進(jìn)程時可以繼承給他們(常用類,主題,共享庫等資源)

2 啟動SytemServer進(jìn)程

3 進(jìn)入Loop循環(huán),等到socket消息

當(dāng)有新消息時會執(zhí)行processOneCommand,主要干了三件事情:

1 讀取參數(shù)列表readArgumentList,參數(shù)列表是AMS 跨進(jìn)程發(fā)過來的

2 根據(jù)參數(shù)fork子進(jìn)程forkAndSpecialize

3 在子進(jìn)程中開始干活handleChildProc

Runnable processOneCommand(ZygoteServer zygoteServer) {

? ? String args[];

Arguments parsedArgs =?null;

? ? FileDescriptor[] descriptors;

?try?{

args =?readArgumentList();

descriptors =?mSocket.getAncillaryFileDescriptors();

? ....

? ? pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,

? ? ? ? ? ? parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,

? ? ? ? ? ? parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.instructionSet,

? ? ? ? ? ? parsedArgs.appDataDir);

?try?{

?if?(pid ==?0) {

?// in child

?zygoteServer.setForkChild();

? ? ? ? ? ? zygoteServer.closeServerSocket();

? ? ? ? ? ? IoUtils.closeQuietly(serverPipeFd);

serverPipeFd =?null;

?return?handleChildProc(parsedArgs, descriptors, childPipeFd);

// 主要是加載ActivityThread 并調(diào)用main函數(shù)

}?else?{

?// In the parent. A pid < 0 indicates a failure and will be handled in

?// handleParentProc.

?IoUtils.closeQuietly(childPipeFd);

childPipeFd =?null;

? ? ? ? ? ? handleParentProc(pid, descriptors, serverPipeFd);// 把應(yīng)用進(jìn)程pid 通過socket 返回給AMS

?return?null;

? ? ? ? }

}?finally?{

? ? ? ? IoUtils.closeQuietly(childPipeFd);

? ? ? ? IoUtils.closeQuietly(serverPipeFd);

? ? }

}

Zygote fork時要單線程.

除了Zygote進(jìn)程,系統(tǒng)啟動是還是啟動其他重要進(jìn)程

servicemanager.rc

service servicemanager /system/bin/servicemanager

? ? class core animation

user?system

group?system?readproc

? ? critical

? ? onrestart restart healthd

? ? onrestart restart zygote

? ? onrestart restart audioserver

? ? onrestart restart media

? ? onrestart restart surfaceflinger

? ? onrestart restart inputflinger

? ? onrestart restart drm

? ? onrestart restart cameraserver

? ? onrestart restart keystore

? ? onrestart restart gatekeeperd

? ? writepid /dev/cpuset/system-background/tasks

?shutdown?critical

surfaceflinger.rc

service surfaceflinger /system/bin/surfaceflinger

? ? class core animation

user?system

? ? group graphics drmrpc readproc

? ? onrestart restart zygote

? ? writepid /dev/stune/foreground/tasks

?socket?pdx/system/vr/display/client ? ? stream?0666?system?graphics u:object_r:pdx_display_client_endpoint_socket:s0

?socket?pdx/system/vr/display/manager ? ?stream?0666?system?graphics u:object_r:pdx_display_manager_endpoint_socket:s0

?socket?pdx/system/vr/display/vsync ? ? ?stream?0666?system?graphics u:object_r:pdx_display_vsync_endpoint_socket:s0

mediaserver.rc

service media /system/bin/mediaserver

?class?main

? ? user media

? ? group audio camera inet net_bt net_bt_admin net_bw_acct drmrpc mediadrm

ioprio rt?4

? ? writepid /dev/cpuset/smart-system/tasks /dev/stune/foreground/tasks

........

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容