zoukankan      html  css  js  c++  java
  • linux监控程序程序自动重启方法(转)

    转自:http://www.cnblogs.com/zhy113/archive/2013/03/15/2960910.html

    家在写server的时候,不管server写的是多么健壮,还是经常出现core dump等程序异常退出的,但是一般情况下需要在无人为干预情况下,能够自动重新启动,保证server程序能够服务用户。这时就需要一个监控程序来实现 能够让程序自动重新启动,现在笔者在写portmap就遇到了这个问题,通过网上查找资料,找到了一个相对靠谱的exec+fork解决方法。

    使用脚本实现自动重启

    首先想到的最简单的使用shell脚本,大概思路:

    ps -ef | grep “$1″ | grep -v “grep” | wc –l 是获取 $1 ($1 代表进程的名字)的进程数,脚本根据进程数来决定下一步的操作。通过一个死循环,每隔 1 秒检查一次系统中的指定程序的进程数,这里也可使用crontab来实现。

    这种方法比较土,还是可以基本解决问题,但是有1s的延迟,笔者在应用中未采用这种方法,有关这个shell脚本,请参看文章后面的附件代码。

    exec+fork方式

    笔者最终采用的exec+fork方式来实现的,具体思想如下:

    1,exec函数把当前进程替换为一个新的进程,新进程由path或file参数指定。可以使用exec函数将程序的执行从一个程序切换到另一个程序;

    2,fork函数是创建一个新的进程,在进程表中创建一个新的表项,而创建者(即父进程)按原来的流程继续执行,子进程执行自己的控制流程;

    3,wait 当fork启动一个子进程时,子进程就有了它自己的生命周期并将独立运行,我们可以在父进程中调用wait函数让父进程等待子进程的结束;

    相信介绍到这里,读者已经能够想到解决方法了:1)首先使用fork系统调用,创建子进程,2)在子进程中使用exec函数,执行需要自动重启的程序,3) 在父进程中执行wait等待子进程的结束,然后重新创建一个新的子进程。

    使用方法:

    #./portmap 需要监控的程序的路径
    #args portmap 需要的参数
    $ ./supervisor ./portmap  args.....

    代码如下:

    复制代码
    /**
     *
     * supervisor 
     *
     * author: liyangguang (liyangguang@software.ict.ac.cn)
     *
     * date: 2011-01-21 21:04:01
     *
     * changes
     * 1, execl to execv
     */
    #include <stdio.h>
    #include <unistd.h>
    #include <errno.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    #include <stdlib.h>int main(int argc, char **argv)
    {
        int ret, i, status;
        char *child_argv[100] = {0};
        pid_t pid;
        if (argc < 2) {
    
            fprintf(stderr, "Usage:%s <exe_path> <args...><strong>n</strong>", argv[0]);
            return -1;
        }
        for (i = 1; i < argc; ++i) {
            child_argv[i-1] = (char *)malloc(strlen(argv[i])+1);
            strncpy(child_argv[i-1], argv[i], strlen(argv[i]));
            child_argv[i-1][strlen(argv[i])] = '<strong>0</strong>';
        }
        while(1){
    
            pid = fork(); 
            if (pid == -1) {
                fprintf(stderr, "fork() error.errno:%d error:%s<strong>n</strong>", errno, strerror(errno));
            }
            if (pid == 0) {
                ret = execv(child_argv[0], (char **)child_argv);
                if (ret < 0) {
                    fprintf(stderr, "execv ret:%d errno:%d error:%s<strong>n</strong>", ret, errno, strerror(errno));
                    continue;
                }
                exit(0);
            }
    if (pid > 0) {
                pid = wait(&status);
    
                fprintf(stdout, "wait return");
            }
    
        }
    return 0;
    }
    复制代码

    shell脚本方式的代码如下:

    # 函数: CheckProcess
    # 功能: 检查一个进程是否存在
    # 参数: $1 --- 要检查的进程名称
    # 返回: 如果存在返回0, 否则返回1.
    #------------------------------------------------------------------------------
    CheckProcess()
    {
      # 检查输入的参数是否有效
      if [ "$1" = "" ];
      then
        return 1
      fi   #$PROCESS_NUM获取指定进程名的数目,为1返回0,表示正常,不为1返回1,表示有错误,需要重新启动
      PROCESS_NUM=`ps -ef | grep "$1" | grep -v "grep" | wc -l` 
      if [ $PROCESS_NUM -eq 1 ];
      then
        return 0
      else
        return 1
      fi
    }     # 检查test实例是否已经存在
    while [ 1 ] ; do
     CheckProcess "test"
     CheckQQ_RET=$?
     if [ $CheckQQ_RET -eq 1 ];
     then   # 杀死所有test进程,可换任意你需要执行的操作     killall -9 test
      exec ./test &  
     fi
     sleep 1
    done
  • 相关阅读:
    Leetcode Excel Sheet Column Number
    AlgorithmsI PA2: Randomized Queues and Deques Subset
    AlgorithmsI PA2: Randomized Queues and Deques RandomizedQueue
    AlgorithmsI PA2: Randomized Queues and Deques Deque
    AlgorithmsI Programming Assignment 1: PercolationStats.java
    hdu多校第四场 1003 (hdu6616) Divide the Stones 机智题
    hdu多校第四场 1007 (hdu6620) Just an Old Puzzle 逆序对
    hdu多校第四场1001 (hdu6614) AND Minimum Spanning Tree 签到
    hdu多校第三场 1007 (hdu6609) Find the answer 线段树
    hdu多校第三场 1006 (hdu6608) Fansblog Miller-Rabin素性检测
  • 原文地址:https://www.cnblogs.com/cxjchen/p/3062435.html
Copyright © 2011-2022 走看看