1. 程式人生 > 其它 >Android Framework實戰視訊--Zygote的fork程序篇

Android Framework實戰視訊--Zygote的fork程序篇

線上學習課程,課程諮詢答疑和新課資訊:QQ交流群:422901085進行課程討論
轉自於:https://blog.csdn.net/learnframework/article/details/116244848

Zygote的fork程序篇

課程答疑和新課資訊:QQ交流群:422901085進行課程討論
FrameWork入門課視訊連結:https://edu.csdn.net/course/detail/30298
FrameWork實戰課1視訊連結:https://edu.csdn.net/course/detail/30275
專題部落格系列:
Android 8.1 zygote 啟動過程原始碼
Android Framework實戰視訊--Zygote的fork程序篇


Android Framework實戰視訊--SystemServer啟動篇
Android Framework實戰視訊--SystemServer啟動FallbackHome篇
Android Framework實戰視訊--FallbackHome程序啟動及Activity啟動篇
Android Framework實戰視訊--FallbackHome結束啟動Launcher篇

1、實戰體驗linux的fork

直接上程式碼體驗fork桌面建立新的子程序
//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
然後執行:./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執行後:多了一個程序號 5320
就會有2個程序的列印,即程式碼中的if和else都執行了,因為fork執行後就有兩個程序分別執行了。
其中fork的返回值如果為:0說明當前就是子程序執行,為子程序的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;
    }

分析發現主要呼叫:

Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids,
                    parsedArgs.debugFlags,
                    null,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);

這個從名字看相對也貼近剛開始學的fork了。繼續看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();
大家心裡有沒有非常非常激動啊
這裡就是真正建立子程序的地方,和剛開始一樣講解實戰的fork程式是不是一樣啊
好了,那到這裡相信大家已經清楚了zygote怎麼一步步的創建出新的程序