`
superisaac
  • 浏览: 62907 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

unix 下程序monitor的简单实现

阅读更多
用c/c++编的程序, 有时会因为某种错误而终止, 如果我们希望终止了也能及时重启. 那么可以考虑monitor/worker模式.

父进程作为monitor, 子进程作真实的工作, 每次子进程终止的时候, monitor通过wait得知, 然后重新fork一个工作子进程, 当monitor被信号杀死的时候, 则杀掉子进程, 唯一的问题是当monitor 被SIGKILL杀死的时候, 无法添加信号回调函数, 也就无法杀掉子进程.

/**
 * Monitor to respawn a working process 
 */
bool terminating = false;
pid_t child_pid = 0;

// This function will be called on calling exit() or return of main()
static void on_monitor_exit()
{
  if(child_pid != 0) {
    terminating = true;
    kill(child_pid, SIGINT);
  }
}

static void stop_monitor(int v) {
  if(child_pid != 0) {
    // Send sigint to child worker
    terminating = true;
    kill(child_pid, SIGINT);
  } else {
    exit(128+v); // 128 + signal is the default exit status on signal
  }
}

static void reload(int v) {
  // doesnot terminate monitor, restart child instead
  if(child_pid != 0) {
    kill(child_pid, SIGINT);
  } else {
    exit(128+v);  // 128 + signal is the default exit status on signal
  }
}

int main(int argc, char ** argv) {
  static bool monitor_initialized = false;
  while(!terminating) {
    child_pid = fork();
    if(child_pid == 0) {
      // In child process, do the actual work
      return child_run(argc, argv);
    } else {
      if(!monitor_initialized) {
	signal(SIGINT, stop_monitor);
	signal(SIGTERM, stop_monitor);
	signal(SIGHUP, reload);
	atexit(on_monitor_exit);
	monitor_initialized = true;
      }

      // Wait for child return
      int child_status;
      pid_t pid = wait(&child_status);
      if(pid != child_pid) {
	break;
      }
    }
  }
  // Monitor stops
}

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics