【问题标题】:How to continue Perl script execution in background?如何在后台继续执行 Perl 脚本?
【发布时间】:2017-06-14 10:07:10
【问题描述】:

我有一个脚本,我想在其中添加一个“自动”模式 一些处理,生成一些输出,然后在后台通过 自己。

我怎样才能安全地做到这一点?会是一个简单的分叉并退出父级吗 这样做,还是会产生僵尸(孤儿)问题?

# initial processing
defined (my $pid fork) or die "Can't fork: $!";
exit if $pid;
# continue child in background

【问题讨论】:

  • 孤儿,即父进程不再存在的进程,通常由 init 进程自动收割。僵尸是另一回事:父进程存在,但不关心wait 子进程,因此即使进程死了,它也没有完全收割。在您的情况下,这将是孤儿,因此无需担心这部分。您可能需要担心与父级(即外壳)的父级共享文件描述符等。
  • 如上所述,这是安全的。这是将某些东西放在后台的一种方法——立即在父级中分叉并退出,而要运行的代码在子级中。然后 init 接管了孩子,一切都很好(当孩子完成时,最终会收获它)。那你想让孩子做什么?它是否与父级退出之前在父级中完成的初始处理有某种关系?
  • 谢谢@zdim。是的,相关。好吧,我称之为运行相同事物的新模式。在其“正常”模式下,脚本获取数据,输出将要完成的操作的摘要,然后输出每个步骤中正在完成的操作。我已经实现了静默模式,但我发现摘要特别有用。所以这个新的“模式”会一直运行,直到打印摘要,然后如果给出了新的选项做一个分叉,杀死父级,设置为静默并继续执行。希望这是实现它的好方法。
  • 好的,谢谢。您可以在子进程中重新启动相同的程序作为守护进程,并选择不执行初始摘要部分来运行它。这可能会完全简化代码。 Proc::Daemon 是一个让它成为守护进程的好方法。在this postthis post 中有一个关于看似非常相似的想法的好信息。
  • 另外,this perlmonks post 重新散列 code from perlipc 以守护进程(无模块)。

标签: perl unix fork zombie-process


【解决方案1】:

孤儿,即父进程不再存在的进程,通常由 init 进程自动收割。僵尸是另一回事:父进程存在但不关心wait 的子进程,因此即使进程死了,它也没有完全收割。在您的情况下,这将是孤儿,因此无需担心这部分。

如果您从 shell 执行进程,您可能仍需要担心与父级的父级共享文件描述符等。我建议您也关闭所有文件描述符,尤其是 stdin、stderr 和 stdout。

【讨论】:

  • 考虑到在正常执行中我的脚本不会关闭标准输入等,我想知道这个孩子在创建后是否真的需要这样做。我错过了什么吗?
  • @sidyll:这可能仅在您从交互式 shell 启动脚本并且不想因与 shell 的不良交互而遇到任何麻烦时才相关,即如果 shell 停止脚本,如果它写入标准输出等。在这个领域还有一些其他的陷阱,比如推断 shell 的作业控制。我经常看到双叉与关闭 std* fd 以完全脱离外壳。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-01
  • 2020-03-21
  • 1970-01-01
  • 2015-09-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多