監聽獲取程序退出事件(Linux、Windows、Java、C++)

原創文章,歡迎轉載。轉載請註明出處:http://blog.csdn.net/jmppok/article/details/16845627
java


爲何要監聽程序退出事件就不用多說了,有各類各樣的需求吧。主要是用於後臺程序,好比要在程序退出的時候釋放資源,關閉鏈接等等。linux

下面針對Java、C++在Windows、Linux下的處理分別進行介紹.windows


1.Java監聽程序退出事件

Java自己是跨平臺的,沒必要關係Windows仍是Linux。具體作法以下:函數

經過Runtime.getRuntime().addShutdownHook(Thread t);添加一個監控線程,在該程序退出時會調用Thread的run方法。不得不說Java真的很方便。
this

我實現的一個例子。spa

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進行判斷,程序啓動時經過.net

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是一個回調函數,在退出時會觸發該函數。
code


具體的實現以下:

#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的監聽器不一樣而已。

相關文章
相關標籤/搜索