用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可以看到守護進程輸出的信息。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章