Linux中用守护进程检测程序运行

2019-07-12 20:05发布

做的一个嵌入式板子开机会自启动一个程序,但发现它工作数天后会退出。检查内存使用并没有泄漏,于是编写了一个守护进程来不断检查程序是否运行,没运行则运行它,这是一个折衷的办法。
说明:
需要运行的程序是AlarmInterface,位于目录/rf/下面。我做了一个脚本DuiJiang来启动这个AlarmInterface,并在脚本中添加了触摸屏支持。也就是说启动DuiJiang就可以启动AlarmInterface。检测程序是否运行的方法是通过ps -w|grep AlarmInterface指令获得AlarmInterface的进程,然后保存在一个文件中.检查AlarmInterface进程是否运行即可判断程序是否运行.
驱动源代码: daemon_service.c: [cpp] view plain copy
  1. "font-family:'Arial Black';font-size:18px;">//守护进程,守护AlarmInterface进程  
  2. //作者:jdh  
  3. //时间:2012-2-27  
  4. #include   
  5. #include   
  6. #include   
  7. #include   
  8. #include   
  9. #include   
  10.   
  11. //程序名字  
  12. #define NAME "AlarmInterface -qws"  
  13. //查找进程中程序名字  
  14. #define NAME_FIND "AlarmInterface"  
  15. //输出目录  
  16. #define DIR_OUT_FILE "/rf/out"  
  17. //要运行的程序  
  18. #define RUN_NAME "DuiJiang &"  
  19.   
  20. //#define DIR_OUT_FILE "/rf/out"  
  21. //#define NAME "gnome-keyring"  
  22. //#define NAME_FIND "gnome"  
  23. //#define DIR_OUT_FILE "/root/test/out"  
  24.   
  25. int daemon(int nochdir,int noclose)  
  26. {  
  27.     pid_t pid;  
  28.   
  29.     //让init进程成为新产生进程的父进程  
  30.     pid = fork();  
  31.     //如果创建进程失败  
  32.     if (pid < 0)  
  33.     {  
  34.         perror("fork");  
  35.         return -1;  
  36.     }  
  37.     //父进程退出运行  
  38.     if (pid != 0)  
  39.     {  
  40.         exit(0);  
  41.     }  
  42.     //创建新的会话  
  43.     pid = setsid();  
  44.     if (pid < -1)  
  45.     {  
  46.         perror("set sid");  
  47.         return -1;  
  48.     }  
  49.     //更改当前工作目录,将工作目录修改成根目录  
  50.     if (!nochdir)  
  51.     {  
  52.         chdir("/");  
  53.     }  
  54.     //关闭文件描述符,并重定向标准输入,输出合错误输出  
  55.     //将标准输入输出重定向到空设备  
  56.     if (!noclose)  
  57.     {  
  58.         int fd;  
  59.         fd = open("/dev/null",O_RDWR,0);  
  60.         if (fd != -1)  
  61.         {  
  62.             dup2(fd,STDIN_FILENO);  
  63.             dup2(fd,STDOUT_FILENO);  
  64.             dup2(fd,STDERR_FILENO);  
  65.             if (fd > 2)  
  66.             {  
  67.                 close(fd);  
  68.             }  
  69.         }  
  70.     }  
  71.     //设置守护进程的文件权限创建掩码  
  72.     umask(0027);  
  73.   
  74.     return 0;  
  75. }  
  76.   
  77. //是否有匹配的字符,有则返回1,没有返回0  
  78. //src:源字符串  
  79. //dst:目标字符串  
  80. //len:源字符串被比较的长度  
  81. int match(char *src,char *dst,int len)  
  82. {  
  83.     int i = 0;  
  84.     int j = 0;  
  85.     int size_dst = 0;  
  86.   
  87.     //获得目标字符串的长度  
  88.     size_dst = strlen(dst);  
  89.     //如果目标字符串的长度大于len,返回失败  
  90.     if (size_dst > len)  
  91.     {  
  92.         return 0;  
  93.     }     
  94.     //开始比较  
  95.     for (i = 0;i < len;i++)  
  96.     {  
  97.         for (j = 0;j < size_dst;j++)  
  98.         {  
  99.             if (src[i + j] != dst[j])  
  100.             {  
  101.                 break;  
  102.             }  
  103.         }  
  104.         if (j == size_dst)  
  105.         {  
  106.             return 1;  
  107.         }  
  108.     }  
  109.   
  110.     return 0;  
  111. }  
  112.   
  113. int main(int argc,char *argv[])  
  114. {  
  115.     int fd = 0;  
  116.     char buf[100];  
  117.   
  118.     //开启守护进程  
  119.     daemon(0,0);  
  120.   
  121.     while (1)  
  122.     {  
  123.         //打开日志  
  124.         openlog(argv[0],LOG_CONS|LOG_PID,LOG_USER);  
  125.           
  126.         //查看程序是否运行  
  127.         //新建输出文件  
  128.         system("touch "DIR_OUT_FILE);  
  129.         //获得程序ID  
  130.         system("ps -w|grep "NAME_FIND" >> "DIR_OUT_FILE);  
  131.         //打开输出文件  
  132.         fd = open(DIR_OUT_FILE,O_CREAT|O_RDONLY,0777);  
  133.         //清空缓存  
  134.         memset(buf,0,100);  
  135.         //读取全部  
  136.         read(fd,buf,100);  
  137.         //判断是否有程序文件运行  
  138.         if (match(buf,NAME,90))  
  139.         {  
  140.             syslog(LOG_INFO,"jdh success!!!!!!!!!!");  
  141.         }  
  142.         else  
  143.         {  
  144.             syslog(LOG_INFO,"jdh fail!!!!!!!!!!");  
  145.             //运行程序  
  146.             system(RUN_NAME);  
  147.         }  
  148.   
  149.         //休眠  
  150.         sleep(5);  
  151.         //删除输出文件  
  152.         system("rm "DIR_OUT_FILE);  
  153.           
  154.         //休眠  
  155.         sleep(55);  
  156.     }  
  157.   
  158.     //关闭日志  
  159.     closelog();  
  160.   
  161.     return 0;  
  162. }  
  163.   
  164.   

守护进程每分钟检测一次,用tail -f /var/log/messages可以看到守护进程输出的信息.