在線學習課程,課程咨詢答疑和新課信息:QQ交流群:422901085進行課程討論
轉自于:https://blog.csdn.net/learnframework/article/details/116244848
Zygote的fork進程篇
課程答疑和新課信息:QQ交流群:422901085進行課程討論
FrameWork入門課視頻鏈接:https://edu.csdn.net/course/detail/30298
FrameWork實戰(zhàn)課1視頻鏈接:https://edu.csdn.net/course/detail/30275
專題博客系列:
Android 8.1 zygote 啟動過程源碼
Android Framework實戰(zhàn)視頻--Zygote的fork進程篇
Android Framework實戰(zhàn)視頻--SystemServer啟動篇
Android Framework實戰(zhàn)視頻--SystemServer啟動FallbackHome篇
Android Framework實戰(zhàn)視頻--FallbackHome進程啟動及Activity啟動篇
Android Framework實戰(zhàn)視頻--FallbackHome結束啟動Launcher篇
1、實戰(zhàn)體驗linux的fork
直接上代碼體驗fork桌面創(chuàng)建新的子進程
//fork.c
#include <unistd.h>
#include <stdio.h>
int main(void)
{
int pid;
int count2=0;
printf("main current process pid == %d \n",getpid());
pid=fork();
if (pid == 0) {//子進程,其中getpid()代表獲取當前進程號,getppid()表示獲取當前父進程號
printf("child process pid == %d ppid == %d \n",getpid(),getppid());
} else {
printf("this process current pid == %d pid = %d ppid == %d \n",getpid(),pid,getppid());
}
while(1);
return 0;
}
因為屬于linux的代碼,只需要在ubuntu上運行既可以:
gcc fork.c -o fork
然后執(zhí)行:./fork
輸出如下:
main current process pid == 5319
this process current pid == 5319 pid = 5320 ppid == 5308
child process pid == 5320 ppid == 5319
可以看出調用fork以前只有一個進程 pid = 5319
但是在fork執(zhí)行后:多了一個進程號 5320
就會有2個進程的打印,即代碼中的if和else都執(zhí)行了,因為fork執(zhí)行后就有兩個進程分別執(zhí)行了。
其中fork的返回值如果為:0說明當前就是子進程執(zhí)行,為子進程的pid就說明是原來的父進程
2、Zygote fork進程的源碼分析
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java中main方法里面的如下代碼
if (startSystemServer) {
Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
// {@code r == null} in the parent (zygote) process, and {@code r != null} in the
// child (system_server) process.
if (r != null) {
r.run();
return;
}
}
核心就是forkSystemServer方法
private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
//省略。。
int pid;
try {
parsedArgs = new ZygoteConnection.Arguments(args);
//省略。。
/* Request to fork the system server process */
//核心方法
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.debugFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
/* For child process */
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
zygoteServer.closeServerSocket();
return handleSystemServerProcess(parsedArgs);
}
return null;
}
分析發(fā)現主要調用:
Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.debugFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
這個從名字看相對也貼近剛開始學的fork了。繼續(xù)看Zygote.forkSystemServer
public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags,
int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
//省略
int pid = nativeForkSystemServer(
uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities);
//省略
return pid;
}
這里調用的又是nativeForkSystemServer,nativeForkSystemServer屬于jni調用:
代碼路徑:
frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
static jint com_android_internal_os_Zygote_nativeForkSystemServer(
JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,
jint debug_flags, jobjectArray rlimits, jlong permittedCapabilities,
jlong effectiveCapabilities) {
pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids,
debug_flags, rlimits,
permittedCapabilities, effectiveCapabilities,
MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true, NULL,
NULL, NULL, NULL);
//省略
return pid;
}
調用到了ForkAndSpecializeCommon方法:
// Utility routine to fork zygote and specialize the child process.
static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray javaGids,
jint debug_flags, jobjectArray javaRlimits,
jlong permittedCapabilities, jlong effectiveCapabilities,
jint mount_external,
jstring java_se_info, jstring java_se_name,
bool is_system_server, jintArray fdsToClose,
jintArray fdsToIgnore,
jstring instructionSet, jstring dataDir) {
//省略
pid_t pid = fork();
if (pid == 0) {
//省略
} else if (pid > 0) {
//省略
}
return pid;
}
ForkAndSpecializeCommon方法本身非常長,但是看到這里有一個 pid_t pid = fork();
大家心里有沒有非常非常激動啊
這里就是真正創(chuàng)建子進程的地方,和剛開始一樣講解實戰(zhàn)的fork程序是不是一樣啊
好了,那到這里相信大家已經清楚了zygote怎么一步步的創(chuàng)建出新的進程