转载:http://blog.csdn.net/21cnbao/article/details/7748729

在一个典型的嵌入式系统中,会存在一个硬件看门狗,正常运转的系统会周期喂狗,否则证明系统hang了。硬件看门狗存在相当大的局限性,它只能监控整个系统而不能监控单个的进程或者线程。于是发明软件看门狗意义重大。SystemServer会用到软件看门狗来确保AM 、PM、WM这几个服务hang住之后,退出SystemServer进程,从而进入上回书中的Zygote与SystemServer的生死与共。注意service是hang而不是死,绕到个死胡同里出不来了。镜湖女侠决定了革命,你再怎么去说服她也没有用了。这些重要的service运行于SystemServer的进程空间,在祖国的怀抱里长大,它们热爱祖国热爱人民,只是步调偏了,不按照当局规定的方式“爱国”,当局透过Java里面去synchronized某锁拿思想汇报的时候长时间拿不到。

我们随便读一下PowerManagerService.java的源代码,会发现几乎所有的重要操作都会透过synchronized其中的mLocks进行,咱们抓几个看看:

很显然,如果我们故意去synchronizedmLocks这个锁,如果长时间拿不到,基本可认定PowerManagerService在某个操作里面hang了,短时间或者直接就拿到了,证明一切正常。PowerManagerService里面实现了monitor成员函数来synchronized mLocks:

[java]view plaincopy
  1. //forwatchdog
  2. publicvoidmonitor(){
  3. synchronized(mLocks){}
  4. }

同样的道理,对于其他的几个service,我们也可以用类似的方法来验证它们是否hang。同志们啊,很多国内的书或者文档里面把这个侦测hang的过程说成是侦测死锁,含义其实是大错特错了,也把广大的读者搞地不知所云。因为死锁只是引起hang的一种可能,hang的含义则更加广泛。缓刑或者监外执行的罪犯,周期性地会去派出所报告工作,如果没去报告,很可能不是被家里人死锁在房间里打不开门了,更可能是跑路了。

同样,国内很多的教科书以内核cs8900驱动为例讲解网络设备驱动,我也反复在各大公司澄清过cs8900 那就是一反面教材,是一个平台相关信息渗透入与平台无关驱动代码的典型错误范例,需要拨乱反正啊有木有?

了解了侦测service hang的原理,我们需要一套方法来实现这个侦测,这个过程透过watchdog来实现。在Android中,watchdog继承于thread类,代码位于frameworks/base/services/java/com/android/server/Watchdog.java。采用单例模式,提供getInstance() 接口,同时在watchdog创建的过程中,会创建一个用于消息处理的HeartbeatHandler:

[java]view plaincopy
  1. publicstaticWatchdoggetInstance(){
  2. if(sWatchdog==null){
  3. sWatchdog=newWatchdog();
  4. }
  5. returnsWatchdog;
  6. }
  7. privateWatchdog(){
  8. super("watchdog");
  9. mHandler=newHeartbeatHandler();
  10. }

SystemServer会调用watchdog的start函数,从而让继承于thread的Watchdog的run函数在一新线程被执行:

[java]view plaincopy
  1. publicvoidrun(){
  2. booleanwaitedHalf=false;
  3. while(true){
  4. mCompleted=false;
  5. mHandler.sendEmptyMessage(MONITOR);//引发HeartbeatHandler在相应线程处理MONITOR消息
  6. synchronized(this){
  7. longtimeout=TIME_TO_WAIT;//周期性等待
  8. longstart=SystemClock.uptimeMillis();
  9. while(timeout>0&&!mForceKillSystem){
  10. try{
  11. wait(timeout);
  12. }catch(InterruptedExceptione){
  13. Log.wtf(TAG,e);
  14. }
  15. timeout=TIME_TO_WAIT-(SystemClock.uptimeMillis()-start);
  16. }
  17. if(mCompleted&&!mForceKillSystem){
  18. //monitor都返回了,mCompleted为真
  19. waitedHalf=false;
  20. continue;
  21. }
  22. if(!waitedHalf){
  23. //monitor没有都返回,再进行第二次等待判断
  24. waitedHalf=true;
  25. continue;
  26. }
  27. }
  28. //第2次了,monitor还没都返回,确实hung了
  29. if(!Debug.isDebuggerConnected()){
  30. //SystemServer自杀
  31. Process.killProcess(Process.myPid());
  32. System.exit(10);
  33. }else{
  34. Slog.w(TAG,"Debuggerconnected:Watchdogis*not*killingthesystemprocess");
  35. }
  36. waitedHalf=false;
  37. }
  38. }

这个run函数实现比较简单, 周期性地设置mCompleted变量为假,通知心跳handler去调用各个monitor,而心跳handler会调用各个service的monitor,如果各个monitor都返回了,心跳handler会将mCompleted设置为真(这个过程是不是和使用硬件看门狗的情况下把定时器复位惊人的相似?因此,我们可以把这个过程看做“喂狗”)。否则,经过2次等待watchgod的run()发现mCompleted还为假,就证明hang了。我们看看心跳handler调用各个monitor的过程并“喂狗”的过程:

[java]view plaincopy
  1. finalclassHeartbeatHandlerextendsHandler{
  2. @Override
  3. publicvoidhandleMessage(Messagemsg){
  4. switch(msg.what){
  5. caseMONITOR:{
  6. //调用每个monitor
  7. finalintsize=mMonitors.size();
  8. for(inti=0;i<size;i++){
  9. mCurrentMonitor=mMonitors.get(i);
  10. mCurrentMonitor.monitor();
  11. }
  12. synchronized(Watchdog.this){
  13. mCompleted=true;//修改mCompleted为true
  14. mCurrentMonitor=null;
  15. }
  16. }break;
  17. }
  18. }
  19. }

