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

实现功能:

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

说明:

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

--------------------- 作者:jdh99 来源:CSDN 原文:https://blog.csdn.net/jdh99/article/details/7300641?utm_source=copy 版权声明:本文为博主原创文章,转载请附上博文链接!

//守护进程,守护AlarmInterface进程
//作者:jdh
//时间:2012-2-27
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <syslog.h>
 
//程序名字
#define NAME "AlarmInterface -qws"
//查找进程中程序名字
#define NAME_FIND "AlarmInterface"
//输出目录
#define DIR_OUT_FILE "/rf/out"
//要运行的程序
#define RUN_NAME "DuiJiang &"
 
//#define DIR_OUT_FILE "/rf/out"
//#define NAME "gnome-keyring"
//#define NAME_FIND "gnome"
//#define DIR_OUT_FILE "/root/test/out"
 
int daemon(int nochdir,int noclose)
{
    pid_t pid;
 
    //让init进程成为新产生进程的父进程
    pid = fork();
    //如果创建进程失败
    if (pid < 0)
    {
        perror("fork");
        return -1;
    }
    //父进程退出运行
    if (pid != 0)
    {
        exit(0);
    }
    //创建新的会话
    pid = setsid();
    if (pid < -1)
    {
        perror("set sid");
        return -1;
    }
    //更改当前工作目录,将工作目录修改成根目录
    if (!nochdir)
    {
        chdir("/");
    }
    //关闭文件描述符,并重定向标准输入,输出合错误输出
    //将标准输入输出重定向到空设备
    if (!noclose)
    {
        int fd;
        fd = open("/dev/null",O_RDWR,0);
        if (fd != -1)
        {
            dup2(fd,STDIN_FILENO);
            dup2(fd,STDOUT_FILENO);
            dup2(fd,STDERR_FILENO);
            if (fd > 2)
            {
                close(fd);
            }
        }
    }
    //设置守护进程的文件权限创建掩码
    umask(0027);
 
    return 0;
}
 
//是否有匹配的字符,有则返回1,没有返回0
//src:源字符串
//dst:目标字符串
//len:源字符串被比较的长度
int match(char *src,char *dst,int len)
{
    int i = 0;
    int j = 0;
    int size_dst = 0;
 
    //获得目标字符串的长度
    size_dst = strlen(dst);
    //如果目标字符串的长度大于len,返回失败
    if (size_dst > len)
    {
        return 0;
    }    
    //开始比较
    for (i = 0;i < len;i++)
    {
        for (j = 0;j < size_dst;j++)
        {
            if (src[i + j] != dst[j])
            {
                break;
            }
        }
        if (j == size_dst)
        {
            return 1;
        }
    }
 
    return 0;
}
 
int main(int argc,char *argv[])
{
    int fd = 0;
    char buf[100];
 
    //开启守护进程
    daemon(0,0);
 
    while (1)
    {
        //打开日志
        openlog(argv[0],LOG_CONS|LOG_PID,LOG_USER);
        
        //查看程序是否运行
        //新建输出文件
        system("touch "DIR_OUT_FILE);
        //获得程序ID
        system("ps -w|grep "NAME_FIND" >> "DIR_OUT_FILE);
        //打开输出文件
        fd = open(DIR_OUT_FILE,O_CREAT|O_RDONLY,0777);
        //清空缓存
        memset(buf,0,100);
        //读取全部
        read(fd,buf,100);
        //判断是否有程序文件运行
        if (match(buf,NAME,90))
        {
            syslog(LOG_INFO,"jdh success!!!!!!!!!!");
        }
        else
        {
            syslog(LOG_INFO,"jdh fail!!!!!!!!!!");
            //运行程序
            system(RUN_NAME);
        }
 
        //休眠
        sleep(5);
        //删除输出文件
        system("rm "DIR_OUT_FILE);
        
        //休眠
        sleep(55);
    }
 
    //关闭日志
    closelog();
 
    return 0;
}
 
守护进程每分钟检测一次,用tail -f /var/log/messages可以看到守护进程输出的信息.

猜你喜欢

转载自blog.csdn.net/mianhuantang848989/article/details/82995739