Почему необязательный аргумент возвращается из parent()
пустым при вызове с использованием echo hello
?
Поскольку дочерний процесс очень короткий, и когда вы получаете команду, которая запрашивает родительский процесс, дочерний процессболее не существует.Поэтому операционная система больше не может запрашивать об этом процессе.
Почему этого не происходит при вызове getHandle()
или pid()
?
Обратите внимание, что ни один из них не является Optional
.Это означает, что API гарантирует, что значения будут возвращены в них.Фактически реализация такова, что дескриптор создается, включая идентификатор процесса, как только процесс создается операционной системой и возвращается в pb.start()
.Таким образом, у вас есть дескриптор, и у вас есть идентификатор процесса - но процесс с этим идентификатором не гарантированно останется живым, когда вы его используете.
Документация специально говорит вам не делать предположенийо жизнеспособности или идентичности базового процесса.
В настоящее время вызов parent()
осуществляется путем запроса операционной системы с использованием дочернего pid.Таким образом, родительский элемент не является частью записи процесса при создании процесса, и к тому времени, когда вы вызываете его, он может быть недоступен.
Как избежать этой ситуации
При каждом использованииOptional
, не используйте get
.Особенно не без проверки, присутствует ли он заранее или нет (а использование isPresent
... get
считается «антипаттерном»).Когда вы видите, что API дает вам Optional
, подумайте, что вы хотите сделать, если этот Optional
окажется пустым.Не делайте предположений, которые не обоснованы документацией.
В этом случае вы можете отобразить сообщение по умолчанию, если родитель не найден.Например:
System.out.println("parent of child process: "
+ p.toHandle().parent().map(ProcessHandle::pid)
.map(Object::toString)
.orElse("not available"));
Или вы можете использовать pid текущего процесса в качестве значения по умолчанию или все, что вы можете придумать.Или вы можете выдвинуть исключение другого рода, если личность родителя абсолютно необходима для вашей работы.Информацию о различных способах элегантной работы с ним см. В документации по Optional
.
Нет способа расширить базовый процесс - вы можете использовать сценарий оболочки, который спит после выполнения переданной вами команды, ноЯ считаю, что это решение в лучшем случае неуклюже.