【问题标题】:perl run background job and force job to finish?perl 运行后台作业并强制作业完成?
【发布时间】:2013-10-02 12:24:28
【问题描述】:

我有一个 Perl 脚本,它启动一个后台作业来打印一些 将信息记录到文件中,执行某些操作,然后 完成。

我想在脚本完成后结束后台进程, 但据我所知,如果我使用如下双叉,那么waitpid($pid,0) 将等待后台进程完成,而不是杀死它, 而kill(9,$pid) 不会摆脱后台进程。

示例脚本:

#!/usr/bin/perl
use strict;

# Do a first general top
my $ret = `top -b -n 1 > logfile`;

# Do a background $USER top every minute
my $cmd = "top -b -d 60 -n 300 -u $ENV{USER} >> logfile";
my $pid;
unless ($pid = fork) {
  unless (fork) {       #second_fork
    exec "$cmd";
    die "exec failed!";
  }                     #second_fork
  exit 0;
}

# Script does something else for 1-2 hours
# [...]
# We are finished now, let's finish the logging

# waitpid($pid,0) would wait until top command is finished
force_background_job_to_finish($pid) if (background_job_still_running($pid));

# Add final top to the end
$ret = `top -b -n 1 >> logfile`;

1;

任何想法如何force_background_job_to_finish

【问题讨论】:

    标签: perl ipc kill-process


    【解决方案1】:

    这对我有用:

    $SIG{CHLD}="IGNORE";
    my $cmd = "top -b -d 60 -n 300 -u $ENV{USER} >> logfile";
    if (my $logger_pid=fork) {
        # parent
        do_something_for_1to2_hours();
        kill 15, $logger_pid;
    } else {
        # child (logger)
        exec($cmd);
    }
    

    【讨论】:

    • 如果kill 命令之前没有任何内容,它确实会杀死它,但是如果我添加一个虚拟的sleep 5; 而不是do_something_for_1to2_hours();,我仍然可以看到记录器进程在杀死命令。
    • 我的错误,尝试使用kill 15 (SIGTERM) 而不是kill 1 (SIGHUP)。答案已编辑。
    • 我把它改成了 kill 15,但我仍然可以看到 top 命令正在运行。
    • 如果您添加了$SIG{CHLD}="IGNORE",那么top 进程应该会在被杀死后立即死亡并被回收。运行这个单行代码:perl -le '$SIG{CHLD}="IGNORE"; if($pid=fork) { sleep 1; kill 15, $pid; system "ps $pid"; } else { exec "top -b -d 1 -n 300 -u $ENV{USER}" }' - 你应该看到一次top 的输出,然后只看到ps $pid 命令的标题行,对吗?
    • 你的单线现在适合我,我想我从脚本中复制+粘贴它时可能遗漏了一些东西。
    【解决方案2】:

    通常使用双叉,这样您就不必担心收割子进程。由于您想控制子进程,您可以只执行一次 fork,它会为您提供进程 ID,然后您可以使用它来使用 kill 杀死您的子进程。

    【讨论】:

    • 所以如果我去掉标记为#second_fork 的行,我如何杀死后台进程? kill(9,$pid) 不会杀死它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-03
    相关资源
    最近更新 更多