killProcess 和 exit 的区别
Process.killProcess(pid)
最终执行系统调用 kill
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);
}
}
signal(信号)
信号 是一个古老的、异步的 IPC 机制,一个进程可以给另一个进程发送信号(kill
),收到信号(SIGxxx
)的进程会暂停并进入相应的信号处理程序(Signal Handlers
),信号处理程序是可以配置的
kill -s sig pid
kill(pid, sig)
// 自定义信号处理程序
// handler 可以是:SIG_IGN 忽略此信号,SIG_DFL 设置默认的信号处理程序,函数地址
// SIGKILL 和 SIGSTOP 是不可以忽略和自定义的
signal(signum, handler)
常见的信号
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 触发 |
System.exit(status)
退出 VM 回到 native 代码,能够保证 shutdown hook 执行完,native 代码甚至可以重新进入 VM 或者做其他的事,进程没有被杀死,其他 native thread 也在正常运行
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);
}
}
}
}
shutdown hook
通过 Runtime.addShutdownHook(Thread)
添加的任务确实可以在 System.exit(status)
时被执行,但就像 Uncaught Exception Handling 里描述的那样,主线程退出 VM 后虽然没有结束(在等待 shutdown hook 执行完毕),但它也不再消费分发过来的 input 事件导致出现 ANR 对话框,然后被用户杀死 app process,当然在进程被杀死前 shutdown hook 也有跟 uncaught exception handler 差不多长的生存时间