#android #go #subprocess #kill-process
#Android #Вперед #подпроцесс #убить процесс
Вопрос:
Недавно я попробовал вспомогательный процесс Android Runtime.getRuntime().exec(command)
и обнаружил, что могу уничтожить http-сервер NodeJS, но не могу уничтожить http-сервер Go.
для node
и go
двоичных файлов он доступен в Termux;
- http-сервер узла: https://github.com/stallpool/halfbase/tree/master/nodejs/tinyserver/index.js
- перейти на http-сервер: https://github.com/stallpool/halfbase/blob/master/golang/tinyserver/main.go
Для вспомогательного процесса узла его можно запустить на Android Service
и p.waitFor()
; когда придет время, он может быть убит p.destroy()
Однако для вспомогательного процесса go он может быть запущен, но не может быть остановлен p.destroy()
even p. destroyForcibly()
; в этой статье https://medium.com/honestbee-tw-engineer/gracefully-shutdown-in-go-http-server-5f5e6b83da5a , это гарантирует, что сервер go может быть закрыт корректно, и я попробовал это, но p.destroy()
все равно не работает.
Я признателен, если кто-нибудь может осветить мне способ убить процесс. спасибо!
Ответ №1:
просто придумал способ взлома; не элегантно; направьте меня к лучшему решению, если таковое имеется!
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.")
}
}
извините за мое заблуждение. в настоящее время я полностью понимаю, почему мой сервер go не может быть уничтожен после того, как я добавлю журнал ps -ef
до / после завершения процесса.
на самом деле я использую go run main.go
для запуска сервера; однако go run main.go
скомпилирую код и сгенерирую двоичный файл в папке tmp; затем он создаст дочерний процесс (выполнит двоичный файл); когда я это сделал p.destroy()
, он просто убил go
процесс, но процесс дочернего сервера остался там.
правильное решение — получить pid
приведенный выше код; и использовать ps -o pid= --ppid=<pid>
, чтобы получить дочернее дерево и уничтожить все процессы для очистки.