用Linux守护进程检测某个程序是否运行

环境:

主机:Fedora12

目标板:SC6410

目标板LINUX内核版本:2.6.36

实现功能:

做的一个嵌入式板子开机会自启动一个程序,但发现它工作数天后会退出。检查内存使用并没有泄漏,于是编写了一个守护进程来不断检查程序是否运行,没运行则运行它,这是一个折衷的办法。

说明:

需要运行的程序是AlarmInterface,位于目录/rf/下面。我做了一个脚本DuiJiang来启动这个AlarmInterface,并在脚本中添加了触摸屏支持。也就是说启动DuiJiang就可以启动AlarmInterface。检测程序是否运行的方法是通过ps -w|grep AlarmInterface指令获得AlarmInterface的进程,然后保存在一个文件中.检查AlarmInterface进程是否运行即可判断程序是否运行.

驱动源代码:

daemon_service.c:

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

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

相关推荐