class Process {
public static final int SIGNAL_KILL = 9;
public static final void killProcess(int pid) {
sendSignal(pid, SIGNAL_KILL);
}
public static final native void sendSignal(int pid, int signal);
}
// android_util_Process.cpp
void android_os_Process_sendSignal(JNIEnv* env, jobject clazz, jint pid, jint sig)
{
if (pid > 0) {
ALOGI("Sending signal. PID: %" PRId32 " SIG: %" PRId32, pid, sig);
kill(pid, sig);
}
}
最终执行系统调用 kill
kill -s sig pid
kill(pid, sig)
// 自定义信号处理程序
// handler 可以是:SIG_IGN 忽略此信号,SIG_DFL 设置默认的信号处理程序,函数地址
// SIGKILL 和 SIGSTOP 是不可以忽略和自定义的
signal(signum, handler)
信号 是一个古老的、异步的 IPC 机制,一个进程可以给另一个进程发送信号(kill),收到信号(SIGxxx)的进程会暂停并进入相应的信号处理程序(Signal Handlers),信号处理程序是可以配置的
| Singal | Number | Default Action | Desc |
|---|---|---|---|
| SIGKILL | 9 | Terminate (core dump) | Kill (cannot be caught or ignored) |
| SIGSEGV | 11 | Terminate (core dump) | Invalid memory reference |
| SIGINT | 2 | Terminate | Terminal interrupt signal,常见于在控制台由 Ctrl-C 触发 |
| SIGSTOP | Stop | Stop executing (cannot be caught or ignored),常见于在控制台由 Ctrl-Z 触发 |
class System {
public static void exit(int status) {
Runtime.getRuntime().exit(status);
}
}
class Runtime {
public void exit(int status) {
// Make sure we don't try this several times
synchronized(this) {
if (!shuttingDown) {
shuttingDown = true;
Thread[] hooks;
synchronized (shutdownHooks) {
// create a copy of the hooks
hooks = new Thread[shutdownHooks.size()];
shutdownHooks.toArray(hooks);
}
// Start all shutdown hooks concurrently
for (Thread hook : hooks) {
hook.start();
}
// Wait for all shutdown hooks to finish
for (Thread hook : hooks) {
try {
hook.join();
} catch (InterruptedException ex) {
// Ignore, since we are at VM shutdown.
}
}
// Ensure finalization on exit, if requested
if (finalizeOnExit) {
runFinalization();
}
// Get out of here finally...
nativeExit(status);
}
}
}
}
退出 VM 回到 native 代码,能够保证 shutdown hook 执行完,native 代码甚至可以重新进入 VM 或者做其他的事,进程没有被杀死,其他 native thread 也在正常运行
通过 Runtime.addShutdownHook(Thread) 添加的任务确实可以在 System.exit(status) 时被执行,但就像 Uncaught Exception Handling 里描述的那样,主线程退出 VM 后虽然没有结束(在等待 shutdown hook 执行完毕),但它也不再消费分发过来的 input 事件导致出现 ANR 对话框,然后被用户杀死 app process,当然在进程被杀死前 shutdown hook 也有跟 uncaught exception handler 差不多长的生存时间