Linux之守护进程

时间:2021-05-16 04:44:31

想实现的目标是通过守护进程Monit监控另外一个进程Videocheck是否运行,如果Videocheck关闭,则由守护进程重新启动Videocheck进程

本身使用的系统是ubuntu 14.04

Monit的代码如下:

#include<unistd.h>
#include<signal.h>
#include<stdio.h>
#include<stdlib.h>
#include<sys/param.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<time.h>
#define BUFSZ 150
void init_daemon()
{
int pid;
int i;
pid=fork();
if(pid<0)
    exit(1);  //创建错误,退出
else if(pid>0) //父进程退出
    exit(0);


setsid(); //使子进程成为组长
pid=fork();
if(pid>0)
    exit(0); //再次退出,使进程不是组长,这样进程就不会打开控制终端
else if(pid<0)
    exit(1);


//关闭进程打开的文件句柄
for(i=0;i<NOFILE;i++)
    close(i);
chdir("/home/yl/Desktop/t");  //改变目录


umask(0);//重设文件创建的掩码
return;
}




void err_quit(char *msg)
{
perror(msg);
exit(EXIT_FAILURE);
}


// 判断程序是否在运行
int does_service_work()
{
FILE* fp;
int count;
char buf[BUFSZ];
char command[150];
sprintf(command, "ps -ef | grep Videocheck | grep -v grep | wc -l" );
if((fp = popen(command,"r")) == NULL)
err_quit("popen");


if( (fgets(buf,BUFSZ,fp))!= NULL )
{
count = atoi(buf);
}
pclose(fp);
    return count;
//      exit(EXIT_SUCCESS);
}

void main()
{
    FILE *fp;
    time_t t;
    int count;
    init_daemon();

    while(1)
    {
        sleep(1); //等待一分钟再写入
        fp=fopen("testfork345.log","a");
        
       if(fp>0)
        {
            count = does_service_work();
            time(&t);
           if(count>0)
           { fprintf(fp,"current time is:%s and the process exists, the count is %d\n",asctime(localtime(&t)), count);  //转换为本地时间输出 
            
           } else
            {
                fprintf(fp,"current time is:%s and the process does not exist, restart it!\n",asctime(localtime(&t)));  //转换为本地时间输出
                //printf("restart\rn");
               //system("/home/user/daemon/thisisatest"); //启动服务
              system("../Videocheck");
            }
            fclose(fp);
        }
    }
    return;
}



Videocheck的代码如下:


#include<unistd.h>
#include<signal.h>
#include<stdio.h>
#include<stdlib.h>
#include<sys/param.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<time.h>
int main()
{
    FILE *fp;
    time_t t;
    while(1)
    {
        sleep(1); //等待一分钟再写入
        fp=fopen("testfork5.log","a");
        if(fp>=0)
        {
            time(&t);
            fprintf(fp,"current time is:%s\n",asctime(localtime(&t)));  //转换为本地时间输出
            fclose(fp);
        }
    }
    return 0;
}



通过gcc  -o Monit Monit.c生成Monit程序

通过gcc  -o Videocheck Videocheck.c生成Videocheck程序


在/etc/init.d/rc.local文件增加./home/yl/Desktop/Monit

既可以开机启动守护程序,进而启动Videocheck程序。


关于开机启动守护程序,看了很多可以通过编写脚本的方式,本人编写脚本程序Monit.sh,具体内容如下,可以通过./Monit.sh start启动Monit, 但如果将该脚本放在/etc/init.d/rc.local里边却无法启动,以后有时间再研究

#! /bin/sh
###BEGIN INIT INFO
# Provides:            
# Description:       A simple example for daemon app
### END INIT INFO




if [ -f /etc/init.d/functions ]
then
    . /etc/init.d/functions
else
    . /lib/lsb/init-functions
fi


NAME=Example_Daemond
DAEMON=/home/yl/Desktop/Monit
LOCKFILE=/var/lock/subsys/$DAEMON
PIDFILE=/var/run/$NAME.pid


#start function 
start(){
    echo -n "Starting daemon: "$NAME
    start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON
    echo "."
}
#stop function
stop(){
    echo "Stopping $DAEMON ..."
    if pidof $DAEMON > /dev/null; then
        killall -9 $DAEMON > /dev/null
        rm -rf $PIDFILE
        echo "Stop $DAEMON Success..."
    fi    
}




#restart function
restart(){
    start
    stop
}


#status function 
status(){
    if pidof -o %PPID $DAEMON > /dev/null; then
             echo $NAME" is running..."
             exit 0
    else
             echo $NAME" is not running..."
             exit 1
    fi
}




case "$1" in
start)
    start
    ;;
stop)
    stop
    ;;
reload|restart)
    stop
    sleep 2
    start
    ;;
status)
    status
    ;;
*)
    echo $"Usage: $0 {start|stop|restart|status}"
    exit 1
esac