C++ – 写一个守护进程A,用于监控进程B,B挂掉就拉起

概述:

1、A可以是守护进程也可以是守护脚本

2、A是守护进程

3、A具有保活其他进程的服务

守护进程(已验证)

1 //main.c
  2 
  3 #include <stdio.h>
  4 #include <unistd.h>
  5 #include <sys/types.h>
  6 #include <sys/stat.h>
  7 #include <fcntl.h>
  8 #include <syslog.h>
  9 
 10 //守护应用名
 11 #define APP_NAME "untitled_ATU201console"
 12 //生成日志文件
 13 #define LOG_FILE "/home/root/ljc/folder_daemon/untitled_ATU201console.log"
 14 //匹配成功
 15 #define MATCH_RES "1"
 16 //启动守护应用的脚本
 17 #define SCRIPT_FILE "start_daemon"
 18 
 19 
 20 
 21 int daemon(int nochdir, int noclose) {
 22     pid_t pid;
 23 
 24     //让init进程成为新产生进程的父进程
 25     pid = fork();
 26     //如果创建进程失败
 27     if (pid < 0) {
 28         perror("fork");
 29         return -1;
 30     }
 31     //父进程退出运行
 32     if (pid != 0) {
 33         exit(0);
 34     }
 35     //创建新的会话
 36     pid = setsid();
 37     if (pid < -1) {
 38         perror("set sid");
 39         return -1;
 40     }
 41     //更改当前工作目录,将工作目录修改成根目录
 42     if (!nochdir) {
 43         chdir("/");
 44     }
 45     //关闭文件描述符,并重定向标准输入,输出合错误输出
 46     //将标准输入输出重定向到空设备
 47     if (!noclose) {
 48         int fd;
 49         fd = open("/dev/null", O_RDWR, 0);
 50         if (fd != -1) {
 51             dup2(fd, STDIN_FILENO);
 52             dup2(fd, STDOUT_FILENO);
 53             dup2(fd, STDERR_FILENO);
 54             if (fd > 2) {
 55                 close(fd);
 56             }
 57         }
 58     }
 59     //设置守护进程的文件权限创建掩码
 60     umask(0027);
 61 
 62     return 0;
 63 }
 64 
 65 //是否有匹配的字符,有则返回1,没有返回0
 66 //src:源字符串
 67 //dst:目标字符串
 68 //len:源字符串被比较的长度
 69 int match(char *src, char *dst, int len) {
 70     syslog(LOG_INFO, "--------------------match1");
 71 
 72     int i = 0;
 73     int j = 0;
 74     int size_dst = 0;
 75 
 76     //获得目标字符串的长度
 77     size_dst = strlen(dst);
 78     //如果目标字符串的长度大于len,返回失败
 79     if (size_dst > len) {
 80         syslog(LOG_INFO, "--------------------match11");
 81         return 0;
 82     }
 83 
 84     syslog(LOG_INFO, "--------------------match2");
 85 
 86     //开始比较
 87     for (i = 0; i < len; i++) {
 88         for (j = 0; j < size_dst; j++) {
 89             if (src[i + j] != dst[j]) {
 90                 break;
 91             }
 92         }
 93         if (j == size_dst) {
 94             return 1;
 95         }
 96     }
 97 
 98     syslog(LOG_INFO, "--------------------match3");
 99 
100     return 0;
101 }
102 
103 int main(int argc, char *argv[]) {
104     int fd = 0;
105     char buf[100];
106 
107     //开启守护进程
108     daemon(0, 0);
109 
110     while (1) {
111         syslog(LOG_INFO, "--------------------main1");
112 
113         //打开日志
114         openlog(argv[0], LOG_CONS | LOG_PID, LOG_USER);
115 
116         //查看程序是否运行
117         //新建输出文件
118         system("touch "LOG_FILE);
119         //获得程序ID
120         system("ps -ef | grep "APP_NAME" | grep -v grep | wc -l >> "LOG_FILE);
121         //打开输出文件
122         fd = open(LOG_FILE, O_CREAT | O_RDONLY, 0777);
123         //清空缓存
124         memset(buf, 0, 100);
125         //读取全部
126         read(fd, buf, 100);
127 
128         syslog(LOG_INFO, "--------------------main2");
129 
130         //判断是否有程序文件运行
131 //        if (match(buf, MATCH_RES, 1)) {
132 //            syslog(LOG_INFO, "match success!!!");
133 //        } else {
134 //            syslog(LOG_INFO, "match fail!!!");
135 //            //运行程序
136 //            system(SCRIPT_FILE);
137 //        }
138 
139         int res = memcmp(buf, MATCH_RES, 1);
140         syslog(LOG_INFO, "buf = %s\n", buf);
141         syslog(LOG_INFO, "MATCH_RES = %s\n", MATCH_RES);
142         syslog(LOG_INFO, "res = %d\n", res);
143         if ( res == 0) {
144             syslog(LOG_INFO, "match success!!!");
145         } else {
146             syslog(LOG_INFO, "match fail!!!");
147             //运行程序
148 //            system(SCRIPT_FILE);
149             system("/home/root/ljc/folder_daemon/untitled_ATU201console &");
150         }
151 
152         syslog(LOG_INFO, "--------------------main3");
153 
154         //休眠
155         sleep(2);
156         //删除输出文件
157         system("rm "LOG_FILE);
158         //休眠
159         sleep(5);
160     }
161     //关闭日志
162     closelog();
163 
164     return 0;
165 }

