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\n", 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\n", strerror(errno)); return; } // 如果子進程是由於某種信號退出的,捕獲該信號 if (WIFSIGNALED(status)) { int signalNum = WTERMSIG(status); printf("Child process was killed by signal num: %d\n", signalNum); } // 檢測是否生成了core文件 if (WCOREDUMP(status)) { printf("Child process core dump file generated\n"); } // 等待3秒鍾重新啟動子進程 sleep(3); pid = fork(); if (pid == 0) { printf("Fork new child process\n"); 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\n", getpid()); // 初始化看門狗進程 bool ret = initWatchDog(); if (!ret) { printf("Init watch dog failed\n"); return 1; } printf("Init watch dog success...\n"); // 運行子進程代碼 childProcessFunc(); return 0; } 

該例子的github地址:https://github.com/chxuan/samples/blob/master/WatchDog/WatchDog.cpp


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM