2009-08-03 1 views
2

作業中のプログラムの一部と並行して画面上を刻むライブタイムカウンタを作成するにはどうすればよいですか?プログラムと並行して動作する子プロセスとしてタイムカウンタを作成するにはどうすればよいですか?

のは、私は数分のカップルのための内部プログラムを実行し、次の小さなサブコードとしましょう:最後にそれを待っている間、私は出力がランニングをstdoutにフォークか何かを開くことができ、

system (`compile command`); 
exec "simu -sh"; 

を時刻?

もう1つ質問がありますが、スクリプトの残りの部分を傷つけることなくALARMカウンタを画面に出力するにはどうすればよいですか?

+0

進捗バーを作成しようとしていますか? –

+0

オプションになります。 – YoDar

答えて

3

あなたの質問に文脈を与えることは重要です。あなたはすでに親と子の2つのプロセスを持っています。子はexecと置き換えられているので、子を使って監視することはできませんが、親は利用可能です。 waitpidコールをノンブロッキングにするだけです(つまり、正常に終了するまで待つことはなく、すぐに失敗します)。また、これはevalalarm機能の必要性を取り除きます:スレッドとしてそれを産卵して、設定する値を待っている(あなたがPerlを有効にスレッドを持っていると仮定)について

#!/usr/bin/perl 

use strict; 
use warnings; 
use POSIX ":sys_wait_h"; 

my $timeout = 180; 
my $program = "simulator --shell"; 

die "could not fork: $!" unless defined (my $pid = fork); 

#this is the child process 
unless ($pid) { 
    exec $program; 
    #if we reach this code the exec failed 
    die "exec of simulator failed: $!"; 
} 

#this is the parent process 
my $tries = 0; 
#check to see if $pid is done, but don't block if it isn't 
until (waitpid(-1, WNOHANG) == $pid) { 
    #put what you want to print while waiting here: 
    print scalar localtime, "\n"; 

    if ($tries++ > $timeout) { 
     warn "timed out, sending SIGKILL to simulator\n"; 
     kill 9, $pid; 
     waitpid($pid, 0); 
     last; 
    } 
} continue { 
    sleep 1; 
} 
+0

私は選択肢がない、またはexec機能を回避する方法について知らない。私がそれを実行すると、時間カウンターは停止することができません。たぶんexec関数が作業場所の中で実行されるからです。それでも内部でexecコマンドが実行されている間にクロックカウンタを実行するための方法はありますか?または、ALARMカウンタ(execコマンドkill pidに属する)を画面に出力できますか? – YoDar

+0

なぜexec()の代わりにsystem()を使用するだけでいいですか? –

+0

私は次のリンクで提案されたManiとしてexec()を使用しました: http://stackoverflow.com/questions/1165316/how-can-i-limit-the-time-spent-in-a-specific-section- perlスクリプトの 死んで来る問題を取得せずにタイムアウトウィンドウを使用する別の方法があるなら私は喜んで知ってうれしいです:) – YoDar

-1

方法:

# Modules to be used 
use strict; 
use warnings; 
# Threads module 
use Thread; 

# Share out the variable so it can be set and 
# view by main thread and spawned thread 
my $value:shared = 0; # value to be set when completed 

# Create a thread with a subroutine to compile and set the passed in reference 
# to 1 when complete. Pass in the reference to value 
my $t = Thread->new(sub {`compile command`; ${$_[0]} = 1;}, \$value); 

# Counter to count 
my $count = 0; 

# Loop until the routine set the value 
while ($value == 0) 
{ 
    # Increment the count and print it out. 
    $count++; 
    print "$count\n"; 
    # Sleep for second to let the other thread process 
    sleep 1; 
} 
# Thread as completed so join back together 
$t->join(); 

# Indicate items have completed. 
print "Done $count\n"; 

Windows XPでは、ActiveState PERL 5.10で上記の例を実行しました。

これは、 にかかる時間を秒単位で示します。うまくいけば、より細かい粒度を探しているわけではありません。あなたは実際の時間を望むなら、カウンターの代わりにlocaltime()を使うことができます。

参照がロックされていないため、ルーチンの最後に設定されていれば、それが完了してバックアップに参加するだけです。

perl threadsの詳細については、こちらをご覧ください。

Perlmonksをご覧ください。

関連する問題