Linux下監控程式並自動重啟的方法分享 如果是簡單的手機重啟,可以按如下操作進行: ----Linux 重啟命令---- Java代碼 1、shutdown 2、poweroff 3、init 4、reboot 5、halt 這裡不作介紹了,主要是講自動重啟實現方法。 使用指令碼實現自動重啟 首先想到的最簡單的使用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等待子進程的結束,然後重新建立一個新的子進程。 使用方法: Java代碼 #./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...>n", 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])] = ''; } while(1){ pid = fork(); if (pid == -1) { fprintf(stderr, "fork() error.errno:%d error:%sn", errno, strerror(errno)); break; } if (pid == 0) { ret = execv(child_argv[0], (char **)child_argv); //ret = execl(child_argv[0], "portmap", NULL, 0); if (ret < 0) { fprintf(stderr, "execv ret:%d errno:%d error:%sn", 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,表示有錯誤,需要重新啟動 Java代碼 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