当前位置:  开发笔记 > 编程语言 > 正文

如何让父进程退出子进程?

如何解决《如何让父进程退出子进程?》经验,为你挑选了4个好方法。

我正在使用ProcessBuilder启动子进程,并且如果父进程执行,则需要子进程退出.在正常情况下,我的代码正在正确地阻止孩子.但是,如果我导致操作系统杀死父级,则子级将继续运行.

有没有办法将子进程"绑定"到父进程,这样当父进程被杀时它会退出?


类似的问题:

父母退出后如何使子进程死亡?

使用fork()创建的子进程是否会在父级被杀死时自动终止?

Greg Case.. 37

虽然您无法防止硬中止(例如Unix上的SIGKILL),但您可以防止导致父进程关闭的其他信号(例如SIGINT)并清理您的子进程.您可以通过使用关闭钩子来实现此目的:请参阅运行时#addShutdownHook,以及此处的相关SO问题.

您的代码可能如下所示:

String[] command;
final Process childProcess = new ProcessBuilder(command).start();

Thread closeChildThread = new Thread() {
    public void run() {
        childProcess.destroy();
    }
};

Runtime.getRuntime().addShutdownHook(closeChildThread); 


sblundy.. 20

子进程与其父进程之间没有关系.他们可能知道彼此的进程ID,但它们之间没有硬连接.你在谈论一个孤儿过程.这是操作系统级别的问题.意味着任何解决方案都可能取决于平

关于我唯一能想到的是让孩子定期检查其父母身份,如果父母关闭则退出.我不认为这会是那么可靠.



1> Greg Case..:

虽然您无法防止硬中止(例如Unix上的SIGKILL),但您可以防止导致父进程关闭的其他信号(例如SIGINT)并清理您的子进程.您可以通过使用关闭钩子来实现此目的:请参阅运行时#addShutdownHook,以及此处的相关SO问题.

您的代码可能如下所示:

String[] command;
final Process childProcess = new ProcessBuilder(command).start();

Thread closeChildThread = new Thread() {
    public void run() {
        childProcess.destroy();
    }
};

Runtime.getRuntime().addShutdownHook(closeChildThread); 



2> sblundy..:

子进程与其父进程之间没有关系.他们可能知道彼此的进程ID,但它们之间没有硬连接.你在谈论一个孤儿过程.这是操作系统级别的问题.意味着任何解决方案都可能取决于平

关于我唯一能想到的是让孩子定期检查其父母身份,如果父母关闭则退出.我不认为这会是那么可靠.


如果您正在轮询以查看子项的PPID是否为1,则定期检查父项的状态是可靠的,因为孤立的进程获得init进程的PPID.(PID = 1)
我刚刚通过一个简单的改进实现了这个"父状态检查" - 我只是将原始的parent_pid传递给了孩子,他们只是检查父pid是否保持不变.因此无论init/systemd/pid数值如何,它都应该工作.

3> 小智..:

您只需在子进程中启动从System.in读取的线程即可.如果你不是写你孩子的标准书,那么其他人都不会这样做,并且该主题将"永远"阻止.但是如果父进程被杀死或者死亡,你将获得EOF(或异常).所以你也可以关闭孩子.(子进程以java.lang.ProcessBuilder开头)



4> 小智..:

提供与@tomkri的答案类似的黑客方式,并提供演示代码.

如果您的子进程不需要使用输入流,只需将子进程输入流重定向到其父进程的输入流.然后在子节点中添加一个线程以始终读取输入流,并且当此线程无法从输入流中读取任何内容时,此子进程将退出.所以父进程退出 - >父进程输入流不存在 - >子进程输入流不存在 - >子进程退出.

这是Java中的演示代码.

家长流程:

package process.parent_child;

import java.io.File;
import java.io.IOException;
import java.lang.ProcessBuilder.Redirect;

public class ParentProc {

    public static void main(String[] args) {
        System.out.println("I'm parent.");

        String javaHome = System.getProperty("java.home");
        String javaBin = javaHome + File.separator + "bin" + File.separator + "java";
        ProcessBuilder builder = new ProcessBuilder(javaBin, "process.parent_child.ChildProc");

        // Redirect subprocess's input stream to this parent process's input stream.
        builder.redirectInput(Redirect.INHERIT);
        // This is just for see the output of child process much more easily.
        builder.redirectOutput(Redirect.INHERIT);
        try {
            Process process = builder.start();
            Thread.sleep(5000);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Parent exits.");
    }
}

儿童过程:

package process.parent_child;

import java.io.IOException;
import java.util.Scanner;

public class ChildProc {


    private static class StdinListenerThread extends Thread {

        public void run() {
            int c;
            try {
                c = System.in.read();
                while ( c != -1 ) {
                    System.out.print(c);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            System.out.println("\nChild exits.");
            System.exit(0);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        System.out.println("I'm child process.");
        StdinListenerThread thread = new StdinListenerThread();
        thread.start();
        Thread.sleep(10000);
    }
}

通过以下命令运行此父进程后:

    java process.parent_child.ParentProc

你会看见

    I'm parent.
    I'm child process.
    Parent exits.
    xmpy-mbp:bin zhaoxm$
    Child exits

当父进程退出时,子进程立即退出.

推荐阅读
农大军乐团_697
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有