当前仓库属于暂停状态,部分功能使用受限,详情请查阅 仓库状态说明
86 Star 244 Fork 109

dfire / hera
暂停

 / 详情

任务取消只会杀死窗口进程,无法真正杀死子线程!

待办的
创建于  
2019-10-12 14:29
            CountDownLatch latch = new CountDownLatch(2);
            Thread inputThread = new StreamThread(process.getInputStream(), threadName, latch);
            Thread outputThread = new StreamThread(process.getErrorStream(), threadName, latch);
            inputThread.setUncaughtExceptionHandler(new HeraCaughtExceptionHandler());
            outputThread.setUncaughtExceptionHandler(new HeraCaughtExceptionHandler());
            inputThread.start();
            outputThread.start();
            try {
                exitCode = process.waitFor();
                latch.await();
            } catch (InterruptedException e) {
                exitCode = Constants.INTERRUPTED_EXIT_CODE;
                log(e);
            } finally {
                process = null;
            }
                      

上面这段是执行的方法,会在本地使用ProcessBuilder.start()方法创建一个进程,并且通过waitfor()阻塞当前线程,然后使用latch.await()再次阻塞当前线程。

再看取消任务的代码

//强制kill 进程
        if (process != null) {
            log("WARN Attempting to kill the process ");
            try {
                process.destroy();
                int pid = getProcessId();
                String st = "sudo sh -c \"cd; pstree " + pid + " -p | grep -o '([0-9]*)' | awk -F'[()]' '{print \\$2}' | xargs kill -9\"";
                String[] commands = {"sudo", "sh", "-c", st};
                ProcessBuilder processBuilder = new ProcessBuilder(commands);
                try {
                    process = processBuilder.start();
                    log("kill process tree success");
                } catch (Exception e) {
                    log(e);
                }
            } catch (Exception e) {
                log(e);
            } finally {
                process = null;
            }
        }

问题有两点:

  • process.destroy先调用了,那么下面的通过pstree等一系列shell命令杀死子进程的脚本就根本无法执行,因为process.destroy会立刻杀死在run方法中调起的进程!应该把destory方法后置!
  • String st = "sudo sh -c \"cd; pstree " + pid + " -p | grep -o '([0-9]*)' | awk -F'[()]' '{print \\$2}' | xargs kill -9\"";
    这段代码根本不可能执行成功,因为awk的命令在双引号里执行有转义的问题!改成下面这样就可以了String st = "sudo sh -c \"cd; pstree " + pid + " -p | grep -o '([0-9]*)' | sed s/'[()]'/''/g | xargs kill -9\"";

所以可以看出,由于无法杀死子进程,所以实际cancel方法只是把窗口进程,也就是run()中启动的process的进程杀死了,而真正的执行任务的线程并没有杀死,而latch.await()方法则会导致任务的执行线程一直等待,直到子任务执行完毕。这个问题出现在所有shell启动的脚本里。看似杀死了任务,实际任务在后台跑得很快乐

评论 (1)

蔡啸 创建了任务
蔡啸 修改了描述
蔡啸 修改了描述
蔡啸 修改了描述
蔡啸 修改了描述
展开全部操作日志

这个问题在老版本的宙斯也有,后来我们修复了

登录 后才可以发表评论

状态
负责人
里程碑
Pull Requests
关联的 Pull Requests 被合并后可能会关闭此 issue
分支
开始日期   -   截止日期
-
置顶选项
优先级
参与者(2)
Java
1
https://gitee.com/dfire/hera.git
git@gitee.com:dfire/hera.git
dfire
hera
hera

搜索帮助