環境:
主機: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可以看到守護進程輸出的信息。