2

バックグラウンドで別のプロセスを開始し、他のスクリプトが終了するのを待たずに終了する必要がある Perl スクリプトがあります。Perl で待機する方法や、他のプログラミング言語を待機しない方法をカバーする StackOverflow のスレッドはたくさんありますが、Perl の正しい答えを見つけることができないようです。

私はかなり読んで、正しいことをしていると思っていましたが、私の試みはどれも正しく機能していないようです。これまでに試したすべてのバリエーションは次のとおりです。

system(qq|perl /util/script.pl $id|);

system(qq|perl /util/script.pl $id &|);

exec(qq|perl /util/script.pl $id|);

exec(qq|perl /util/script.pl $id &|);

これらのそれぞれで、親プロセスは終了する前に子プロセスが終了するのを待ち続けます。私が間違っていることと、バックグラウンド プロセスをフォークする正しい方法を教えてください。

よろしくお願いします。


デバッグに役立つ完全なコード。API->Function() 呼び出しはオブジェクト指向モジュールであることに注意してください:

sub Add {
    my $self = shift;
    my $domain = shift;

    if(!$self->IsValid($domain)) { return; }

    my $SQL = qq| insert into domains set added=NOW(),domain=| . API->Database->Quote($domain);
    my $sth = API->DatabaseQuery($SQL);

    $SQL = qq| select last_insert_id() |;
    $sth = API->DatabaseQuery($SQL);
    my $id = $sth->fetchrow_array();

    my $command = qq|perl /home/siteuser/util/new.pl $id &|;
    system($command);

    return {'id'=>$id,'domain'=>$domain};
}
4

4 に答える 4

4

最初のものはそのように動作するように設計されています -systemコマンドを実行し、終了するために終了します。

最後の 2 つもそのように設計されていexecます。具体的には、決して戻らないように設計されています。基本的に、親プロセスを子プロセスに置き換えます。

ただし、2 番目のコマンドはトリックを実行する必要がありsystemます。呼び出しから起動されるコマンドは shell であり、実行する文字列が与えられます。文字列は「&」で終わるため、シェルがコマンドをバックグラウンド プロセスとして起動し、その起動後に独自の実行を終了することを意味します。

#2が機能しなかった方法を示すコードをさらに投稿していただけますか?

また、バックティックまたは qx を試すとどうなるかを確認してください。

my $output = qx|perl /util/script.pl $id &|;
print $output;

また、不明な点を減らす方法として、次のコマンドを実行して、何が出力されるか教えてください。

my $output = qx|(echo "AAAAAAA"; /bin/date; sleep 5; /bin/date; echo "BBBBBBB") &|;
print $output;
于 2010-12-13T17:41:11.053 に答える
3

You need to disassociate the child from the parent. See perldoc -q daemon. Or Proc::Daemon

于 2010-12-13T18:56:12.723 に答える
3

電話fork()する前に電話していますかsystem、それともexec?

my $pid = fork();
if (defined($pid) && $pid==0) {
    # background process
    my $exit_code = system( $command );
    exit $exit_code >> 8;
}


my $pid = fork();
if (defined($pid) && $pid==0) {
    # background process
    exec( $command );
    # doesn't^H^H^H^H^H^H shouldn't return
}
于 2010-12-13T18:09:36.353 に答える
0

fork を使用すると、プロセスをバックグラウンドで実行するのに適しています。

my $pid = fork;
die "fork failed" unless defined $pid;
if ($pid == 0) {
    # child process goes here
    do '/util/script.pl';
    exit;
}
# parent process continues here
于 2010-12-13T18:00:16.127 に答える