zoukankan      html  css  js  c++  java
  • Linux编程之《看门狗进程》

    Intro

    当我们编写服务器代码时,为了让自己的服务器在意外崩溃时能够及时的重启,软件看门狗就显示出它的作用了,该看门狗进程是通过fork一个子进程(业务进程),父进程一旦捕获到了子进程的结束信号就重新再fork一个子进程来实现的,下面将完整代码贴上。

    
    /************************************************
     * 该例程讲解Linux软件看门狗的优雅编写方法
     *
     * 编写WatchDog有很多种方式:
     * a.一个WatchDog.sh脚本程序
     * b.一个WatchDog.exe可执行程序
     * c.一个可执行程序里面包含WatchDog
     *
     * 本例程就是使用的c方式,通过父进程监控子进程的运行状态来实现的
     * 其中父进程就是子进程(具体的任务进程)的WatchDog
    ************************************************/
    #include <unistd.h>
    #include <signal.h>
    #include <sys/wait.h>
    #include <errno.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <assert.h>
    
    void childProcessFunc()
    {
        int i = 0;
        while (true)
        {
            ++i;
            printf("i: %d, pid: %d, ppid: %d
    ", i, getpid(), getppid());
            if (i == 10)
            {
                // 子进程主动结束
                //exit(0);
                char* p = NULL;
                *p = 1;
            }
            sleep(1);
        }
    }
    
    void forkChildProcess(int)
    {
        int status = 0;
        // 等待子进程中断或终止,释放子进程资源
        // 否则死掉的子进程会变成僵尸进程
        int pid = wait(&status);
        if (pid < 0)
        {
            printf("error: %s
    ", strerror(errno));
            return;
        }
    
        // 如果子进程是由于某种信号退出的,捕获该信号
        if (WIFSIGNALED(status))
        {
            int signalNum = WTERMSIG(status);
            printf("Child process was killed by signal num: %d
    ", signalNum);
        }
    
        // 检测是否生成了core文件
        if (WCOREDUMP(status))
        {
            printf("Child process core dump file generated
    ");
        }
    
        // 等待3秒钟重新启动子进程
        sleep(3);
    
        pid = fork();
        if (pid == 0)
        {
            printf("Fork new child process
    ");
            childProcessFunc();
        }
    }
    
    bool initWatchDog()
    {
        int pid = fork();
        if (pid)
        {
            // 父进程一直监视子进程的运行状态
            while (true)
            {
                // 捕获子进程结束信号
                assert(signal(SIGCHLD, forkChildProcess) != SIG_ERR);
                // 父进程挂起,当有信号来时被唤醒
                pause();
            }
        }
        else if (pid < 0)
        {
            return false;
        }
    
        return true;
    }
    
    int main()
    {
        printf("Main pid: %d
    ", getpid());
    
        // 初始化看门狗进程
        bool ret = initWatchDog();
        if (!ret)
        {
            printf("Init watch dog failed
    ");
            return 1;
        }
    
        printf("Init watch dog success...
    ");
    
        // 运行子进程代码
        childProcessFunc(); 
    
        return 0;
    }
    
    

    该例子的github地址:https://github.com/chxuan/samples/blob/master/WatchDog/WatchDog.cpp

  • 相关阅读:
    Newtonsoft.Json.SerializeObject 转换参数
    EntityFramework Code First 特性
    删除SVN
    C# 数据库连接字符串
    javascript 计算后 无聊的小数点处理
    python index 自己实现
    springcloud 网关过滤器Zuul Filter
    Spring Cloud Feign服务通信与负载均衡机制
    Spring Cloid Ribbon服务的通信与负载均衡搭建
    spring-cloud注册中心集群
  • 原文地址:https://www.cnblogs.com/lidabo/p/14004695.html
Copyright © 2011-2022 走看看