【问题标题】:Perl system(), exec() and interactions with LSFPerl system()、exec() 和与 LSF 的交互
【发布时间】:2015-05-05 12:30:00
【问题描述】:

我有一个脚本必须启动 2 个独立进程,并等到其中一个进程完成后再继续。

到目前为止,我通过创建一个带有if fork pid == 0, exec, else wait 的进程来运行它。另一个是使用system 和命令行创建的。

现在我正准备推出此脚本以在 Platform Load Sharing Facility (LSF) 上运行此类工作对进程的 400 次迭代,但我担心稳定性。我知道进程可能会崩溃。在这种情况下,我需要一种方法来知道进程何时崩溃,并终止它的配对进程和主脚本。

最初我写了一个监视周期为 3 分钟的看门狗,如果 3 分钟不活动过去,它会杀死进程。然而,这引起了很多误报,因为当 LSF 暂停两个进程之一时,看门狗将它们视为不活动的。

在 LSF 中,当我发布作业时,我可以选择终止它们。但是,当我杀死一个工作时,我到底要杀死什么? kill 会取消 Perl 脚本创建的两个进程吗?还是让他们像僵尸一样奔跑?

重申一下,

  • 杀死 LSF 队列中的作业是否也会杀死该作业创建的每个进程?

  • 从 Perl 脚本生成两个独立进程并等待其中一个进程退出再继续的最佳(最安全?)方法是什么?

  • 如何编写一个看门狗来区分已崩溃的进程和被 LSF 管理员挂起的进程?

【问题讨论】:

  • LSF 如何暂停/恢复?我想是通过SIGSTOPSIGCONT?
  • "默认操作是向作业发送以下信号:SIGTSTP 用于并行或交互作业。SIGTSTP 被主进程捕获并传递给运行在其他主机上的所有从进程。SIGSTOP 用于顺序作业。SIGSTOP 不能被用户程序捕获。可以使用 lsf.conf 中的 LSB_SIGSTOP 参数配置 SIGSTOP 信号。"来自 LSF 的“作业控制”。我想知道在这种情况下“从属进程”的含义是否是指由原始作业生成的进程

标签: linux perl lsf


【解决方案1】:

监视器是应该创建子进程的监视器。 (它也可以启动“主脚本”。)wait 会在它们崩溃时告诉你。

my %children;

my $pid1 = fork();
if (!defined($pid1)) { ... }
if ($pid1) { ... }
++$children{$pid1};

my $pid2 = fork();
if (!defined($pid2)) { ... }
if ($pid2) { ... }
++$children{$pid2};

while (keys(%children)) {
   my $pid = wait();
   next if !$children{$pid};  # !!!

   delete($children{$pid});

   if ($? & 0x7F) { ... }   # Killed from signal
   if ($? >> 8) { ... }     # Returned an error
}

【讨论】:

  • 所以你的想法是重构脚本?这样你就有了一个调用主脚本的脚本,并且还创建了 2 个子进程,它使用等待来捕获返回值并查看它是错误还是被信号杀死?
  • 是的。主脚本可以将管道继承给子脚本。
  • 另外,您可能不知道setsid(2)(以POSIX::setsid() 提供)。创建一个可以向其发送信号的进程组。
  • 非常感谢,这看起来是继续前进的最佳方式!
猜你喜欢
  • 1970-01-01
  • 2014-02-21
  • 2010-11-25
  • 2010-10-22
  • 2015-01-24
  • 1970-01-01
  • 2011-01-17
  • 2015-04-27
相关资源
最近更新 更多