监听获取程序退出事件(Linux、Windows、Java、C++)
2013-11-20 17:50
495 查看
原创文章,欢迎转载。转载请注明出处:/article/1944256.html
为什么要监听程序退出事件就不用多说了,有各种各样的需求吧。主要是用于后台程序,比如要在程序退出的时候释放资源,关闭连接等等。
下面针对Java、C++在Windows、Linux下的处理分别进行介绍.
通过Runtime.getRuntime().addShutdownHook(Thread t);添加一个监控线程,在该程序退出时会调用Thread的run方法。不得不说Java真的很方便。
我实现的一个例子。
linux退出信号主要有SIGHUP,SIGINT,SIGQUIT,SIGTERM,即1,2,3,15
下面是我的一个封装。
在主程序启动时创建Handler(),则程序退出时会捕获到相应的信号
其中ctrHandler是一个回调函数,在退出时会触发该函数。
具体的实现如下:
为什么要监听程序退出事件就不用多说了,有各种各样的需求吧。主要是用于后台程序,比如要在程序退出的时候释放资源,关闭连接等等。
下面针对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的监听器不同而已。相关文章推荐
- 监听获取程序退出事件(Linux、Windows、Java、C++)
- windows和linux下执行java程序+获取本机IP
- java工具类,在Windows,Linux系统获取电脑的MAC地址、本地IP、电脑名
- linux和windows下如何知道端口是被那个程序监听占用?
- java程序判断操作系统是Windows还是Linux
- 用纯Java代码根据IP获取windows和linux的MAC物理地址
- windows和linux下获取当前程序路径以及cpu数
- Windows/Linux环境下使用Java VisualVM进行Java程序性能分析与监视
- Java获取主机IP地址,自动区分Windows和Linux
- Java 获取Windows 和 Linux 下 IP 机制
- java通过jni方式获取硬盘序列号(windows,linux)
- 在JAVA与JSP中要调用一个LINUX上的脚本程序,或WINDOWS上的脚本程序
- 【Linux菜鸟成长记(十)】解决Windows的Java程序在ubuntu Eclipse下显示中文乱码
- java支持跨平台获取cpuid、主板id、硬盘id、mac地址 (兼容windows、Linux)
- java支持跨平台获取cpuid、主板id、硬盘id、mac地址 (兼容windows、Linux)
- 如何能够使java程序中的文件路径在windows和linux正确显示
- 监听所有的Java程序的事件
- 利用C/C++编写程序以获取文件夹内所有子文件名,windows和Linux两个版本都有
- Android 监听back事件,点击两次退出程序
- Java中获取windows、Linux和windows7的MAC地址