android init重启service(进程)

在init进程的main函数中有调用sigchld_handler_init() 设置SIGCHLD signal。

在子进程比如收到signal时,init进程会收到通知,在SIGCHLD_handler()中write;然后在handle_signal()中read;然后会调用ReapOneProcess();然后调用这个service对象的reap()

void sigchld_handler_init() {
    // Create a signalling mechanism for SIGCHLD.
    int s[2];
    if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0, s) == -1) {
        PLOG(FATAL) << "socketpair failed in sigchld_handler_init";
    }

    signal_write_fd = s[0];
    signal_read_fd = s[1];

    // Write to signal_write_fd if we catch SIGCHLD.
    struct sigaction act;
    memset(&act, 0, sizeof(act));
    act.sa_handler = SIGCHLD_handler;
    act.sa_flags = SA_NOCLDSTOP;
    sigaction(SIGCHLD, &act, 0);

    ReapAnyOutstandingChildren();

    register_epoll_handler(signal_read_fd, handle_signal);
}

在Reap()中,以media service为例,它应该是没有SVC_ONESHOT flag的,所以会调Service::KillProcessGroup(),这个函数会发signal SIGKILL(9)给media进程以杀掉它。

然后调用onrestart_.ExecuteAllCommands()

void Service::Reap(const siginfo_t& siginfo) {
    if (!(flags_ & SVC_ONESHOT) || (flags_ & SVC_RESTART)) {
        KillProcessGroup(SIGKILL);
    }

    // Remove any descriptor resources we may have created.
    std::for_each(descriptors_.begin(), descriptors_.end(),
                  std::bind(&DescriptorInfo::Clean, std::placeholders::_1));

    for (const auto& f : reap_callbacks_) {
        f(siginfo);
    }

    if (flags_ & SVC_EXEC) UnSetExec();

    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_DISABLED;
    }

    // Disabled and reset processes do not get restarted automatically.
    if (flags_ & (SVC_DISABLED | SVC_RESET))  {
        NotifyStateChange("stopped");
        return;
    }

    // If we crash > 4 times in 4 minutes, reboot into recovery.
    boot_clock::time_point now = boot_clock::now();
    if ((flags_ & SVC_CRITICAL) && !(flags_ & SVC_RESTART)) {
        if (now < time_crashed_ + 4min) {
            if (++crash_count_ > 4) {
                LOG(FATAL) << "critical process ‘" << name_ << "‘ exited 4 times in 4 minutes";
            }
        } else {
            time_crashed_ = now;
            crash_count_ = 1;
        }
    }

    flags_ &= (~SVC_RESTART);
    flags_ |= SVC_RESTARTING;

    // Execute all onrestart commands for this service.
    onrestart_.ExecuteAllCommands();

    NotifyStateChange("restarting");
    return;
}

这个onrestart_.ExecuteAllCommands()对于media进程来说,它没有添加command(如下面的mediaserver.rc),所以不会做什么事情。

frameworks/av/media/mediaserver/mediaserver.rc

service media /system/bin/mediaserver
    class main
    user media
    group audio camera inet net_bt net_bt_admin net_bw_acct drmrpc mediadrm
    ioprio rt 4
    writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks

  

  

  

原文地址:https://www.cnblogs.com/aspirs/p/11407611.html

时间: 2024-10-28 22:46:33

android init重启service(进程)的相关文章

Android init进程——属性服务

目录 目录 概述 属性服务 属性服务初始化 创建存储空间 __system_property_area_init init_workspace 客户端进程访问属性内存区域 属性服务器的分析 启动属性服务器 服务端处理设置属性请求 客户端发送请求 概述 init是一个进程,确切的说,它是Linux系统中用户空间的第一个进程.由于Android是基于Linux内核的,所以init也是Android系统中用户空间的第一个进程.init的进程号是1.作为天字第一号进程,init有很多重要的工作: ini

Android -- Init进程对信号的处理流程

