【问题标题】:Java process sending itself to the backgroundJava 进程将自身发送到后台
【发布时间】:2017-07-30 21:55:32
【问题描述】:

我知道如何“去魔化”进程(不要与Thread.setDaemon 混淆)。有一些答案 herehere 我正在使用我自己的 perl 包装器,效果很好。

但我现在想得到的是,父进程等待 Java 进程,直到它说“OK”,即,直到它真正成功启动(不仅进程启动,而且一切正常运行) .

我可以通过编写文件、绑定到套接字或类似方式来表明这一点,但它很难看。在deamonize 列表中的八项中,我只需要稍微简化的以下三项:

  • 关闭标准输入、标准输出和标准错误。
  • 在后台运行(即 fork)
  • 忽略 SIGHUP。

第一项和最后一项可以在进程开始之前完成,因此只剩下forking 进程。由于存在ForkJoinPool,因此在谷歌上搜索“Java fork”是没有希望的。在我弄脏手之前,我想知道是否

  • Java 9 支持它(那我就等着看)
  • 有人已经在使用 JNA 并且遇到了什么问题
  • 有更好的解决方案

我不关心 Windows,因为它适用于 Linux 服务器。

【问题讨论】:

  • 进程内守护进程真的不是一个好主意。即使你认为你不需要其中的一些东西,你也可能真的需要(例如,未能放弃控制终端可能最终会使你的整个系统无法使用)......以及 8 个列表非常不完整。
  • @o11c 你可能是对的,但你能详细说明一下吗?我真的只做这三件事,并且在生产两年后(代码继承自旧项目)。我可能应该切换到守护进程,但我仍在考虑在 Java 中进行分叉。
  • 例如,如果你不放弃控制终端,/dev/pts/可能会慢慢填满,然后你就根本无法创建任何新终端。现在,如果你访问/dev/tty1,你可以用它来杀死邪恶的守护进程,但如果你只有 SSH,你就完蛋了。
  • 注意:我实际上并不知道如何安全地守护进程。相反,我知道不去尝试
  • 如今,正确守护进程的最佳方式似乎是“docker run ...”...

标签: java linux fork daemon jna


【解决方案1】:

我不知道这对 Java 的翻译效果如何,但从系统调用的角度来看:

当父母和孩子都在您的完全控制之下时,您应该调用pipesocketpair 来创建自己的通信通道,并通过环境变量或命令行参数将其指定给孩子。请记住在每个进程中立即关闭一半(如果您可以在 fork 和 exec 之间进行控制,或者通过 CLOEXEC 标志 - 这意味着子 executable 根本不需要知道父进程的结束) .

我不知道为什么你似乎对使用套接字犹豫不决——也许你的印象是本地套接字占用端口(它们不占用)——尽管如果所有数据都在一个方向上传输,我更喜欢管道只是为了清楚。

如果子级可以创建自己的子级,则应尽快在继承管道上设置CLOEXEC 标志。

你必须发送一个肯定的消息来表示成功;必须将提前关闭管道视为错误(尽管您也可能有明确的错误)。请注意,这意味着您不必跟踪退出值(如果“孩子”实际上是孙子,则很有用)。


或者,也许您应该让其他东西来完成这项工作:您的初始化系统、X11 和 DBUS?例如,如果孩子崩溃了,您在想应该怎么做?

【讨论】:

  • AFAIK,几乎没有什么可以转化为纯 Java,尽管使用 JNA,一切都应该做。在纯Java中,我可以创建一个ServerSocket(int port),这很丑,但我不在乎占用端口;它们都是我的,完成后我可以关闭它们。 +++ 我想使用进程退出代码:我将启动我的 Java 进程,让它 fork,让父进程等到子进程以错误退出值结束或断开连接。我明白了,我不知道后者该怎么做。
  • 关于初始化系统、X11 和 DBUS,我一无所知。如果孩子崩溃了,那么我所能做的就是尝试重新启动它。因为它从未发生过,所以应该每分钟检查一次 cron 作业。我知道,有更好的解决方案,但考虑到崩溃的可能性很低,一分钟的停机时间是没有问题的,而且愚蠢的 cron 工作似乎比我不太了解的高级工具风险更小。
  • 必须以一种或另一种方式使用本机代码,因为fork 系统调用极大地限制了您的代码可以执行的操作,并且虚拟机不遵守这些限制。但您可以将其限制为几百行。
  • 重新初始化:如果这次失败了,很有可能再次失败。但是,它可能不会。初始化系统对此进行了很多思考,具有良好的默认值,但也具有可配置性。而sd_notify("READY=1") 的“我实际上开始成功了”至少是半标准化的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-25
相关资源
最近更新 更多