4

perl でバックグラウンド プロセスを実行しようとしています。別の perl スクリプトを呼び出すために使用される子プロセスを作成します。この子プロセスと並行して数行のコードを実行したいと考えています。子プロセスが完了したら、コード行を出力したいと思います。

メインスクリプト

#!/usr/bin/perl

$|=1;

print "before the child process\n";

my $pid = fork();

if (defined $pid)
{
    system("perl testing.pl");
}

print "before wait command\n";

wait();

print "after 20 secs of waiting\n";

testing.pl

#!/usr/bin/perl

print "inside testing\n";

sleep(20);

期待される出力

子プロセスの前に
待機コマンドの前
(20 秒待ってから印刷する必要があります) 
20 秒待った後
4

3 に答える 3

8

あなたのスクリプトには多くの問題があります。いつも:

use strict;
use warnings;

local特殊変数を使用することをお勧めします。特別な値を含む変数のみがundefに対して false を返しますdefined。したがって、他のすべての値 (0ここでは ; であっても) に対して true を返しますdefined。他のスクリプトでは、シバンが間違っています。

#!/usr/bin/perl

use strict;
use warnings;

local $| = 1;

print "Before the child process\n";

unless (fork) {
    system("perl testing.pl");
    exit;
}

print "Before wait command\n";
wait;
print "After 20 secs of waiting\n";
于 2012-11-23T14:05:43.583 に答える
7

perlipcドキュメント「バックグラウンドプロセス」セクションには、次のように書かれています。

次のコマンドをバックグラウンドで実行できます。

system("cmd &");

コマンドSTDOUTSTDERR(場合STDINによっては、シェルによっては)は親と同じになります。SIGCHLDダブルforkが行われるため、キャッチする必要はありません。詳細については、以下を参照してください。

プログラムの引数にアンパサンドを追加するとsystem、メインプログラムを大幅に簡素化できます。

#! /usr/bin/env perl

print "before the child process\n";

system("perl testing.pl &") == 0
  or die "$0: perl exited " . ($? >> 8);

print "before wait command\n";

wait;
die "$0: wait: $!" if $? == -1;

print "after 20 secs of waiting\n";
于 2012-11-23T13:53:47.143 に答える
1

fork戻り値の処理は、確かに少しトリッキーです。 Aristotle による最近の記事では、素晴らしく簡潔な forking イディオムが取り上げられています。あなたの場合は、次のようになります。

#!/usr/bin/env perl
use 5.010000;
use strict;
use warnings qw(all);

say 'before the child process';
given (fork) {
    when (undef) { die "couldn't fork: $!" }
    when (0) {
        exec $^X => 'testing.pl';
    } default {
        my $pid = $_;
        say 'before wait command';
        waitpid $pid, 0;
        say 'after 20 secs of waiting';
    }
}

行に注意してexec $^X => '...'ください: $^X変数は、現在の Perl 実行可能ファイルへのフル パスを保持するため、「正しい Perl バージョン」が保証されます。また、system事前分岐している場合、呼び出しは無意味です。

于 2012-11-26T03:45:10.013 に答える