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

  • 相关阅读:
    3、Nginx负载均衡实现的策略
    2、Nginx 是如何实现并发的?为什么 Nginx 不使用多线程?Nginx常见的优化手段有哪些?502错误可能原因有哪些?
    1、HTTP 的负载均衡?Nginx负载均衡
    用 Python 手写十大经典排序算法
    处理TypeError: testFunc() missing 1 required positional argument: 'self' -- 没有实例化对象的错误
    Socket技术详解
    MAC终端常用命令
    接口自动化测试框架 -- reudom
    如何在Pypi发布上传你自己的Python库
    Docker数据目录迁移解决方案
  • 原文地址:https://www.cnblogs.com/highway-9/p/5515392.html
Copyright © 2011-2022 走看看