Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clean way to exec a new sub process and get its PID to be able to kill it? #33

Open
frankbenoit opened this issue Nov 26, 2014 · 0 comments

Comments

@frankbenoit
Copy link

Hi

First, I am not sure if this is the right place for this issue. Is there a forum for such a question?

I want to create a new sub process with

Runtime.getRuntime().exec( ...

Then later I want to be able to kill that process and its childs.
The java Process.destroyForcibly() did not work, but JavaSysMon.killProcessTree() does.
So I need the PID of the newly created process.

My current approach is to do it this way:

  1. Create a lock around the start procedure
  2. get list of all child PIDs
  3. create the sub process
  4. get list of all child PIDs
  5. find the PID that did not existed before

Here is my code:

// locking
synchronized(ExternCmd.class){
    int[] childsBefore = getChildPids();
    Process process = Runtime.getRuntime().exec( cmdLine.toArray( new String[ cmdLine.size() ]), null, workdir );
    int[] childsAfter = getChildPids();
    int subPid = -1;
    for( int i = 0; i < childsAfter.length; i++ ){
        if( Arrays.binarySearch( childsBefore, childsAfter[i] ) < 0 ){
            Assert.isTrue( subPid < 0, "A PID was already found. The result is ambiguous." );
            subPid = childsAfter[i];
            Assert.isTrue( subPid > 0 );
        }
    }
    Assert.isTrue( subPid > 0, "The PID was not found" );
} // end of locking, now use the subPid

private int[] getChildPids(){
    JavaSysMon sysMon = new com.jezhumble.javasysmon.JavaSysMon();
    List<?> childs = sysMon.processTree().find(sysMon.currentPid()).children();
    int[] res = new int[childs.size()];
    int idx = 0;
    for( Object c : childs ){
        res[idx] = ((OsProcess)c).processInfo().getPid();
    }
    Arrays.sort( res );
    return res;
}

But this seems to have drawbacks and be fragile. Isn't it?

  • It would be good if starting synchronized is not needed
  • If somewhere in the same application another process is started independantly this would result in a ambiguous PID.

My question:

  1. Is there a better way to it?
  2. If not, could JavaSysMon implement support for this use case?

thx
Frank

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant