为啥 Java 创建的两个子进程行为不同?

Posted

技术标签:

【中文标题】为啥 Java 创建的两个子进程行为不同?【英文标题】:Why two subprocesses created by Java behave differently?为什么 Java 创建的两个子进程行为不同? 【发布时间】:2011-02-10 07:52:45 【问题描述】:

我使用Java Runtime.getRuntime().exec(command) 创建一个子进程并打印它的pid 如下:

public static void main(String[] args) 

Process p2;
try        
    p2 = Runtime.getRuntime().exec(cmd);
    Field f2 = p2.getClass().getDeclaredField("pid");
    f2.setAccessible(true);
    System.out.println( f2.get( p2 ) );
 catch (Exception ie)

    System.out.println("Yikes, you are not supposed to be here");



我尝试了 C++ 可执行文件和 Java 可执行文件(.jar 文件)。两个可执行文件都将连续打印出“Hello World”到标准输出。

cmd 是C++ 可执行文件时,pid 会打印到控制台,但一旦main() 返回,子进程就会被终止。但是,当我在 cmd 中调用 .jar 可执行文件时,子进程不会被杀死,这是期望的行为。

我不明白为什么具有不同可执行文件的相同 Java 代码的行为会如此不同。我应该如何修改我的代码,以便在 Java 中拥有持久的子进程?

PS:我使用的是 Ubuntu 9.10 和 OpenJDK-1.6。 (不确定它们是否重要~)

这个领域的新手。欢迎提出任何建议。

百合

【问题讨论】:

【参考方案1】:

C++ EXE 几乎肯定被标记为控制台应用程序。我认为 jar 默认会被视为 GUI 应用程序,并且会执行标准的 detach-from-the-main-process 事情。

如果您将 C++ 代码转换为 GUI 应用程序,我想您会看到它的行为类似于 jar。

【讨论】:

我认为这不是 OP 所期望的答案。如何轻松“将 C++ 代码转换为 GUI 应用程序”? 简单的答案?你没有。控制台和 Windows 子系统是分开的,并且使用方式不同。 Windows 应用程序不会获得控制台,因此除非您附加到进程,否则您将永远看不到输出。 不太简单的答案:msdn.microsoft.com/en-us/library/ms682055(v=VS.85).aspx 感谢您的回复。但问题是:我不在乎控制台输出。只要main()返回后子进程还在运行,我就已经很开心了~

以上是关于为啥 Java 创建的两个子进程行为不同?的主要内容,如果未能解决你的问题,请参考以下文章

当子进程仍然打开时,为啥 Java 进程会从 Gradle 挂起?

linux下fork两子进程为啥只有一个读取到pipe的内容?

为啥 Python 不能通过子进程执行 java.exe?

为啥我通过 spawn() 创建的 Node 子进程挂起?

为啥在调用 c++ fork 函数之前创建的值没有被父进程和子进程修改两次?

为啥在并行子进程之间分叉两次后 pipe() 不工作?