Android -- Init进程对信号的处理流程 在Android中,当一个进程退出(exit())时,会向它的父进程发送一个SIGCHLD信号.父进程收到该信号后,会释放分配给该子进程的系统资源:并且父进程需要调用wait()或waitpid()等待子进程结束.如果父进程没有做这种处理,且父进程初始化时也没有调用signal(SIGCHLD, SIG_IGN)来显示忽略对SIGCHLD的处理,这时子进程将一直保持当前的退出状态,不会完全退出.这样的子进程不能被调度,所做的只是在进程列表中占据

Android service进程保护

应用进程保活基本就是围绕两个方面来展开: 1 尽量保证进程不被杀死. 2 进程被杀死后复活.细分如下: 1)Service重启 2)进程守护 3)Receiver触发 4) AlarmManager or JobScheduler循环触发 5)与系统Service捆绑-–可以不考虑,了解即可 下面将围绕这几点展开讨论. 一,基本概念 1.什么才叫应用进程保活 应用进程保活可以理解为应用位于后台永远不能被杀死.这里的可以简略地分为两种情况,第一种是当系统资源紧俏的时候或者基于某种系统自身的后台运行

Android init进程——源码分析

概述 Android本质上是一个基于Linux内核的开源操作系统,与我现在用的Ubuntu系统类似,但是所有的Android设备都是运行在ARM处理器(ARM源自进阶精简指令集机器,源自ARM架构)上,而像Ubuntu操作系统是x86(x86是一系列的基于intel 8086 CPU计算机微处理器指令集架构)系统.不过既然Android也是基于Linux内核的系统,那么基本的启动过程也应该符合Linux的规则.下图基本描述了当你按下电源开关后Android设备的执行步骤: 一个完整的Linux系

android init进程分析 基本流程

(懒人最近想起我还有csdn好久没打理了,这个android init躺在我的草稿箱中快5年了,稍微改改发出来吧) android设备上电,引导程序引导进入boot(通常是uboot),加载initramfs.kernel镜像,启动kernel后,进入用户态程序.第一个用户空间程序是init, PID固定是1.在android系统上,init的代码位于/system/core/init下,基本功能有: 管理设备 解析并处理启动脚本init.rc 实时维护这个init.rc中的服务 init进程的

Android init进程——解析配置文件

目录 目录 init解析配置文件 关键字定义 kw_is 解析 K_import K_on command执行 K_service service service结构体 parse_service parse_line_service init控制service init解析配置文件 在解析service服务是如何启动之前,让我们先来学习一下init进程是如何解析init.rc等配置文件的. init进程解析配置文件的代码如下(/system/core/init/init.c&&/syst

ANDROID init进程

init简要 init是Android上启动的第一个用户态进程. 执行序列是: start_kernel() -> rest_init() -> kernel_init() -> init_post() -> run_init_process() if (ramdisk_execute_command) { //rdinit, default "/init" run_init_process(ramdisk_execute_command); printk(KE

android init进程分析 init脚本解析和处理

(懒人近期想起我还有csdn好久没打理了.这个android init躺在我的草稿箱中快5年了.略微改改发出来吧) RC文件格式 rc文件是linux中常见的启动载入阶段运行的文件.rc是run commands的缩写.基本上能够理解为在启动阶段运行的一些列命令.android init进程启动时,也会运行此启动脚本文件,init.rc.init.rc的写法稍有点复杂,具体可參考 /system/core/init下的readme文件.脚本基本组成是由四类,为: commands: 命令 act

Android中的跨进程通信方法实例及特点分析(一):AIDL Service

转载请注明出处:http://blog.csdn.net/bettarwang/article/details/40947481 最近有一个需求就是往程序中加入大数据的采集点,但是因为我们的Android程序包含两个进程,所以涉及到跨进程通信的问题.现将Android中的跨进程通信方式总结如下. Android中有4种跨进程通信方式,分别是利用AIDL Service.ContentProvider.Broadcast.Activity实现. 1.利用AIDL Service实现跨进程通信 这是