Android framework Watchdog的监控过程

来源:互联网 发布:投资理财系统源码 编辑:程序博客网 时间:2024/05/07 08:00

用android的MountService来分析Watchdog的注册和监控过程. 代码路径为:

frameworks/base/services/java/com/android/server/MountService.java

此Watchdog为软件Watchdog, 在Android Framework中处理的事情有:

  1. 接收系统内部的reboot事件然后处理
  2. 监控SystemServer进程, 防止死锁
Watchdog是在SystemServer进程中启动并初始化的,然后也把自己交给Watchdog监控了.
Watchdog用的是单例模式, 所以整个系统只有一个Watchdog实例. 
获取方法为:
Watchdog.getInstance()

下面分析如何把MountServer添加到Watchdog的监控列表

首先MountServer必须implements Watchdog.Monitor 并且实现接口函数 monitor() , 
    /** {@inheritDoc} */    public void monitor() {        if (mConnector != null) {            mConnector.monitor();        }       } 
mConnector.monitor()的原型为
    /** {@inheritDoc} */     public void monitor() {        synchronized (mDaemonLock) { }    }

这个很简单, 如果mDaemonLock如果死锁的话, synchronized会一直阻塞住, 不能退出函数, 这就可以得到监控的目的了.

当实现了monitor()函数后就需要把实例自己添加到Watchdog的监控列表里面, 代码为:
        // Add ourself to the Watchdog monitors if enabled.        if (WATCHDOG_ENABLE) {            Watchdog.getInstance().addMonitor(this);        }
这个在MountService构造函数的最后部分.

添加完后我们来分析WatchDog如何监控的


1. watchdog 监控线程开始时发一个消息给自己handleMessage()做异步处理, 然后主线程等待30s后再继续往下跑 (这是wait(30s)函数, 当需要的时候可以随时唤醒).
2. 在handleMessage中会循环的运行通过addMonitor()加入进来的实例的monitor()函数, 如果顺利的话就很快完成, 然后设置mCompleted=true 成功退出.
3. 如果有其中一个monitor()死锁的话,这条异步处理线程就需要等待主线程那边的处理了, 要杀要宰随便, 反正不能往下跑了.

4. 在主线程这边, 当等待30秒后, 如果成功的话会继续下一论的sendMessage, handleMessage.  (mForceKillSystem这个是系统事件影响的, 正常情况下为false)
5. 如果发现mCompleted不是true的话,就代表有线程阻塞超过30秒, 如果是系统第一次超过30秒的话, 先把堆栈的信息保存并打印出来, 然后再尝试给系统一次机会, 再触发一次monitor()的监控.
6. 如果系统人品比较好的话, 说明上一次超时30秒不是死锁, 只是处理相对慢了而已, 这时候的处理就如步骤2
7. 不过一般系统人品没那么好, 会继续阻塞, 那么watchdog就认为当前系统真正死锁了. 1分钟啊, 足足给了系统1分钟的机会没有珍惜, 那也就时候把SystemServer 也就是自己Kill掉了. 为了预防Kill不够干脆, 后面加上exit()的操作. 这就双保险了. 

8. Kill掉了之后, init里会重新把SystemServer跑起来, 重新初始化一堆的service, 重新再做一次机器人了.


原创粉丝点击