<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                先看service是如何啟動的。 1.啟動zygote init.rc中有這樣一句話: ~~~ #class_start是一個COMMAND,對應的函數為do_class_start,很重要,切記。 class_startdefault ~~~ class_start標示一個COMMAND,對應的處理函數為do_class_start,它位于boot section的范圍內。為什么說它很重要呢? 還記得init進程中的四個執行階段嗎?當init進程執行到下面幾句話時,do_class_start就會被執行了。 ~~~ //將bootsection節的command加入到執行隊列 action_for_each_trigger("boot",action_add_queue_tail); //執行隊列里的命令,class可是一個COMMAND,所以它對應的do_class_start會被執行。 drain_action_queue(); ~~~ 下面來看do_class_start函數: **builtins.c** ~~~ int do_class_start(int nargs, char **args) { /* args為do_class_start的參數,init.rc中只有一個參數,就是default。 下面這個函數將從service_list中尋找classname為”default”的service,然后 調用service_start_if_not_disabled函數。現在讀者明白了service結構體中 classname的作用了嗎? */ service_for_each_class(args[1],service_start_if_not_disabled); return 0; } ~~~ 我們已經知道,zygote這個service的classname的值就是“default”,所以會針對這個service調用service_start_if_not_disabled,這個函數的代碼是: **parser.c** ~~~ static void service_start_if_not_disabled(structservice *svc) { if (!(svc->flags & SVC_DISABLED)) { service_start(svc,NULL); //zygote可沒有設置SVC_DISABLED } } ~~~ service_start函數的代碼如下所示: **init.c** ~~~ void service_start(struct service *svc, constchar *dynamic_args) { structstat s; pid_tpid; intneeds_console; int n; svc->flags &= (~(SVC_DISABLED|SVC_RESTARTING)); svc->time_started = 0; if(svc->flags & SVC_RUNNING) { return;//如果這個service已在運行,則不用處理 } /* service一般運行于另外一個進程中,這個進程也是init的子進程,所以啟動service前需要判斷 對應的可執行文件是否存在,zygote對應的可執行文件是/system/bin/app_process */ if(stat(svc->args[0], &s) != 0) { svc->flags |= SVC_DISABLED; return; } ...... pid =fork(); //調用fork創建子進程 if(pid == 0) { //pid為零,我們在子進程中 struct socketinfo *si; struct svcenvinfo *ei; char tmp[32]; int fd, sz; //得到屬性存儲空間的信息并加到環境變量中,后面在屬性服務一節中會碰到使用它的地方。 get_property_workspace(&fd, &sz); add_environment("ANDROID_PROPERTY_WORKSPACE", tmp); //添加環境變量信息 for (ei = svc->envvars; ei; ei = ei->next) add_environment(ei->name, ei->value); //根據socketinfo創建socket for (si = svc->sockets; si; si = si->next) { int s = create_socket(si->name, !strcmp(si->type,"dgram") ? SOCK_DGRAM :SOCK_STREAM, si->perm,si->uid, si->gid); if (s >= 0) { //在環境變量中添加socket信息。 publish_socket(si->name, s); } } ......//設置uid,gid等 setpgid(0, getpid()); if(!dynamic_args) { /* 執行/system/bin/app_process,這樣就進入到app_process的main函數中了。 fork、execve這兩個函數都是Linux系統上常用的系統調用。 */ if (execve(svc->args[0], (char**)svc->args, (char**) ENV) < 0) { ...... } }else { ...... } ......//父進程init的處理,設置service的信息,如啟動時間、進程號,以及狀態等。 svc->time_started = gettime(); svc->pid = pid; svc->flags |= SVC_RUNNING; //每一個service都有一個屬性,zygote的屬性為init.svc.zygote,現在設置它的值為running notify_service_state(svc->name, "running"); } ~~~ 原來,zygote是通過fork和execv共同創建的!但service結構中的那個onrestart好像沒有派上用場,原因何在? 2. 重啟zygote 根據名字,就可猜到onrestart應該是在zygote重啟時用的。下面先看在zygote死后,它的父進程init會有什么動作: **init.c** ~~~ static void sigchld_handler(int s) { //當子進程退出時,init的這個信號處理函數會被調用 write(signal_fd, &s, 1); //往signal_fd write數據 } ~~~ signal_fd,就是在init中通過socketpair創建的兩個socket中的一個,既然會往這個signal_fd中發送數據,那么另外一個socket就一定能接收到,這樣就會導致init從poll函數中返回: **init.rc::main函數代碼片斷** ~~~ nr =poll(ufds, fd_count, timeout); ...... if(ufds[2].revents == POLLIN) { read(signal_recv_fd, tmp, sizeof(tmp)); while (!wait_for_one_process(0))//調用wait_for_one_process函數處理 ; continue; } ...... //直接看這個wait_for_one_process函數: static int wait_for_one_process(int block) { pid_tpid; intstatus; structservice *svc; structsocketinfo *si; time_tnow; structlistnode *node; structcommand *cmd; while( (pid = waitpid(-1, &status, block ? 0 : WNOHANG)) == -1 && errno == EINTR ); if(pid <= 0) return -1; //找到死掉的那個service,現在應該找到了代表zygote的那個service。 svc = service_find_by_pid(pid); ...... if(!(svc->flags & SVC_ONESHOT)) { //殺掉zygote創建的所有子進程,這就是zygote死后,Java世界崩潰的原因。 kill(-pid, SIGKILL); } //清理socket信息,不清楚的讀者可以通過命令man 7 AF_UNIX查詢一下相關知識。 for(si = svc->sockets; si; si = si->next) { char tmp[128]; snprintf(tmp, sizeof(tmp), ANDROID_SOCKET_DIR"/%s",si->name); unlink(tmp); } svc->pid = 0; svc->flags &= (~SVC_RUNNING); if(svc->flags & SVC_ONESHOT) { svc->flags |= SVC_DISABLED; } ...... now= gettime(); /* 如果設置了SVC_CRITICAL標示,則4分鐘內該服務重啟次數不能超過4次,否則 機器會重啟進入recovery模式。根據init.rc的配置,只有servicemanager進程 享有此種待遇。 */ if(svc->flags & SVC_CRITICAL) { if(svc->time_crashed + CRITICAL_CRASH_WINDOW >= now) { if (++svc->nr_crashed > CRITICAL_CRASH_THRESHOLD) { ...... sync(); __reboot(LINUX_REBOOT_MAGIC1,LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, "recovery"); return 0; } }else { svc->time_crashed = now; svc->nr_crashed = 1; } } svc->flags |= SVC_RESTARTING; //設置標示為SVC_RESTARTING,然后執行該service onrestart中的COMMAND,這些內容就 //非常簡單了,讀者可以自行學習。 list_for_each(node, &svc->onrestart.commands) { cmd = node_to_item(node, struct command, clist); cmd->func(cmd->nargs, cmd->args); } //設置init.svc.zygote的值為restarting。 notify_service_state(svc->name, "restarting"); return0; } ~~~ 通過上面的代碼,可知道onrestart的作用了,但zygote本身又在哪里重啟的呢?答案就在下面的代碼中: **init.c::main函數代碼片斷** ~~~ for(;;) { int nr, i, timeout = -1; for (i = 0; i < fd_count; i++) ufds[i].revents = 0; drain_action_queue(); //poll函數返回后,會進入下一輪的循環 restart_processes(); //這里會重啟所有flag標志為SVC_RESTARTING的service。 ...... } ~~~ 這樣,zygote又回來了!
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看