当前位置: 首页 > news >正文

中国建设银行官方网站纪念币免费网站创建

中国建设银行官方网站纪念币,免费网站创建,做网站要用什么服务器吗,做商务网站要多少钱init进程会读取rc文件,然后孵化很多其他系统服务进程,为防止子进程死亡后称为僵尸进程,init需要监测子进程是否死亡,如果死亡,则清除子进程资源,并重新拉起进程。 system/core/init/init.cpp InstallSigna…

init进程会读取rc文件,然后孵化很多其他系统服务进程,为防止子进程死亡后称为僵尸进程,init需要监测子进程是否死亡,如果死亡,则清除子进程资源,并重新拉起进程。
system/core/init/init.cpp

InstallSignalFdHandler(&epoll);

init进程第二阶段启动的时候,创建了epoll,并将子进程相关处理注册到epoll中

static void InstallSignalFdHandler(Epoll* epoll) {// Applying SA_NOCLDSTOP to a defaulted SIGCHLD handler prevents the signalfd from receiving// SIGCHLD when a child process stops or continues (b/77867680#comment9).const struct sigaction act { .sa_handler = SIG_DFL, .sa_flags = SA_NOCLDSTOP };sigaction(SIGCHLD, &act, nullptr);sigset_t mask;sigemptyset(&mask);sigaddset(&mask, SIGCHLD);if (!IsRebootCapable()) {// If init does not have the CAP_SYS_BOOT capability, it is running in a container.// In that case, receiving SIGTERM will cause the system to shut down.sigaddset(&mask, SIGTERM);}if (sigprocmask(SIG_BLOCK, &mask, nullptr) == -1) {PLOG(FATAL) << "failed to block signals";}// Register a handler to unblock signals in the child processes.const int result = pthread_atfork(nullptr, nullptr, &UnblockSignals);if (result != 0) {LOG(FATAL) << "Failed to register a fork handler: " << strerror(result);}signal_fd = signalfd(-1, &mask, SFD_CLOEXEC | SFD_NONBLOCK);if (signal_fd == -1) {PLOG(FATAL) << "failed to create signalfd";}constexpr int flags = EPOLLIN | EPOLLPRI;auto handler = std::bind(HandleSignalFd, false);if (auto result = epoll->RegisterHandler(signal_fd, handler, flags); !result.ok()) {LOG(FATAL) << result.error();}
}

使用epoll注册监听信号量fd,子进程死亡会发送信号给init进程,这里就会调用epoll中注册的回调函数HandleSignalFd

static void HandleSignalFd(bool one_off) {signalfd_siginfo siginfo;auto started = std::chrono::steady_clock::now();do {ssize_t bytes_read = TEMP_FAILURE_RETRY(read(signal_fd, &siginfo, sizeof(siginfo)));if (bytes_read < 0 && errno == EAGAIN) {auto now = std::chrono::steady_clock::now();std::chrono::duration<double> waited = now - started;if (waited >= kDiagnosticTimeout) {LOG(ERROR) << "epoll() woke us up, but we waited with no SIGCHLD!";started = now;}std::this_thread::sleep_for(100ms);continue;}if (bytes_read != sizeof(siginfo)) {PLOG(ERROR) << "Failed to read siginfo from signal_fd";return;}break;} while (!one_off);switch (siginfo.ssi_signo) {case SIGCHLD:ReapAnyOutstandingChildren();break;case SIGTERM:HandleSigtermSignal(siginfo);break;default:PLOG(ERROR) << "signal_fd: received unexpected signal " << siginfo.ssi_signo;break;}
}

对于SIGCHLD信号,调用ReapAnyOutstandingChildren
system/core/init/sigchld_handler.cpp

void ReapAnyOutstandingChildren() {while (ReapOneProcess() != 0) {}}
static pid_t ReapOneProcess() {siginfo_t siginfo = {};// This returns a zombie pid or informs us that there are no zombies left to be reaped.// It does NOT reap the pid; that is done below.if (TEMP_FAILURE_RETRY(waitid(P_ALL, 0, &siginfo, WEXITED | WNOHANG | WNOWAIT)) != 0) {PLOG(ERROR) << "waitid failed";return 0;}auto pid = siginfo.si_pid;if (pid == 0) return 0;// At this point we know we have a zombie pid, so we use this scopeguard to reap the pid// whenever the function returns from this point forward.// We do NOT want to reap the zombie earlier as in Service::Reap(), we kill(-pid, ...) and we// want the pid to remain valid throughout that (and potentially future) usages.auto reaper = make_scope_guard([pid] { TEMP_FAILURE_RETRY(waitpid(pid, nullptr, WNOHANG)); });std::string name;std::string wait_string;Service* service = nullptr;if (SubcontextChildReap(pid)) {name = "Subcontext";} else {//查找死亡进程pidservice = ServiceList::GetInstance().FindService(pid, &Service::pid);if (service) {name = StringPrintf("Service '%s' (pid %d)", service->name().c_str(), pid);if (service->flags() & SVC_EXEC) {auto exec_duration = boot_clock::now() - service->time_started();auto exec_duration_ms =std::chrono::duration_cast<std::chrono::milliseconds>(exec_duration).count();wait_string = StringPrintf(" waiting took %f seconds", exec_duration_ms / 1000.0f);} else if (service->flags() & SVC_ONESHOT) {auto exec_duration = boot_clock::now() - service->time_started();auto exec_duration_ms =std::chrono::duration_cast<std::chrono::milliseconds>(exec_duration).count();wait_string = StringPrintf(" oneshot service took %f seconds in background",exec_duration_ms / 1000.0f);}} else {name = StringPrintf("Untracked pid %d", pid);}}if (siginfo.si_code == CLD_EXITED) {LOG(INFO) << name << " exited with status " << siginfo.si_status << wait_string;} else {LOG(INFO) << name << " received signal " << siginfo.si_status << wait_string;}if (!service) {LOG(INFO) << name << " did not have an associated service entry and will not be reaped";return pid;}//杀死进程,清除资源,并设置重启标志service->Reap(siginfo);if (service->flags() & SVC_TEMPORARY) {ServiceList::GetInstance().RemoveService(*service);}return pid;
}

