当前位置:   article > 正文

Android内核分析-Android系统启动过程(三)_android /proc/self/task

android /proc/self/task


前言

在第二章节,我们提到ZygoteInit的main函数中执行了startSystemServer来启动system_server服务。下图是SystemSever启动的服务,接下来我们分析下源码
在这里插入图片描述

Zygote与SystemServer

startSystemServer()

/**
 * Prepare the arguments and fork for the system server process.
 */
private static boolean startSystemServer(String abiList, String socketName)
        throws MethodAndArgsCaller, RuntimeException {
   
    long capabilities = posixCapabilitiesAsBits(
        OsConstants.CAP_IPC_LOCK,
        OsConstants.CAP_KILL,
        OsConstants.CAP_NET_ADMIN,
        OsConstants.CAP_NET_BIND_SERVICE,
        OsConstants.CAP_NET_BROADCAST,
        OsConstants.CAP_NET_RAW,
        OsConstants.CAP_SYS_MODULE,
        OsConstants.CAP_SYS_NICE,
        OsConstants.CAP_SYS_RESOURCE,
        OsConstants.CAP_SYS_TIME,
        OsConstants.CAP_SYS_TTY_CONFIG
    );
    /* Containers run without this capability, so avoid setting it in that case */
    if (!SystemProperties.getBoolean(PROPERTY_RUNNING_IN_CONTAINER, false)) {
   
        capabilities |= posixCapabilitiesAsBits(OsConstants.CAP_BLOCK_SUSPEND);
    }
    /* 初始化参数 */
    String args[] = {
   
        "--setuid=1000",
        "--setgid=1000",
        "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1032,3001,3002,3003,3006,3007,3009,3010",
        "--capabilities=" + capabilities + "," + capabilities,
        "--nice-name=system_server",
        "--runtime-args",
        "com.android.server.SystemServer",
    };
    ZygoteConnection.Arguments parsedArgs = null;

    int pid;

    try {
   
        parsedArgs = new ZygoteConnection.Arguments(args);
        ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
        ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);

        /* Request to fork the system server process */
        pid = Zygote.forkSystemServer(
                parsedArgs.uid, parsedArgs.gid,
                parsedArgs.gids,
                parsedArgs.debugFlags,
                null,
                parsedArgs.permittedCapabilities,
                parsedArgs.effectiveCapabilities);//对zygote进程进行fork,得到的子进程就是SystemServer进程,返回的子进程pid为0
    } catch (IllegalArgumentException ex) {
   
        throw new RuntimeException(ex);
    }

    /* system_server进程 */
    if (pid == 0) {
   //子进程ystem_server进程pid为0,此时位于system_server进程中
        if (hasSecondZygote(abiList)) {
   //如果有第二个zygote进程,那就等第二个zygote进程创建完
            waitForSecondaryZygote(socketName);
        }

        handleSystemServerProcess(parsedArgs);
    }

    return true;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71

该函数中我们看到有个forkSystemServer方法的调用,其实就是在此处创建了system_server进程,而最后通过handleSystemServerProcess启动其他各种服务。

/**
 * Special method to start the system server process. In addition to the
 * common actions performed in forkAndSpecialize, the pid of the child
 * process is recorded such that the death of the child process will cause
 * zygote to exit.
 *
 * @param uid the UNIX uid that the new process should setuid() to after
 * fork()ing and and before spawning any threads.
 * @param gid the UNIX gid that the new process should setgid() to after
 * fork()ing and and before spawning any threads.
 * @param gids null-ok; a list of UNIX gids that the new process should
 * setgroups() to after fork and before spawning any threads.
 * @param debugFlags bit flags that enable debugging features.
 * @param rlimits null-ok an array of rlimit tuples, with the second
 * dimension having a length of 3 and representing
 * (resource, rlim_cur, rlim_max). These are set via the posix
 * setrlimit(2) call.
 * @param permittedCapabilities argument for setcap()
 * @param effectiveCapabilities argument for setcap()
 *
 * @return 0 if this is the child, pid of the child
 * if this is the parent, or -1 on error.
 */
public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags,
        int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
   
    VM_HOOKS.preFork();
    int pid = nativeForkSystemServer(//调用native方法nativeForkSystemServer来fork system_server进程
            uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities);
    // Enable tracing as soon as we enter the system_server.
    if (pid == 0) {
   
        Trace.setTracingEnabled(true);
    }
    VM_HOOKS.postForkCommon();
    return pid;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

该函数分为三阶段处理preFork、nativeForkAndSpecialize、postForkCommon。
VM_HOOKS是Zygote对象的静态成员变量:VM_HOOKS = new ZygoteHooks()

ZygoteHooks.preFork()
public void preFork() {
   
    Daemons.stop(); //停止4个Daemon子线程
    waitUntilAllThreadsStopped(); //等待所有子线程结束
    token = nativePreFork(); //完成gc堆的初始化工作
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

Daemons.stop

public static void stop() {
   
    HeapTaskDaemon.INSTANCE.stop(); //Java堆整理线程
    ReferenceQueueDaemon.INSTANCE.stop(); //引用队列线程
    FinalizerDaemon.INSTANCE.stop(); //析构线程
    FinalizerWatchdogDaemon.INSTANCE.stop(); //析构监控线程
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

此处守护线程Stop方式是先调用目标线程interrrupt()方法,然后再调用目标线程join()方法,等待线程执行完成。

waitUntilAllThreadsStopped

private static void waitUntilAllThreadsStopped() {
   
    File tasks = new File("/proc/self/task");
    // 当/proc中线程数大于1,就出让CPU直到只有一个线程,才退出循环
    while (tasks.list().length > 1) {
   
        Thread.yield();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

nativePreFork

nativePreFork通过JNI最终调用如下方法:

/*art/runtime/native/dalvik_system_ZygoteHooks.cc*/
static jlong ZygoteHooks_nativePreFork(JNIEnv* env, jclass) {
   
    Runtime* runtime = Runtime::Current();
    runtime->PreZygoteFork(); // 见下文
    if (Trace::GetMethodTracingMode() != TracingMode::kTracingInactive) {
   
      Trace::Pause();
    }
    //将线程转换为long型并保存到token,该过程是非安全的
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/227808
推荐阅读
相关标签
  

闽ICP备14008679号