守护脚本1(待验证)

1 //假设要监控的进程名称为test,TargetProcessName为启动该进程的脚本,status 有一系列的宏 对应可以检测。 
 2 while [ 0 ]
 3 do
 4     Result=$(ps -ef | grep -v grep |grep "test")
 5     if [ "" == "$Result" ]
 6     then
 7 RecordTime=$(date)
 8 echo  "Restar test" >>$LogFile
 9         nohup $TargetProcessName>>$LogFile &
10 sleep 2
11     fi
12     Result=
13 done

守护脚本2(待验证)

1 #!/bin/bash
 2 # 直接上代码吧
 3 # watchdog.sh
 4 
 5 #定义映射表 k=进程号 v=作业
 6 declare -A mapper
 7 #进程号文件
 8 conf=dog.pid
 9 
10 
11 function debug
12 {
13     echo $@
14 }
15 
16 #param pid 进程号 
17 #使用ps命令查询该进程是否存在,如果不存在返回"gone",否则返回"stay"
18 
19 function watch
20 {
21     local pid=$1
22     local index=`ps -ef|awk '{print $2}'|grep -P "^${pid}$"`
23     if [ "${index}None" = "None" ]; then
24         echo gone
25         return
26     fi
27     echo stay
28 }
29 
30 #每过5秒钟检查一遍所有的进程,调用上面的watch
31 
32 function dogit
33 {
34     while [ 1 ]
35     do
36         sleep 5
37         for pid in ${!mapper[@]}
38         do
39             debug pid:$pid
40             local t=`watch $pid`
41             debug "test result is $t!!!"
42             if [ "$t" = "gone" ]; then
43                 debug "$c with pid $pid was gone"
44                 loadscript ${mapper[$pid]}
45                 unset mapper[$pid]
46                 sed -i "/$pid/d" $conf
47             fi
48         done
49     done
50 }
51 
52 #从作业文件加载需要守护的作业命令
53 
54 function loadscript
55 {
56     local script=$@
57     debug script=$script
58     $script > /dev/null &
59     local pid=$!
60     mapper[$pid]=$script
61     echo $pid >> $conf
62 }
63 
64 function clean
65 {
66     if [ -f $conf ]; then
67         while read line; do
68             if [ -n "$line" ]; then
69                 pid=`ps -ef|awk '{print $2}'|grep $line|grep -v 'grep'`
70                 if [ -n "${pid}" ]; then
71                     debug killing $pid
72                     kill $pid
73                 fi
74             fi
75         done < $conf
76     fi
77     echo > $conf
78     debug done!
79 }
80 
81 function main
82 {
83     clean
84     local file=$1
85     if [ -f $file ]; then
86         while read line
87         do
88             loadscript $line
89         done < $file
90         dogit
91     else
92         echo "Not a file!"
93     fi
94 }
95 
96 main $1;

原文链接: https://www.cnblogs.com/citrus/p/14183721.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/206399

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月12日 下午10:35
下一篇 2023年2月12日 下午10:35

相关推荐