【问题标题】:Perl: When does "system" actually return?Perl:“系统”何时真正返回?
【发布时间】:2012-08-28 02:13:43
【问题描述】:

在 CGI 网页中,我有一个按钮,按下该按钮会提交一个表单并调用一个子例程,该子例程具有:

sub run {
     &emailDebug("Started " .localtime);
    system("(/tools/script1.pl &) ; (/tools/script2.pl &)");
    &emailDebug("Ended " .localtime);
}

它们都从 11:08:05 开始(因此是花哨的命令),我自己在脚本中获取时间戳并将它们通过电子邮件发送给自己。

第二个完成 11:08:22 和第一个 11:08:36 但从上面发送的电子邮件将显示 11:08:06。

最有趣的是,页面加载大约 30 秒,只要两个脚本中较长的一个运行。

我不介意页面加载,但我不明白为什么它会这样。作为 页面正在加载,显然子程序run 本身没有返回,但两封电子邮件几乎同时发送。

【问题讨论】:

    标签: perl unix cgi


    【解决方案1】:

    system 在您调用的命令允许它返回时立即返回。在这个特定示例中,它应该立即返回,但这可能会因 shell 而中断。为了更加确定,您可能会尝试将通话一分为二:

    system("/tools/script1.pl &");
    system("/tools/script2.pl &");
    

    此外,根据您的网络服务器配置,它可能会注意到您仍然在分叉子节点中打开了 STDOUT,并且它会等待所有子节点结束后再提供响应,即使您的主脚本已经结束。将您生成的脚本 STDOUT/ERR 重定向到主脚本中的 /dev/null、close(STDOUT)close(STDERR),或者查阅您的网络服务器/框架文档,了解如何在完成输出后刷新响应。

    【讨论】:

    • 是的,如果我使用控制台在系统上运行命令,就必须如此,因为它现在(或你的)进入 bg,但我必须按回车键才能恢复我的提示。您的设置行为相同,包括时间行为。 close(STDOUT) 将杀死脚本,因为它必须打印一些 html 并且 close(STDERR) 什么也不做。
    • @Recc,然后手动设置分叉,而不是使用system 并在那里关闭 OUT/ERR。
    【解决方案2】:

    您正在将脚本作为后台进程执行,因此系统会立即返回。如果您想等待完成,请删除 &s 并按顺序执行它们:

    system("(/tools/script1.pl) ; (/tools/script2.pl)");
    

    【讨论】:

    • 那为什么页面也会立即加载呢?它仍然需要 30 多秒,这是我对后台进程的意图,因为其他脚本在它们一起运行时也需要 15-20 秒。对用户来说似乎更快。
    • 这可能是因为您的脚本使用的资源。
    • 是的,它的脚本需要很长时间(两者中最长的,因为它们同时开始)。系统确实如您所说返回,但没有解释为什么页面仍然以某种方式等待,子完成执行,我只是通过用相同的电子邮件调用包装它来检查。
    • 如果脚本使您的 CPU 过载,则页面加载延迟是预期的。
    • 这些脚本在服务器上执行,延迟是因为它们使用一些糟糕的 API 在网络上以 XML 格式提取数千条记录
    【解决方案3】:

    上面的打印语句是什么意思?您的代码显示没有 print 调用

    您的run 子例程将在两个子进程启动后立即返回。您可以通过两次调用system 并删除命令行中的括号来使事情更清楚。由于尾随 & 号,对系统的两个调用都会立即返回,让孩子们独立运行

    在调用run之后,一定是有别的东西延迟了页面的返回,大概是在以某种方式检测子进程的工作何时完成

    顺便说一句,当您进行简单调用时,您应该从不在子例程名称上使用与号。自从 18 年前我们得到 Perl 5 以来,它就没有必要了

    【讨论】:

    • 不,什么都没有。当我开始使用 Perl 时,我一定读过过时的资源,不知道 &,干杯。 (刚才读了一些)
    猜你喜欢
    • 2012-05-14
    • 2014-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多