最近,我正在尝试使用Runtime.getRuntime().exec(command)
进行Android子进程,发现我可以销毁NodeJS http服务器,但不能销毁Go http服务器。
对于node
和go
二进制文件,可以从Termux获得。
对于节点子进程,可以在Android的
Service
和p.waitFor()
中启动;时间到了,可以用p.destroy()
杀死它但是,对于go sub进程,它可以启动,但不能被
p.destroy()
甚至p. destroyForcibly()
杀死;在本文https://medium.com/honestbee-tw-engineer/gracefully-shutdown-in-go-http-server-5f5e6b83da5a中,它确保可以优雅地关闭go服务器,并且我尝试了它,但是p.destroy()
仍然无法正常工作。如果有人能给我一种杀死该过程的方法,我们将不胜感激。谢谢!
最佳答案
只是想出了一种破解方法;不优雅引导我找到更好的解决方案!
Log.d("AppDebug", p.javaClass.getName())
// from above log
// we can know Android use "java.lang.UNIXProcess" as implementation of java.lang.Process
// to make sure the sub process is killed eventually
if (p.isAlive()) {
val klass = p.javaClass
if (klass.getName().equals("java.lang.UNIXProcess")) {
Log.d("AppDebug", "force terminate sub process ..")
try {
val f = klass.getDeclaredField("pid");
f.setAccessible(true);
val pid = f.getInt(p);
// XXX: buggy here, if getInt throw an error, the filed is exposed!
f.setAccessible(false);
android.os.Process.killProcess(pid);
Log.d("AppDebug", "force terminating done.")
} catch (e: Exception) {
Log.d("AppDebug", "force terminating failed.")
}
} else {
Log.d("AppDebug", "force terminating not supported.")
}
}
对不起,我的误导。目前,我完全理解为什么在杀死进程之前/之后添加一些有关
ps -ef
的日志后,为什么不能杀死go服务器。实际上,我使用
go run main.go
启动服务器;但是,go run main.go
将编译代码并在tmp文件夹中生成一个二进制文件。然后它将产生一个子进程(执行二进制文件);当我执行p.destroy()
时,它只是杀死了go
进程,但子服务器进程仍然存在。正确的解决方案是,像上面的代码一样获得
pid
;并使用ps -o pid= --ppid=<pid>
获取子树并杀死所有进程进行清理。
关于android - 如何在Android上销毁golang子进程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64058005/