ProcessHandle returns 不明确的结果

ProcessHandle returns ambiguous results

我有两个 Java 11 种方法来检查给定 PID 的进程是否 运行:

  public static final boolean isProcessRunning( final long pid ) {
    Optional< ProcessHandle > optionalProcess = ProcessHandle.of( pid );
    return optionalProcess.isPresent() && optionalProcess.get().isAlive();
  }

  public static boolean isProcessRunning2( final long pid ) {
    return ProcessHandle.allProcesses()
        .filter( p -> p.pid() == pid )
        .anyMatch( p -> p.isAlive() );
  }

在 Linux 客户端上检查多个 PID 时,我有时会得到某些 PID 的不同结果,其中第一个实现总是 returns true 而第二个总是 false.

用shell命令ps -ef | grep <pid>检查一些“误报”表明第一个实现似乎是错误的,OS也不知道这些过程。 假设第二种实现总是正确的,但似乎效率很低。

第一个实现有什么问题,我该如何解决?

另一方面,查看 ProcessHandleImpl.isAlive() (Java 11 version) it seems that this method might return true if the native method isAlive0(pid) returns 0 - which it does "if the start time cannot be determined". The same native method is also used to determine whether to return an empty optional (returns -1) or not (returns 0 or actual start time). ProcessHandle.allProcesses() 的实现获取 pid 0 的所有子级,然后调用 getProcessPids0(...)(另一种本机方法)到 return pid 并开始次。

所以这似乎是您正在使用的 JVM 的本机代码的差异 - 或者您的 OS 中的一个(取决于本机代码在做什么)。

要“修复”您的第一个片段,您可以使用 info().startInstant().isPresent():

消除“0”开始时间
public static final boolean isProcessRunning( final long pid, final boolean excludeUnsure ) {
    Optional< ProcessHandle > optionalProcess = ProcessHandle.of( pid );
    
    if( excludeUnsure ) {
        return optionalProcess.map(ph -> ph.info())
                .flatMap(info -> info.startInstant())
                .isPresent();
    } else {
        return optionalProcess.map(ph -> ph.isAlive()).orElse(Boolean.FALSE);
    }      
 }