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

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


说明:

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


驱动源代码:

daemon_service.c:

[cpp]  view plain  copy
  1. <span style="font-family:'Arial Black';font-size:18px;">//守护进程,守护AlarmInterface进程  
  2. //作者:jdh  
  3. //时间:2012-2-27  
  4. #include <stdio.h>  
  5. #include <unistd.h>  
  6. #include <sys/types.h>  
  7. #include <sys/stat.h>  
  8. #include <fcntl.h>  
  9. #include <syslog.h>  
  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. </span>  

守护进程每分钟检测一次,用tail -f /var/log/messages可以看到守护进程输出的信息.
Linux中,`fork()` 函数是一个用于创建新进程的标准库函数,它通常用于初始化子进程。下面是如何使用 `fork()` 函数创建新进程的基本步骤: 1. **包含头文件**: ```c #include <unistd.h> ``` 2. **调用 fork() 函数**: ```c pid_t pid = fork(); // fork() 函数返回值 ``` `fork()` 函数会创建一个新的进程,如果调用成功,返回当前进程的ID(0),新创建的子进程返回其自身的ID(通常是大于0的)。如果遇到错误,会返回-1。 3. **处理返回值**: - 如果 `pid == 0` (即返回0),这表示我们是在子进程中,可以继续执行特定于子进程的操作。 - 如果 `pid > 0` (父进程),那么我们可以对子进程进行监控,也可以忽略这个返回值,因为父进程无需进一步操作子进程。 4. **避免无限递归**(如果在子进程中再次调用 `fork()`,会陷入死循环): ```c if (pid == 0) { // 子进程代码... exit(0); // 或者使用 _exit() 来退出子进程 } else if (pid < 0) { // 错误处理 perror("fork failed"); exit(-1); } ``` 5. **子进程的行为**: - 子进程从父进程复制了大部分上下文,并有自己的地址空间,除了复制的部分外,父子进程之间共享的数据区(如全局变量、静态变量)都是相同的。 6. **通信和同步**(如果有需要的话): 使用 `wait()`、`waitpid()` 等函数来等待子进程结束,或者使用管道、消息队列等机制进行进程间通信。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值