监听获取程序退出事件(Linux、Windows、Java、C++)

监听程序退出事件,主要是用于程序的优雅退出。

下面针对Java、C++在Windows、Linux下的处理分别进行介绍.

1.Java监听程序退出事件

Java本身是跨平台的,不必关系Windows还是Linux。具体做法如下:

通过Runtime.getRuntime().addShutdownHook(Thread t);添加一个监控线程,在该程序退出时会调用Thread的run方法。不得不说Java真的很方便。

我实现的一个例子。

  1. public class RTMServer extends Thread{
  2. private MessageServer msg_server = null;
  3. private ThriftServer thrift_server = null;
  4. public RTMServer()
  5. {
  6. this.setName("RTMServer");
  7. }
  8. public void start_server()
  9. {
  10. // 添加程序关闭监听线程
  11. Runtime.getRuntime().addShutdownHook(this);
  12. msg_server = new MessageServer();
  13. msg_server.start();
  14. thrift_server = new ThriftServer("ThriftServer");
  15. thrift_server.start();//该方法会阻塞
  16. }
  17. /*
  18. * 继承Thread
  19. * 用于在程序关闭时释放资源。
  20. * @see java.lang.Thread#run()
  21. */
  22. public void run()
  23. {
  24. if(thrift_server != null)
  25. {
  26. thrift_server.close();
  27. }
  28. if(msg_server != null)
  29. {
  30. msg_server.close();
  31. }
  32. VMManager.instance.destroyPool();
  33. }
  34. public static void main(String[] args) {
  35. // 初始化日志
  36. LogUtil.init();
  37. RTMServer server = new RTMServer();
  38. server.start_server();
  39. }
  40. }

是不是很简单呢?

2.C++ Linux下监听程序退出事件

主要通过Linux的signal进行判断,程序启动时通过

sigaction(SIGHUP,&act,NULL)

设置要捕获的信号,则发生相应的信号时就会被

handle_signal(int n,struct siginfo *siginfo,void *myact)

捕获。

linux退出信号主要有SIGHUP,SIGINT,SIGQUIT,SIGTERM,即1,2,3,15

下面是我的一个封装。

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <sys/types.h>
  5. #include <sys/stat.h>
  6. #include <fcntl.h>
  7. #include <unistd.h>
  8. #include <signal.h>
  9. class SignalHandler{
  10. public:
  11. SignalHandler();
  12. public:
  13. // 程序退出时的函数操作
  14. static void handle_signal(int n,struct siginfo *siginfo,void *myact);
  15. };
  16. SignalHandler * g_exit_handler = NULL;
  17. SignalHandler::SignalHandler()
  18. {
  19. /** install signal use sigaction **/
  20. struct sigaction act;
  21. sigemptyset(&act.sa_mask); /** 清空阻塞信号 **/
  22. act.sa_flags=SA_SIGINFO; /** 设置SA_SIGINFO 表示传递附加信息到触发函数 **/
  23. act.sa_sigaction=handle_signal;
  24. if(sigaction(SIGHUP,&act,NULL) < 0 // 1
  25. || sigaction(SIGINT,&act,NULL) < 0 // 2
  26. || sigaction(SIGQUIT,&act,NULL) < 0 // 3
  27. //|| sigaction(SIGKILL,&act,NULL) < 0 // 9
  28. || sigaction(SIGTERM,&act,NULL) < 0 // 15
  29. )
  30. {
  31. LOG4CPP(LOG_LEVEL_ERROR,"install signal handler error");
  32. }
  33. }
  34. void SignalHandler::handle_signal(int n,struct siginfo *siginfo,void *myact)
  35. {
  36. LOG4CPP(LOG_LEVEL_WARN,"SIGNAL received: signo=%d errno=%d code=%d ",siginfo->si_signo,siginfo->si_errno,siginfo->si_code);
  37. if(siginfo->si_signo == 1
  38. || siginfo->si_signo == 2
  39. || siginfo->si_signo == 3
  40. || siginfo->si_signo == 9
  41. || siginfo->si_signo == 15)
  42. {
  43. //程序退出,进行退出处理操作
  44. exit(0);
  45. }
  46. }


在主程序启动时创建Handler(),则程序退出时会捕获到相应的信号

g_exit_handler = new SignalHandler();

3.C++ Windows下监听程序退出事件

windows下捕获程序退出事件主要通过

 SetConsoleCtrlHandler( (PHANDLER_ROUTINE) ctrlhandler, true )

其中ctrHandler是一个回调函数,在退出时会触发该函数。

具体的实现如下:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <sys/types.h>
  5. #include <sys/stat.h>
  6. #include <fcntl.h>
  7. #include <unistd.h>
  8. #include <signal.h>
  9. bool ctrlhandler( DWORD fdwctrltype );
  10. if( SetConsoleCtrlHandler( (PHANDLER_ROUTINE) ctrlhandler, true ) )
  11. {
  12. }
  13. else
  14. {
  15. LOG4CPP(LOG_LEVEL_ERROR,"install signal handler error");
  16. }
  17. bool ctrlhandler( DWORD fdwctrltype )
  18. {
  19. switch( fdwctrltype )
  20. {
  21. // handle the ctrl-c signal.
  22. case CTRL_C_EVENT:
  23. //printf( "ctrl-c event\n\n" );
  24. //return( true );
  25. // ctrl-close: confirm that the user wants to exit.
  26. case CTRL_CLOSE_EVENT:
  27. //printf( "ctrl-close event\n\n" );
  28. //return( true );
  29. // pass other signals to the next handler.
  30. case CTRL_BREAK_EVENT:
  31. //printf( "ctrl-break event\n\n" );
  32. //return false;
  33. case CTRL_LOGOFF_EVENT:
  34. //printf( "ctrl-logoff event\n\n" );
  35. //return false;
  36. case CTRL_SHUTDOWN_EVENT:
  37. //printf( "ctrl-shutdown event\n\n" );
  38. //return false;
  39. //清理
  40. return true;
  41. default:
  42. return false;
  43. }
  44. }


4.总结

其实原理都差不多,就是在程序启动时需要设置一个“程序退出监听器”,只不过在windows、linux下C++、Java的监听器不同而已。


(0)

相关推荐