问题描述:一个父进程监控多个子进程,子进程执行函数f,若子进程挂掉,则重新fork一个子进程。
#ifndef MS_MONITOR_H_ #define MS_MONITOR_H_ 3 #include <iostream> 4 #include <string> 5 #include <vector> 6 #include <sys/types.h> 7 #include <sys/wait.h> 8 #include <sys/stat.h> 9 10 typedef int (*superMonitorHndl)(int argc, char **argv); 11 static int run_child = 0; 12 13 class SuperMonitor{ 14 public: 15 SuperMonitor(); 16 SuperMonitor(int childnum); 17 ~SuperMonitor(); 18 void Initial(superMonitorHndl f); 19 20 private: 21 int startChild(std::vector<pid_t>& pidArr,superMonitorHndl f); 22 bool isAbnormalExit(int pid, int status); 23 void Run (superMonitorHndl f); 24 25 int child_num; 26 }; 27 28 #endif
#include <iostream> 1 #include <string> 2 #include <vector> 3 #include <sys/types.h> 4 #include <unistd.h> 5 #include <fcntl.h> 6 #include <stdlib.h> 7 #include <sys/wait.h> 8 #include <sys/stat.h> 9 #include "super_monitor.h" 10 using namespace std; 11 12 SuperMonitor::SuperMonitor(){ 13 } 14 SuperMonitor::SuperMonitor(int childnum){ 15 child_num = childnum; 16 } 17 SuperMonitor::~SuperMonitor(){ 18 } 19 20 void SuperMonitor::Run(superMonitorHndl f){ 21 int rc; 22 rc = f (0, (char **) 0); 23 } 24 25 bool SuperMonitor::isAbnormalExit(int pid, int status){ 26 bool bRestart = true; 27 if(WIFEXITED(status)) { 28 printf("child normal termination, exit pid = %d, status = %d\n", pid, WEXITSTATUS(status)); 29 bRestart = false; 30 }else if(WIFSIGNALED(status)){ 31 printf("abnormal termination, pid = %d, signal number = %d\n", pid, WTERMSIG(status)); 32 if(WTERMSIG(status) == SIGKILL) { 33 bRestart = false; 34 printf("has been killed by user ??, exit pid = %d, status = %d\n", pid, WEXITSTATUS(status)); 35 } 36 }else if(WIFSTOPPED(status)) 37 printf("child stopped, pid = %d, signal number = %d\n", pid, WSTOPSIG(status)); 38 else 39 printf("child other reason quit, pid = %d, signal number = %d\n", pid, WSTOPSIG(status)); 40 return bRestart; 41 } 42 43 int SuperMonitor::startChild(std::vector<pid_t> &pidArr,superMonitorHndl f){ 44 int pid = fork(); if(pid == 0) { 37 //TODO 36 Run(f); 35 } 34 else if(pid > 0) { 33 pidArr.push_back(pid); 32 ++run_child; 31 } 30 return pid; 29 } 28 27 void SuperMonitor::Initial(superMonitorHndl f){ 26 pid_t father_pid; 25 std::vector<pid_t> pidArr; 24 while(run_child < child_num){ 23 father_pid = startChild(pidArr,f); 22 if(father_pid == 0||father_pid ==-1) 21 break; 20 } 19 if(father_pid<0) 18 printf("error in fork!"); 17 else if(father_pid==0) 16 printf("I am the child process, my process ID is %d, father is %d\n",getpid(),getppid()); 15 else 14 printf("I am the parent process, my process ID is %d\n",getpid()); 13 12 sleep(3); 11 for(std::vector<pid_t>::iterator i = pidArr.begin();i!= pidArr.end();) { 10 //测试是否所有的进程都已启动 9 if(kill(*i, 0) != 0) { 8 --run_child; 7 i = pidArr.erase(i); 6 } else { 5 ++i; 4 //printf("%d process is started!\n",i); 3 } 2 } 1 int status = 0; time_t preTime = 0; 1 time_t curTime = 0; 2 3 while(run_child > 0) { 4 father_pid = wait(&status); 5 --run_child; 6 if(isAbnormalExit(father_pid, status)) { curTime = time(NULL); 13 if((curTime - preTime) > 2) { 12 father_pid = startChild(pidArr,f); 11 if(father_pid<0) 10 printf("error in fork!"); 9 else if(father_pid==0) 8 printf("I am the child process, my process ID is %d, father is %d\n",getpid(),getppid()); 7 else 6 printf("I am the parent process, my process ID is %d\n",getpid()); 5 } 4 preTime = curTime; 3 } 2 } 1 }