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

来源:互联网 发布:java红包分配算法代码 编辑:程序博客网 时间:2024/05/17 09:26

原创文章,欢迎转载。转载请注明出处:http://blog.csdn.net/jmppok/article/details/16845627


为什么要监听程序退出事件就不用多说了,有各种各样的需求吧。主要是用于后台程序,比如要在程序退出的时候释放资源,关闭连接等等。

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


1.Java监听程序退出事件

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

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

我实现的一个例子。

public class RTMServer extends Thread{private MessageServer msg_server = null;private ThriftServer thrift_server = null;public RTMServer(){this.setName("RTMServer");}public void start_server(){// 添加程序关闭监听线程Runtime.getRuntime().addShutdownHook(this);msg_server = new MessageServer();msg_server.start();thrift_server = new ThriftServer("ThriftServer");thrift_server.start();//该方法会阻塞}/* * 继承Thread * 用于在程序关闭时释放资源。 * @see java.lang.Thread#run() */public void run(){if(thrift_server != null){thrift_server.close();}if(msg_server != null){msg_server.close();}VMManager.instance.destroyPool();}public static void main(String[] args) {// 初始化日志LogUtil.init();RTMServer server = new RTMServer();server.start_server();}}
是不是很简单呢?


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

下面是我的一个封装。

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <signal.h>class SignalHandler{public:SignalHandler();public:// 程序退出时的函数操作static void handle_signal(int n,struct siginfo *siginfo,void *myact);};SignalHandler * g_exit_handler = NULL;SignalHandler::SignalHandler(){/** install signal use sigaction **/struct sigaction act;sigemptyset(&act.sa_mask);   /** 清空阻塞信号 **/act.sa_flags=SA_SIGINFO;     /** 设置SA_SIGINFO 表示传递附加信息到触发函数 **/act.sa_sigaction=handle_signal;if(sigaction(SIGHUP,&act,NULL) < 0      // 1|| sigaction(SIGINT,&act,NULL) < 0  // 2|| sigaction(SIGQUIT,&act,NULL) < 0 // 3//|| sigaction(SIGKILL,&act,NULL) < 0 // 9|| sigaction(SIGTERM,&act,NULL) < 0 // 15){LOG4CPP(LOG_LEVEL_ERROR,"install signal handler error");}}void SignalHandler::handle_signal(int n,struct siginfo *siginfo,void *myact){LOG4CPP(LOG_LEVEL_WARN,"SIGNAL received: signo=%d errno=%d code=%d ",siginfo->si_signo,siginfo->si_errno,siginfo->si_code);if(siginfo->si_signo == 1 || siginfo->si_signo == 2|| siginfo->si_signo == 3|| siginfo->si_signo == 9|| siginfo->si_signo == 15){//程序退出,进行退出处理操作exit(0);}}         

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

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

windows下捕获程序退出事件主要通过
 SetConsoleCtrlHandler( (PHANDLER_ROUTINE) ctrlhandler, true )

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


具体的实现如下:

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <signal.h>bool ctrlhandler( DWORD fdwctrltype );if( SetConsoleCtrlHandler( (PHANDLER_ROUTINE) ctrlhandler, true ) )    {    }else{LOG4CPP(LOG_LEVEL_ERROR,"install signal handler error");}bool ctrlhandler( DWORD fdwctrltype ){switch( fdwctrltype ){// handle the ctrl-c signal.case CTRL_C_EVENT://printf( "ctrl-c event\n\n" );//return( true );// ctrl-close: confirm that the user wants to exit.case CTRL_CLOSE_EVENT://printf( "ctrl-close event\n\n" );//return( true );// pass other signals to the next handler.case CTRL_BREAK_EVENT://printf( "ctrl-break event\n\n" );//return false;case CTRL_LOGOFF_EVENT://printf( "ctrl-logoff event\n\n" );//return false;case CTRL_SHUTDOWN_EVENT://printf( "ctrl-shutdown event\n\n" );//return false;//清理return true;default:return false;}} 

4.总结

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


原创粉丝点击