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

  • 相关阅读:
    百万级数据迁移方案测评小记
    EFCore-一对一配置外键小记2
    mpvue实战-手势滑动导航栏
    React-Native WebView使用本地js,css渲染html
    Dubbo测试环境服务调用隔离这么玩对么
    Kitty中的动态线程池支持Nacos,Apollo多配置中心了
    嘘!异步事件这样用真的好么?
    一时技痒,撸了个动态线程池,源码放Github了
    熬夜之作:一文带你了解Cat分布式监控
    这个Maven依赖的问题,你敢说你没遇到过
  • 原文地址:https://www.cnblogs.com/lidabo/p/14004695.html
Copyright © 2011-2022 走看看