调用Reap函数清理子进程
system/core/init/service.cpp

void Service::Reap(const siginfo_t& siginfo) {//杀死进程if (!(flags_ & SVC_ONESHOT) || (flags_ & SVC_RESTART)) {KillProcessGroup(SIGKILL, false);} else {// Legacy behavior from ~2007 until Android R: this else branch did not exist and we did not// kill the process group in this case.if (SelinuxGetVendorAndroidVersion() >= __ANDROID_API_R__) {// The new behavior in Android R is to kill these process groups in all cases.  The// 'true' parameter instructions KillProcessGroup() to report a warning message where it// detects a difference in behavior has occurred.KillProcessGroup(SIGKILL, true);}}// Remove any socket resources we may have created.//清除socket节点for (const auto& socket : sockets_) {if (socket.persist) {continue;}auto path = ANDROID_SOCKET_DIR "/" + socket.name;unlink(path.c_str());}for (const auto& f : reap_callbacks_) {f(siginfo);}if ((siginfo.si_code != CLD_EXITED || siginfo.si_status != 0) && on_failure_reboot_target_) {LOG(ERROR) << "Service with 'reboot_on_failure' option failed, shutting down system.";trigger_shutdown(*on_failure_reboot_target_);}if (flags_ & SVC_EXEC) UnSetExec();if (name_ == "zygote" || name_ == "zygote64") {//如果是zygote,则清除所有服务进程removeAllEmptyProcessGroups();}if (flags_ & SVC_TEMPORARY) return;pid_ = 0;flags_ &= (~SVC_RUNNING);start_order_ = 0;// Oneshot processes go into the disabled state on exit,// except when manually restarted.if ((flags_ & SVC_ONESHOT) && !(flags_ & SVC_RESTART) && !(flags_ & SVC_RESET)) {flags_ |= SVC_DISABLED;}// Disabled and reset processes do not get restarted automatically.if (flags_ & (SVC_DISABLED | SVC_RESET))  {NotifyStateChange("stopped");return;}#if INIT_FULL_SOURCESstatic bool is_apex_updatable = android::sysprop::ApexProperties::updatable().value_or(false);
#elsestatic bool is_apex_updatable = false;
#endifconst bool is_process_updatable = !use_bootstrap_ns_ && is_apex_updatable;// If we crash > 4 times in 'fatal_crash_window_' minutes or before boot_completed,// reboot into bootloader or set crashing propertyboot_clock::time_point now = boot_clock::now();if (((flags_ & SVC_CRITICAL) || is_process_updatable) && !(flags_ & SVC_RESTART)) {bool boot_completed = GetBoolProperty("sys.boot_completed", false);if (now < time_crashed_ + fatal_crash_window_ || !boot_completed) {if (++crash_count_ > 4) {auto exit_reason = boot_completed ?"in " + std::to_string(fatal_crash_window_.count()) + " minutes" :"before boot completed";if (flags_ & SVC_CRITICAL) {if (!GetBoolProperty("init.svc_debug.no_fatal." + name_, false)) {// Aborts into `fatal_reboot_target_'.SetFatalRebootTarget(fatal_reboot_target_);LOG(FATAL) << "critical process '" << name_ << "' exited 4 times "<< exit_reason;}} else {LOG(ERROR) << "process with updatable components '" << name_<< "' exited 4 times " << exit_reason;// Notifies update_verifier and apexdSetProperty("sys.init.updatable_crashing_process_name", name_);SetProperty("sys.init.updatable_crashing", "1");}}} else {time_crashed_ = now;crash_count_ = 1;}}flags_ &= (~SVC_RESTART);//设置重启标志位flags_ |= SVC_RESTARTING;// Execute all onrestart commands for this service.//启动所有rc中标志位onrestart的服务onrestart_.ExecuteAllCommands();NotifyStateChange("restarting");return;
}

这里清除了进程的资源,并设置该进程标志为SVC_RESTARTING,并启动rc中定义的onrestart相关服务

