Android启动过程 - init进程对服务子进程的管理

接上文

1. 监控service异常退出

对于init启动的service,如果没有指定oneshort(一次性)的option,则默认为常驻service。在此情况下,当servcie意外退出,init将监控到并重启service

首先,在InstallSignalFdHandler中注册SIGCHLD信号的处理函数,用于监听init子进程的终止。SIGCHLD会监听到子进程的终止、暂停、恢复三个状态。init在注册SIGCHLD时,设置了SA_NOCLDSTOP这个flag,其作用是不监听暂停、恢复状态,只关注终止状态。

core/init/init.cpp

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_flags = SA_NOCLDSTOP, .sa_handler = SIG_DFL };
    sigaction(SIGCHLD, &act, nullptr);

    // 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);
    }

    Result<void> cs_result = RegisterSignalFd(epoll, SIGCHLD, Service::GetSigchldFd());
    if (!cs_result.ok()) {
     
        PLOG(FATAL) << cs_result.error();
    }

    if (!IsRebootCapable()) {
     
        Result<int> cs_result = CreateAndRegisterSignalFd(epoll, SIGTERM);
        if (!cs_result.ok()) {
     
            PLOG(FATAL) << cs_result.error();
        }
        sigterm_fd = cs_result.value();
    }
}

而具体SIGCHLD的监听处理,是由epoll来实现的。在RegisterSignalFd中

static Result<void> RegisterSignalFd(Epoll* epoll, int signal, int fd) {
     
    return epoll->RegisterHandler(
            fd, [signal]() {
      HandleSignalFd(signal); }, EPOLLIN | EPOLLPRI);
}

指明了信号处理函数HandleSignalFd

static void HandleSignalFd(int signal) {
     
    ...
    switch (siginfo.ssi_signo) {
     
        case SIGCHLD:
            ReapAnyOutstandingChildren();
            break;
        case SIGTERM:
            HandleSigtermSignal(siginfo);
            break;
        default:
            LOG(ERROR) << "signal_fd: received unexpected signal " << siginfo.ssi_signo;
            break;
    }
}

收到SIGCHLD信号时,会调用ReapAnyOutstandingChildren

core/init/sigchld_handler.cpp

std::set<pid_t> ReapAnyOutstandingChildren() {
     
    std::set<pid_t> reaped_pids;
    for (;;) {
     
        const pid_t pid = ReapOneProcess();
        if (pid <= 0) {
     
            return reaped_pids;
        }
        reaped_pids.emplace(
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值