环境:
主机:Fedora12
目标板:SC6410
目标板LINUX内核版本:2.6.36
实现功能:
做的一个嵌入式板子开机会自启动一个程序,但发现它工作数天后会退出。检查内存使用并没有泄漏,于是编写了一个守护进程来不断检查程序是否运行,没运行则运行它,这是一个折衷的办法。
说明:
需要运行的程序是AlarmInterface,位于目录/rf/下面。我做了一个脚本DuiJiang来启动这个AlarmInterface,并在脚本中添加了触摸屏支持。也就是说启动DuiJiang就可以启动AlarmInterface。检测程序是否运行的方法是通过ps -w|grep AlarmInterface指令获得AlarmInterface的进程,然后保存在一个文件中.检查AlarmInterface进程是否运行即可判断程序是否运行.
驱动源代码:
daemon_service.c:
- //守护进程,守护AlarmInterface进程
- //作者:jdh
- //www.linuxidc.com
- //时间: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可以看到守护进程输出的信息。