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

  • 相关阅读:
    SqlMembershipProvider的配置
    自定义HtppHandler和HttpModule
    [导入]Sql Server 2005 Express中配置用户
    [导入]Asp.net中使用客户端脚本的方法
    JumpServer 架构浅解
    你准备好开始DevOps了吗?
    为什么是戒了爱你
    今天考试了
    [心疼女友]
    这个世界看不清
  • 原文地址:https://www.cnblogs.com/highway-9/p/5515392.html
Copyright © 2011-2022 走看看