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()
Другие вопросы по тегам