而PowerManagerService等service如何进入上面代码中的for循环呢?那是因为他们正好实现了这个Watchdog.Monitor接口,并透过Watchdog.getInstance().addMonitor(this)加到了monitor列表里面。

结合第一回和第二回,我们基本可以看出整个Android软件自愈过程的“环环相扣”,成为一个多么完美的体系啊!SystemServer监控重要service,重要service hang则SystemServer死,SystemServer死则Zygote监控到,Zygote也死并且杀死整个Java世界,Zygote死则init监控到,init重新启动Zygote,之后SystemServer、service又进入重生过程,与死亡的过程相反。

这个过程我们看到了多进程之间的千丝万缕的联系,以及多进程模型的魅力和设计哲学,程序员喜欢孤立的去看待自己的程序而不是总揽全局,而从体系架构的角度去思考问题,我们更加能清楚我们位于整个软件的哪个组成部分。和宇宙大爆炸比起来,咱屌丝们的房子、车子都不过是过眼云烟,所以我们要尽快把自己的人生理想调整到配合宇宙大爆炸的方向上来。从Android的init、Zygote、SystemServer和重要service的彼此关联中,我们至少体会到了一些什么,整天盯着自己的几个函数玩,不在宇宙里玩,玩地多不过瘾啊?关系上是“宇宙大爆炸->Android-> 程序员”,不是“函数->模块->Android”,这是研究Android的方法学。

Android WatchDog正解相关推荐

  1. android常用api大全,Android API详解大全.pdf

    Android API详解大全 Android -- TextView 一.TextView的API 1.1 结构 java.lang.Object ↳ android.view.View ↳ and ...

  2. android watchdog机制

    Android Watchdog 机制 早期手机平台上通常是在设备中增加一个硬件看门狗(WatchDog), 软件系统必须定时的向看门狗硬件中写值来表示自己没出故障(俗称"喂狗") ...

  3. Android MVP 详解(上)

    作者:李旺成 时间:2016年4月3日 "Android MVP 详解(下)"已经发布,欢迎大家提建议. MVP 在 Android 上的使用其实已经有挺长一段时间了,长到似乎有点 ...

  4. Android JNI 详解

    Android JNI 详解 简介 JNI 应该是所有Android老鸟都绕不过的"坎"吧,之所以说是"坎"是因为它比较难,因为他不仅涉及Android开发者的 ...

  5. android动画详解二 属性动画原理

    property动画是一个强大的框架,它几乎能使你动画任何东西.你可以定义一个动画来改变对象的任何属性,不论其是否被绘制于屏幕之上.一个属性动画在一定时间内多次改变一个属性(对象的一个字段)的值.要动 ...

  6. 【转】Android菜单详解——理解android中的Menu--不错

    原文网址:http://www.cnblogs.com/qingblog/archive/2012/06/08/2541709.html 前言 今天看了pro android 3中menu这一章,对A ...

  7. Android菜单详解——理解android中的Menu

    前言 今天看了pro android 3中menu这一章,对Android的整个menu体系有了进一步的了解,故整理下笔记与大家分享. PS:强烈推荐<Pro Android 3>,是我至 ...

  8. Android LayoutInflater详解

    Android LayoutInflater详解 在实际开发中LayoutInflater这个类还是非常有用的,它的作用类 似于findViewById().不同点是LayoutInflater是用来 ...

  9. android Fragments详解

    android Fragments详解一:概述 android Fragments详解二:创建Fragment 转载于:https://my.oschina.net/liangzhenghui/blo ...

最新文章

  1. 深度学习Dropout技术分析
  2. 雨课堂c语言考试题库2020,雨课堂2020题目答案,雨课堂2020作业答案
  3. python+mysql:实现一千万条数据插入数据库
  4. 腾讯 AI Lab 联手迈瑞医疗,助力血液病筛查与体外诊断
  5. Day-4: Python函数
  6. 生命很短,我用tldr
  7. 域中计算机与用户,域内计算机和用户获取实现vbs代码
  8. 教你使用Python实现新个税计算器
  9. (转)淘淘商城系列——SSM框架整合之Dao层整合
  10. 03.三月风雨愁断肠,学习大数据特别忧伤——谈谈AKS创建SQL Server大数据群集创建愁断肠
  11. php输入数据不能为空,输入的数据模型标识(modelID)'的值不能为空或者空白字符串...
  12. Linux命令格式及目录与文件常用命令
  13. 网络运营和网络营销有什么区别?
  14. asp.net中gridview的绑定数据源实现增删改查
  15. 小米首页二级菜单栏实现原理
  16. 论职务犯罪案件侦查 z
  17. ARM中MRS和MSR汇编指令
  18. 算法:食物链(并查集)
  19. 浅谈商学院的功能以及重要性
  20. 【6】在Linux上部署各类软件

热门文章

  1. 秘笈|如何利用DNS做好网络安全工作
  2. WebService 之 WSDL详解
  3. springmvc多文件上传
  4. chrome的cookies
  5. ASP与數据庫,文本文件鏈接精髓
  6. 交换机 路由器 OSI7层模型
  7. LeetCode 394: DecodeString (Java)
  8. 使用Echarts制作散点图(Excel导入数据方式)
  9. C#中的String类
  10. 直接从Windows7RC版升级安装RTM版本的小窍门