溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

linux如何實現(xiàn)監(jiān)控程序和程序自動重啟方法

發(fā)布時間:2022-01-05 09:42:51 來源:億速云 閱讀:255 作者:小新 欄目:云計算

小編給大家分享一下linux如何實現(xiàn)監(jiān)控程序和程序自動重啟方法,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

使用腳本實現(xiàn)自動重啟

首先想到的最簡單的使用shell腳本,大概思路:

ps -ef | grep “$1″ | grep -v “grep” | wc –l 是獲取 $1 ($1 代表進程的名字)的進程數(shù),腳本根據(jù)進程數(shù)來決定下一步的操作。通過一個死循環(huán),每隔 1 秒檢查一次系統(tǒng)中的指定程序的進程數(shù),這里也可使用crontab來實現(xiàn)。

這種方法比較土,還是可以基本解決問題,但是有1s的延遲,筆者在應用中未采用這種方法,有關這個shell腳本,請參看文章后面的附件代碼。

exec+fork方式

筆者最終采用的exec+fork方式來實現(xiàn)的,具體思想如下:

1,exec函數(shù)把當前進程替換為一個新的進程,新進程由path或file參數(shù)指定??梢允褂胑xec函數(shù)將程序的執(zhí)行從一個程序切換到另一個程序;

2,fork函數(shù)是創(chuàng)建一個新的進程,在進程表中創(chuàng)建一個新的表項,而創(chuàng)建者(即父進程)按原來的流程繼續(xù)執(zhí)行,子進程執(zhí)行自己的控制流程;

3,wait 當fork啟動一個子進程時,子進程就有了它自己的生命周期并將獨立運行,我們可以在父進程中調用wait函數(shù)讓父進程等待子進程的結束;

相信介紹到這里,讀者已經能夠想到解決方法了:1)首先使用fork系統(tǒng)調用,創(chuàng)建子進程,2)在子進程中使用exec函數(shù),執(zhí)行需要自動重啟的程序,3) 在父進程中執(zhí)行wait等待子進程的結束,然后重新創(chuàng)建一個新的子進程。

使用方法:

#./portmap 需要監(jiān)控的程序的路徑#args portmap 需要的參數(shù)$ ./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> intmain(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])] = '\0';}while(1){ 
        pid = fork(); if (pid == -1) {fprintf(stderr, "fork() error.errno:%d error:%s\n", 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:%s\n", ret, errno, strerror(errno));continue;}exit(0);} if (pid > 0) {pid = wait(&status); 
            fprintf(stdout, "wait return");} } 
 return 0;}

子進程的結束狀態(tài)返回后存于status,底下有幾個宏可判別結束情況  
WIFEXITED(status)如果子進程正常結束則為非0值。  
WEXITSTATUS(status)取得子進程exit()返回的結束代碼,一般會先用WIFEXITED 來判斷是否正常結束才能使用此宏。  
WIFSIGNALED(status)如果子進程是因為信號而結束則此宏值為真 

WTERMSIG(status)取得子進程因信號而中止的信號代碼,一般會先用WIFSIGNALED 來判斷后才使用此宏。  
WIFSTOPPED(status)如果子進程處于暫停執(zhí)行情況則此宏值為真。一般只有使用WUNTRACED 時才會有此情況。  
WSTOPSIG(status)取得引發(fā)子進程暫停的信號代碼,一般會先用WIFSTOPPED 來判斷后才使用此宏。

wait函數(shù)返回值總結

shell腳本方式的代碼如下:

# 函數(shù): CheckProcess# 功能: 檢查一個進程是否存在# 參數(shù): $1 --- 要檢查的進程名稱# 返回: 如果存在返回0, 否則返回1.#------------------------------------------------------------------------------CheckProcess(){
  # 檢查輸入的參數(shù)是否有效
  if [ "$1" = "" ];  thenreturn 1
  fi   #$PROCESS_NUM獲取指定進程名的數(shù)目,為1返回0,表示正常,不為1返回1,表示有錯誤,需要重新啟動
  PROCESS_NUM=`ps -ef | grep "$1" | grep -v "grep" | wc -l` 
  if [ $PROCESS_NUM -eq 1 ];  thenreturn 0
  elsereturn 1
  fi} 
 # 檢查test實例是否已經存在while [ 1 ] ; do
 CheckProcess "test"
 CheckQQ_RET=$?
 if [ $CheckQQ_RET -eq 1 ]; then # 殺死所有test進程,可換任意你需要執(zhí)行的操作 
   killall -9 test
  exec ./test &  
 fi
 sleep 1done

以上是“l(fā)inux如何實現(xiàn)監(jiān)控程序和程序自動重啟方法”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業(yè)資訊頻道!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經查實,將立刻刪除涉嫌侵權內容。

AI