golang exec.Command вызывает много несуществующих процессов
Я использую golang для вызова pppd, а затем убью его через некоторое время. Однако я получил много несуществующих процессов таким образом.
Вот так я запускаю pppd
exec.Command("sh", "-c", "pppd call vpn").CombinedOutput()
Вот как я это убью.
exec.Command("sh", "-c", "pkill pppd").CombinedOutput()
Тогда я получил много этого
root 31541 23536 0 10:54 ? 00:00:00 [pppd] <defunct>
root 31929 23356 0 10:55 ? 00:00:00 [pptpgw] <defunct>
root 31933 23356 0 10:55 ? 00:00:00 [pptpcm] <defunct>
root 31940 23356 0 10:55 ? 00:00:00 [pppd] <defunct>
root 31993 23536 0 10:55 ? 00:00:00 [pptpgw] <defunct>
root 31997 23536 0 10:55 ? 00:00:00 [pptpcm] <defunct>
root 31998 23536 0 10:55 ? 00:00:00 [pppd] <defunct>
root 32012 23356 0 10:55 ? 00:00:00 [pptpgw] <defunct>
root 32016 23356 0 10:55 ? 00:00:00 [pptpcm] <defunct>
root 32017 23356 0 10:56 ? 00:00:00 [pppd] <defunct>
root 32070 23536 0 10:56 ? 00:00:00 [pptpgw] <defunct>
root 32074 23536 0 10:56 ? 00:00:00 [pptpcm] <defunct>
root 32075 23536 0 10:56 ? 00:00:00 [pppd] <defunct>
root 32083 23356 0 10:56 ? 00:00:00 [pptpgw] <defunct>
root 32087 23356 0 10:56 ? 00:00:00 [pptpcm] <defunct>
root 32089 23356 0 10:56 ? 00:00:00 [pppd] <defunct>
root 32131 23536 0 10:57 ? 00:00:00 [pptpgw] <defunct>
root 32135 23536 0 10:57 ? 00:00:00 [pptpcm] <defunct>
root 32148 23536 0 10:57 ? 00:00:00 [pppd] <defunct>
root 32160 23356 0 10:57 ? 00:00:00 [pptpgw] <defunct>
root 32164 23356 0 10:57 ? 00:00:00 [pptpcm] <defunct>
root 32165 23356 0 10:57 ? 00:00:00 [pppd] <defunct>
root 32177 23536 0 10:57 ? 00:00:00 [pptpgw] <defunct>
root 32181 23536 0 10:57 ? 00:00:00 [pptpcm] <defunct>
Как я могу избежать несуществующих процессов.
3 ответа
Эти "зомби" процессы создаются, когда процесс завершен, но родитель не прочитал их статус выхода через wait
системный вызов.
Я думаю, все, что вам нужно сделать, это позвонить (*Cmd).Wait()
на каждой структуре команд, которую вы создаете. Очевидно, это будет не так просто, как вам хотелось бы, так как вы, вероятно, не хотите звонить Wait
по первой команде до тех пор, пока вторая команда не будет завершена.
РЕДАКТИРОВАТЬ: Как указано в комментариях, (*Cmd).CombinedOutput()
звонки (*Cmd).Run()
, который вызывает (*Cmd).Wait()
... Так что вышесказанное неверно. Реальный ответ в этом случае заключается в том, что по какой-то причине sh
не убирает, и поэтому решение состоит в том, чтобы вырезать среднего человека и сделать звонок следующим образом:
exec.Command("pppd", "call", "vpn").CombinedOutput()
Это научит меня читать документы немного ближе в следующий раз...
Более простой способ отменить вашу команду - использовать exec.CommandContext. например
ctx, cancel := context.WithCancel(context.Background())
exec.CommandContext(ctx, "pppd", "call", "vpn").CombinedOutput()
// in some other goroutine...
cancel()
Может быть, это решит вашу проблему с зомби?
запустить подпроцесс в новом потоке
go exec.Command("sh", "-c", "pppd call vpn").CombinedOutput()
убить подпроцесс
exec.Command("pkill", "pppd").CombinedOutput().CombinedOutput()