程序kill -9与kill -15的区别,以及回调函数的作用

Linux/unix下,中止一个Java进程有两种方式,一种是kill -9 pid,一种是kill -15 pill(默认)。

两种方式的区别是:

SIGNKILL(9) 的效果是立即杀死进程. 该信号不能被阻塞, 处理和忽略。
SIGNTERM(15) 的效果是正常退出进程,退出前可以被阻塞或回调处理
。并且它是Linux缺省的程序中断信号。

---》标准中断信号
在Linux信号机制中,存在多种进程中断信号(Linux信号列表)。其中比较典型的有 SIGNKILL(9) 和 SIGNTERM(15).


由此可见,SIGNTERM(15) 才是理论上标准的kill进程信号。
那使用 SIGNKILL(9) 又有什么错呢?

SIGNKILL(9) 带来的问题
看下面一段程序:

public class ShutdownHookTest {

 private static final void shutdownCallback() {
  System.out.println("Shutdown callback is invoked.");
 }

 public static void main(String[] args) throws InterruptedException {
  Runtime.getRuntime().addShutdownHook(new Thread() {

   @Override
   public void run() {
    shutdownCallback();
   }

  });
  Thread.sleep(10000);
 }

}
在上面这段程序中,我使用Runtime为当前java进程添加了一个ShutdownHook,它的作用是在java正常退出时,执行shutdownCallback()这个回调方法。
此时,如果你试验过在java进程未自动退出前,执行 kill -9 pid,即发送 SIGNKILL 信号,会发现这个回调接口是不会被执行的。这是SIGNKILL信号起的作用。

对于我这个简单的测试用例来说,不被执行也无大碍。但是,如果你的真实系统中有需要在java进程退出后,释放某些资源。
而这个释放动作,因为SIGNKILL被忽略了,那就可能造成一些问题。

所以,推荐大家使用标准的kill进程方式,即 kill -15 pid。

---》》此外,如果想在程序被kill之前执行某些操作,就可以用到这个例子中的Runtime.getRuntime().addShutdownHook函数了,它是一个回调函数,在被kill之前会执行这个函数里面的内容。

`timeSetEvent` 是一个Windows API函数,用于设置定时器事件。它的原型如下: ```c++ MMRESULT timeSetEvent( UINT uDelay, UINT uResolution, LPTIMECALLBACK lpTimeProc, DWORD_PTR dwUser, UINT fuEvent ); ``` 其中,`lpTimeProc` 参数是一个指向回调函数的指针,用于处理定时器事件。回调函数的原型如下: ```c++ void CALLBACK TimeProc( UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2 ); ``` 在回调函数中,`uTimerID` 参数是定时器的标识符,`uMsg` 参数是一个预留参数,通常为 `TIME_TICK`,`dwUser` 参数是 `timeSetEvent` 函数调用时传入的 `dwUser` 参数,`dw1` 和 `dw2` 参数是一些保留参数,通常为0。 下面是一个简单的例子,演示如何使用 `timeSetEvent` 函数和回调函数处理定时器事件: ```c++ #include <Windows.h> #include <iostream> void CALLBACK TimeProc(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2) { std::cout << "Timer triggered! Timer ID: " << uTimerID << std::endl; } int main() { /* 设置定时器事件,每隔 1 秒触发一次 */ MMRESULT res = timeSetEvent(1000, 0, TimeProc, 0, TIME_PERIODIC); if (res == 0) { std::cerr << "Failed to set timer event" << std::endl; return 1; } /* 等待定时器触发 */ std::cout << "Waiting for timer..." << std::endl; system("pause"); /* 取消定时器事件 */ res = timeKillEvent(res); if (res == 0) { std::cerr << "Failed to kill timer event" << std::endl; return 1; } std::cout << "Timer event cancelled" << std::endl; return 0; } ``` 这个例子中,我们设置了一个每隔1秒触发一次的定时器事件,并在回调函数 `TimeProc` 中输出一条消息。程序运行后,会输出 "Waiting for timer...",等待定时器事件的触发。当定时器事件被触发时,会输出 "Timer triggered! Timer ID: xxx",其中 xxx 是定时器的标识符。 当我们按下任意键后,程序会取消定时器事件,并输出 "Timer event cancelled"。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值