1

操作を完了するのに時間がかかる Perl プラグインがあります。そのプラグインは通常、バックグラウンドで送信してすぐにメッセージを出力する CGI インターフェースから Web 経由で起動されます。残念ながら、私はそれを行う方法を見つけることができませんでした。つまり、CGI はプラグインを正しく開始しますが、プラグインが完了するのを待ちます。&fork、detach 、Proc::Backgroundでも試してみましたが、これまでのところ運がありません。問題が CGI に関連していることは確かですが、その理由を知りたいのですが、可能であれば、これを修正したいと思います。これが私が試したコードです。すべての方法がコンソールからうまく機能することに注意してください。問題を引き起こすのはCGIだけです。

# CGI
my $cmd = "perl myplugin.pl";

# Proc::Background
my $proc = Proc::Background->new($cmd);
# The old friend &
system("$cmd &");
# The more complicated fork
my $pid = fork;
if ($pid == 0) {
    my $launch = `$cmd`;
    exit;
}
# Detach

print "Content-type: text/html\n\n";
print "Plugin launched!";

StackOverflow にも同様の質問があることは知っていますが、ご覧のとおり、私の問題は解決しません。

4

2 に答える 2

4

これは基本的に、pilcrow の回答でシェルが舞台裏で行っていることの Perl 実装です。これには 2 つの潜在的な利点があります。シェルを使用して 2 番目のスクリプトを呼び出す必要がないことと、まれに fork が失敗した場合に、より適切なユーザー フィードバックを提供できることです。

my @cmd = qw(perl myplugin.pl);

my $pid = fork;
if ($pid) {
    print "Content-type: text/html\n\n";
    print "Plugin launched!";
}
elsif (defined $pid) {
    # I skip error checking here because the expectation is that there is no one to report the error to.
    open STDIN,  '<', '/dev/null';
    open STDOUT, '>', '/dev/null'; # or point this to a log file
    open STDERR, '>&STDOUT';
    exec(@cmd);
}
else {
    print "Status: 503 Service Unavailable\n";
    print "Content-type: text/html\n\n";
    print "Plugin failed to launch!";
}
于 2012-05-09T15:13:55.527 に答える
3

子プロセスを閉じるか、継承された標準出力と標準エラーを削除して、クライアントに自由に応答できることを Apache が認識できるようにします。この件に関するマーリンの記事を参照してください。

例:

system("$cmd >/dev/null 2>&1 &");

身震いするけどsystem("$cmd ...")

于 2012-05-09T14:25:41.347 に答える