问题描述:一个父进程监控多个子进程,子进程执行函数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 }