3

私は perl が初めてで、perl スクリプトで ^C の処理に問題があります。スリープ中に ^C を受信した後にスクリプトの実行を続行しようとすると、 $FLAG = 2; の前にしか出力されません。その後は何もありません:

# perl test.pl 
sleeping...
^Cawaiking...  =  
#  

それ以外の:

# perl test.pl 
sleeping...
awaiking...    ====                                              
some..
#

^C がプログレス バー スレッドを強制終了しており、終了後は何のアクションも実行されませんが、メイン スレッドで印刷を実行できます。誰でもこの問題を解決できますか?

$SIG{INT} = 'IGNORE';
our $FLAG : shared = 1; 
...
sub call1{
    $FLAG = 1;
    my $pBar = threads->new(\&progressBarInit);
    $pBar->detach;
    print "sleeping...\n";
    sleep 5;
    print "awaiking...\n";
    $FLAG = 2;
    print "some..\n";
    return @result;
}

call1();

sub progressBarInit{
my $max = 50;
    my $counter = 1;
    while($FLAG == 1){
        progressBar( $counter, $max, 50, '=' );
        $counter++;
        if($counter > $max){$counter=1;}
        sleep 1;
    }
}

sub progressBar {
    my ( $counter, $max, $width, $char ) = @_;
    local $| = 1;
    printf "               %-${width}s\r", $char x (($width-1)*$counter/$max);
}
4

1 に答える 1

0

問題は、親でシグナルハンドラーをセットアップすることだと思います。

これによると:http://perldoc.perl.org/threads.html

シグナル ハンドラーは、処理対象となるシグナルのスレッドに設定する必要があります。スレッドをキャンセルする例を次に示します。

フラグを使用する代わりに、シグナルを使用して通信できます。

sub progressBarInit    {
  # Thread 'cancellation' signal handler
  $SIG{'KILL'} = sub { threads->exit(); };
  $SIG{INT} = 'IGNORE';
  ...
}
...
# Signal the thread to terminate, and then detach
# it so that it will get cleaned up automatically
   my $pBar = threads->new(\&progressBarInit);    
    print "sleeping...\n";
    sleep 5;
    print "awaiking...\n";
    $pBar->kill('KILL')->detach();
于 2013-01-31T14:02:03.417 に答える