while (true) {...if (!IsShuttingDown()) {auto next_process_action_time = HandleProcessActions();// If there's a process that needs restarting, wake up in time for that.if (next_process_action_time) {epoll_timeout = std::chrono::ceil<std::chrono::milliseconds>(*next_process_action_time - boot_clock::now());if (*epoll_timeout < 0ms) epoll_timeout = 0ms;}}...}

init进程的死循环中HandleProcessActions会处理服务重启

static std::optional<boot_clock::time_point> HandleProcessActions() {std::optional<boot_clock::time_point> next_process_action_time;//遍历所有的servicefor (const auto& s : ServiceList::GetInstance()) {if ((s->flags() & SVC_RUNNING) && s->timeout_period()) {auto timeout_time = s->time_started() + *s->timeout_period();if (boot_clock::now() > timeout_time) {s->Timeout();} else {if (!next_process_action_time || timeout_time < *next_process_action_time) {next_process_action_time = timeout_time;}}}//如果没有标志为SVC_RESTARTING,则跳过if (!(s->flags() & SVC_RESTARTING)) continue;auto restart_time = s->time_started() + s->restart_period();if (boot_clock::now() > restart_time) {//调用Start重启服务if (auto result = s->Start(); !result.ok()) {LOG(ERROR) << "Could not restart process '" << s->name() << "': " << result.error();}} else {if (!next_process_action_time || restart_time < *next_process_action_time) {next_process_action_time = restart_time;}}}return next_process_action_time;
}

调用Start函数执行

Result<void> Service::Start() {...pid_t pid = -1;if (namespaces_.flags) {pid = clone(nullptr, nullptr, namespaces_.flags | SIGCHLD, nullptr);} else {//新建一个进程pid = fork();}if (pid == 0) {//子进程中执行,运行子进程服务umask(077);RunService(override_mount_namespace, descriptors, std::move(pipefd));_exit(127);}if (pid < 0) {pid_ = 0;return ErrnoError() << "Failed to fork";}...
}

fork子进程,并调用RunService执行service

void Service::RunService(const std::optional<MountNamespace>& override_mount_namespace,const std::vector<Descriptor>& descriptors,std::unique_ptr<std::array<int, 2>, decltype(&ClosePipe)> pipefd) {...if (!ExpandArgsAndExecv(args_, sigstop_)) {PLOG(ERROR) << "cannot execv('" << args_[0]<< "'). See the 'Debugging init' section of init's README.md for tips";}
}

调用ExpandArgsAndExecv执行

static bool ExpandArgsAndExecv(const std::vector<std::string>& args, bool sigstop) {std::vector<std::string> expanded_args;std::vector<char*> c_strings;expanded_args.resize(args.size());c_strings.push_back(const_cast<char*>(args[0].data()));for (std::size_t i = 1; i < args.size(); ++i) {auto expanded_arg = ExpandProps(args[i]);if (!expanded_arg.ok()) {LOG(FATAL) << args[0] << ": cannot expand arguments': " << expanded_arg.error();}expanded_args[i] = *expanded_arg;c_strings.push_back(expanded_args[i].data());}c_strings.push_back(nullptr);if (sigstop) {kill(getpid(), SIGSTOP);}return execv(c_strings[0], c_strings.data()) == 0;
}

调用execv执行可执行文件

http://www.shuangfujiaoyu.com/news/42557.html

相关文章:

  • 百度站点管理优化大师下载安装app
  • 企业网站图片渐变效果怎么做正安县网站seo优化排名
  • 公司做公司网站宣传宁波网站建设的公司
  • 做网站如何引流seo是什么职业做什么的
  • 百度地图网站后台更新竞价推广套户渠道商
  • 地方网站还有得做吗中国局势最新消息今天
  • 分类网站怎么做seo网络营销推广主要做什么
  • 北京做网站的公司拟杭州网络
  • 那可以做网站武汉网络关键词排名
  • wordpress 数学主题win10优化软件哪个好
  • 网站开发和运营合同分开签么北京网站建设公司哪家好
  • 纯div css做网站简洁版杭州网站设计公司
  • 重庆网站建设索q479185700公司官网开发制作
  • 泰安市人才服务平台芜湖seo
  • wordpress 邮件文本优化设计答案六年级
  • 金融企业网站模板长沙seo网站优化公司
  • wordpress音频播放不了seo商城
  • 张家港快速网站建设seo网站推广收费
  • 手把手教你搭建自己的网站免费友链互换
  • 慈溪企业网站seosemester
  • 凡科网站怎么做外链怎么推广比较好
  • 膜结构网站推广怎么做怎么做神马搜索排名seo
  • 网站设计规划的目的和要求seo关键词排名优
  • wordpress自定义页面没反应杭州seo教程
  • 门户网站是什么意思啊天津关键词排名推广
  • 一个网站可以做多少个小程序seo学校培训班
  • 手机网站功能开发方案推广点击器
  • 全国招标公告公示平台国内seo服务商
  • 如何做网站分析大连seo优化
  • 别人的做网站网络广告创意