【问题标题】:ProcessHandle returns ambiguous resultsProcessHandle 返回模棱两可的结果
【发布时间】:2021-10-06 15:40:13
【问题描述】:

我有两个 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 的不同结果,其中第一个实现总是返回 true,而第二个实现总是返回 false

使用 shell 命令ps -ef | grep &lt;pid&gt; 检查一些“误报”表明第一次实现似乎是错误的,操作系统也不知道这些进程。 假设第二个实现总是正确的,但似乎效率很低。

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

【问题讨论】:

    标签: java linux pid isalive processhandle


    【解决方案1】:

    查看ProcessHandleImpl.isAlive()(Java 11 版本)的实现,如果本机方法isAlive0(pid) 返回 0,则此方法可能会返回 true - “如果无法确定开始时间”,它会执行此操作.同样的本机方法也用于确定是否返回一个空的可选项(返回 -1)或不返回(返回 0 或实际开始时间)。另一方面,ProcessHandle.allProcesses() 获取 pid 0 的所有子代,然后调用 getProcessPids0(...)(另一种本地方法)返回 pid 和开始时间。

    因此,您使用的 JVM 的本机代码似乎有所不同 - 或者您的操作系统中的本机代码有所不同(取决于本机代码在做什么)。

    要“修复”您的第一个 sn-p,您可以使用 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);
        }      
     }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-19
      • 2016-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多